如何修改一个Mongoose查询的输出?
我在我的MongoDB集合products
有一个名为date_expired
。
它是type: date
并存储datestring。
我想检索所有产品,并将结果中的date_expired
属性更改为现在剩下的小时数。 我该怎么做呢?
这和Laravel的getter()
类似…?
你可以创build一个虚拟的财产 ,将返回的小时数,直到到期:
ProductSchema.virtual('hoursToExpiry').get(function() { return (this.date_expired - Date.now()) / 3600000; });
要访问此属性:
console.log('hours to expiry:', doc.hoursToExpiry)
如果您想要将该属性包含在任何JSON或JS对象中,请确保您设置了virtuals : true
:
console.log('%j', doc.toJSON({ virtuals : true }));
在这种情况下会考虑使用聚合框架来输出转换。 您可以使用$project
pipe道算术运算符$divide
和$subtract
来实现最终目标。 这些将使您能够执行计算到期的小时数的algorithm,即执行公式:
hoursToExpiry = (date_expired - timeNow)/1000*60*60 //the time units are all in milliseconds
以下面这个简短的mongo shell演示为例:
填充testing集合:
db.test.insert([ { "date_expired": ISODate("2016-03-27T10:55:13.069Z"), "name": "foo" }, { "date_expired": ISODate("2016-06-11T20:55:13.069Z"), "name": "bar" }, { "date_expired": ISODate("2016-06-11T16:17:23.069Z"), "name": "buzz" } ])
聚合操作:
db.test.aggregate([ { "$project": { "name": 1, "dateExpired": "$date_expired", "dateNow": { "$literal": new Date() }, "hoursToExpiry": { "$divide": [ { "$subtract": [ "$date_expired", new Date() ] }, 1000*60*60 ] } } } ])
结果(撰写本文时):
{ "result" : [ { "_id" : ObjectId("575c0f6e8101b29fc93e5b9d"), "name" : "foo", "dateExpired" : ISODate("2016-03-27T10:55:13.069Z"), "dateNow" : ISODate("2016-06-11T13:36:21.025Z"), "hoursToExpiry" : -1826.685543333333 }, { "_id" : ObjectId("575c0f6e8101b29fc93e5b9e"), "name" : "bar", "dateExpired" : ISODate("2016-06-11T20:55:13.069Z"), "dateNow" : ISODate("2016-06-11T13:36:21.025Z"), "hoursToExpiry" : 7.314456666666667 }, { "_id" : ObjectId("575c0f6e8101b29fc93e5b9f"), "name" : "buzz", "dateExpired" : ISODate("2016-06-11T16:17:23.069Z"), "dateNow" : ISODate("2016-06-11T13:36:21.025Z"), "hoursToExpiry" : 2.683901111111111 } ], "ok" : 1 }
通过上面的pipe道,你可以把它作为你的查询的基础,把它作为你的Mongoose实现的aggregate()
方法:
Product.aggregate([ { "$project": { "name": 1, "dateExpired": "$date_expired", "dateNow": { "$literal": new Date() }, "hoursToExpiry": { "$divide": [ { "$subtract": [ "$date_expired", new Date() ] }, 1000*60*60 ] } } } ]).exec(function (err, result) { // Handle err console.log(result); });
或者使用更富裕的API:
Product.aggregate() .project({ "name": 1, "dateExpired": "$date_expired", "dateNow": { "$literal": new Date() }, "hoursToExpiry": { "$divide": [ { "$subtract": [ "$date_expired", new Date() ] }, 1000*60*60 ] } }) .exec(function (err, result) { // Handle err console.log(result); });