文件遵循以下结构:
{
"_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"
进行测试,则结果不为空。
答案 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
}
})
您可以使用此方法实现所需的结果,而无需使用聚合链机制