我有一个名为'agendas'的集合,每个议程都有一个嵌套的任务集合绞盘被引用的对象id。
我正在对任务集合进行查找,然后根据日期范围进行匹配,以查找具有该范围之间任务的所有议程“项目”。然后我做一个过滤器来删除所有任务。所以基本上$ match和$ filter都是一样的。
我不知道为什么我要回复一个带有完全过滤任务的议程项目[]。我认为任何议程项目都会先通过$ match进行过滤。
我的查询:
db.agendas.aggregate([
{ '$lookup': {
from: 'tasks',
localField: 'tasks',
foreignField: '_id',
as: 'tasks' } },
{ '$match': {
'$and': [
{ 'tasks.status': 'Closed' },
{ 'tasks.date': { '$gte': new ISODate('2017-10-01T05:00:00.000Z') } },
{ 'tasks.date': { '$lte': new ISODate('2017-10-01T05:00:00.000Z') } }
] } },
{ '$limit': 100 },
{ '$project': {
type: 1, description: 1,
tasks: {
'$filter': {
input: '$tasks',
as: 'tasks',
cond: { '$and': [
{ '$eq': [ '$$tasks.status', 'Closed' ] },
{ '$gte': [ '$$tasks.date', new ISODate('2017-10-01T05:00:00.000Z') ] },
{ '$lte': [ '$$tasks.date', new ISODate('2017-10-01T05:00:00.000Z') ] }
] } } } } },
{ '$group': { _id: '$type', agenda: { '$push': '$$ROOT' } } },
{ '$sort': { _id: 1 } } ], {}).pretty()
结果
{
"_id" : "Maintenance",
"agenda" : [
{
"_id" : ObjectId("59d429ba15c67c147f8f3513"),
"description" : "Some new item 4",
"type" : "Maintenance",
"tasks" : [ ]
}
]
}
{
"_id" : "Monitoring",
"agenda" : [
{
"_id" : ObjectId("59d50d36e6de730a6d85019b"),
"description" : "Some new test agenda for Tomski",
"type" : "Monitoring",
"tasks" : [
{
"_id" : ObjectId("59d5378808f51d0c6590c724"),
"status" : "Closed",
"text" : "Some task 2",
"author" : {
"id" : ObjectId("59c09f8a8b4ad70aa4cda487"),
"name" : "Karunik De"
},
"date" : ISODate("2017-10-01T05:00:00Z"),
"created" : ISODate("2017-10-04T19:33:28.560Z"),
"__v" : 0
}
]
}
]
}
答案 0 :(得分:1)
如果您有多个条件,并且希望对每项任务应用所有条件,则需要使用$elemMatch
。
像
这样的东西{
"$match": {
"tasks": {
"$elemMatch": {
"status": "Closed",
"date": {
"$gte": new ISODate('2017-10-01T05:00:00.000Z'),
"$lte": new ISODate('2017-10-01T05:00:00.000Z')
}
}
}
}
}
更多here
与下面比较,查找符合每个条件的一项任务。因此,您可以使用匹配所有标准的单个任务或匹配每个条件的三个不同任务来返回文档。
{
"$match": {
"tasks.status": "Closed",
"tasks.date": {
"$gte": new ISODate('2017-10-01T05:00:00.000Z'),
"$lte": new ISODate('2017-10-01T05:00:00.000Z')
}
}
}
更多here