$ project和$ subtract之后的$ match在MongoDB中返回空结果

时间:2018-01-30 13:40:05

标签: mongodb mongodb-query aggregation-framework

文件遵循以下结构:

{ 
    "_id" : ObjectId("5a01b474d88dc4001e684c97"), 
    "created_time" : ISODate("2017-11-07T11:26:12.563+0000"), 
    "posts" : [
        {
            "story" : "Test", 
            "created_time" : ISODate("2017-11-06T17:38:02.000+0000"), 
            "id" : "769055806629274_768721009996087", 
            "_id" : ObjectId("5a01b498d88dc4001e68553c")
        }, 
        {
            "story" : "Test", 
            "created_time" : ISODate("2017-11-05T12:00:00.000+0000"), 
            "id" : "1637086293239159_2011737915773993", 
            "_id" : ObjectId("5a01b498d88dc4001e68553d")
        }
        [...]
     ]
}

我希望按created_time过滤帖子集合。每个帖子需要created_time大于{{1>} 文档。换句话说,我想根据文档仅在过去一个月收到帖子。

我正在尝试这种聚合:

created_time

但结果总是空的。如果我将db.collection.aggregate([ { $project: { "past_month": { $subtract: ["$created_time", 2629746000] //a month }, "created_time": "$created_time", "posts": "$posts" } }, { $unwind: '$posts' }, { $match: { "posts.created_time": { $gte: "$past_month" } } }, { "$group": { "_id": "$_id", "posts": { "$push": "$posts" } } } ]) 更改为$gte: "$past_month"进行测试,则结果不为空。

2 个答案:

答案 0 :(得分:1)

符合要求:

  

每个帖子的created_time都需要大于created_time   文件

要满意,使用MongoDB Server 3.4及更高版本,将 $addFields 管道与 $filter 运算符一起使用来过滤帖子为:

db.collection.aggregate([
    {
        "$addFields": {
            "posts": {
                "$filter": {
                    "input": "$posts",
                    "as": "post",
                    "cond": { 
                        "$gt": [
                            "$$post.created_time", 
                            { "$subtract": ["$created_time", 2629746000] }
                        ] 
                    }
                }
            }
        }
    }
])

$addFields 会将posts数组替换为上面表达式中已过滤的数组。

对于MongoDB 3.2,你仍然可以在 $filter 管道中使用 $addFields ,因为它不受支持,但 {{3} } 而不是。

对于MongoDB 3.0,使用 $project $setDifference 运算符的组合来过滤posts数组

db.collection.aggregate([
    { 
        "$project": {
            "created_time": 1,
            "posts": { 
                "$setDifference": [
                    { 
                        "$map": {
                            "input": "$posts",
                            "as": "post",
                            "in": {
                                "$cond": [
                                    { 
                                        "$gt": [
                                            "$$post.created_time", 
                                            { "$subtract": ["$created_time", 2629746000] }
                                        ] 
                                    },
                                    {
                                        "story" : "$$post.story",
                                        "created_time" : "$$post.created_time",
                                        "id" : "$$post.id",
                                        "_id" : "$$post._id",
                                    },
                                    false
                                ]
                            }
                        }
                    },
                    [false]
                ]
            }
        }
    }
])

答案 1 :(得分:0)

您可以在moment.js库 -

的帮助下以简单干净的方式执行此操作
var checkForDate = moment().subtract(1, 'months');

var startDate= moment(checkForDate).startOf('month');
var endDate= moment(checkForDate).endOf('month');


db.collection.find({
                 "posts.created_time":{
                                   $lt:endDate,
                                   $gt:startDate
                             }
                  })

您可以使用此方法实现所需的结果,而无需使用聚合链机制