如何修改Mongoose查询的输出?

时间:2016-06-11 12:57:46

标签: node.js mongodb mongoose

我的MongoDB集合products中有一个名为date_expired的字段。

它是type: date并存储日期字符串。

我想检索所有产品,并将结果中的date_expired属性更改为从现在起剩余的小时数。我该怎么做?

它类似于Laravel中的getter() ......?

2 个答案:

答案 0 :(得分:3)

您可以创建一个virtual property,它将返回到期前的小时数:

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 }));

答案 1 :(得分:1)

在这种情况下会考虑使用聚合框架来输出转换。您可以使用 $project 管道算术运算符 $divide $subtract 来实现最终目标。这些将使您能够执行计算到期时数的算法,即实施公式:

hoursToExpiry = (date_expired - timeNow)/1000*60*60 //the time units are all in milliseconds

举例说明以下简短的mongo shell演示,它将努力推动这一概念:

填充测试集合:

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
}

使用上述管道,您可以使用 aggregate() 方法将其用于Mongoose实施,作为查询的基础:

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);
    });