如果我有文档并且我正在聚合并且我想子一个字段,例如:
{data: {'date_created': '2011-01-01', 'title': 'abc'}, 'owner': 'Jim'}
{data: {'date_created': '2011-05-01', 'title': 'def'}, 'owner': 'Bob'}
{data: {'date_created': '2011-03-01', 'title': 'ghi'}, 'owner': 'Jim'}
{data: {'date_created': '2011-03-01', 'title': ''}, 'owner': 'Sam'}
并且我想聚合以便我只采用在特定日期之前创建的标题或返回空列表,我将如何构建聚合管道?
所以期望的输出将是:
{owner: "Jim", titles: ["abc", "def"],
owner: "Bob", titles: [],
owner: "Sam", titles: []}
我有一个聚合管道,如下所示:
lookup => unwind =>
{'$match':
{'$or': [{'data.date_created': {'$lte': requested_date}}, {'data.title': {'$exists': False}}]}}}
但是我不知道如何将创建日期在所需时间之后的数据转换为空白,以便将其与空白标题分组。
希望这有帮助。您可以根据日期执行条件推送,然后从标题数组中筛选出空白项目。
db.collection.aggregate([
{"$group":{
_id:"$owner",titles:{
$push: { $cond:[
{ $lte: [ "$data.date_created", "2011-03-01" ]},"$data.title",""
]
}
}
}
},
{
$project: {
_id:0,
owner : "$_id",
titles: {
$filter: {
input: "$titles",
as: "titles",
cond: { $ne: [ "$$titles", "" ] }
}
}
}
}
])
结果:
{ "titles" : [ ], "owner" : "Bob" }
{ "titles" : [ "abc", "ghi" ], "owner" : "Jim" }
{ "titles" : [ ], "owner" : "Sam" }
如果您在没有符合您的条件的项目时没有严格要求空数组,这将使它变得简单得多。如果是这种情况,您可以简单地用$push
或$addToSet
进行$match
和$group
。
例如:
db.foo.aggregate([
{ $match : {'data.date_created': {'$lte': "2011-03-01"}}},
{ $group: {
_id: "$owner",
titles : {$push : "$data.title"}
}}
])
结果:
{ "_id" : "Sam", "titles" : [ "" ] }
{ "_id" : "Jim", "titles" : [ "abc", "ghi" ] }
另一种选择是先执行$group / $push
,然后使用 $filter 过滤数组元素(需要 MongoDB 3.2+(。
例如:
db.foo.aggregate([
{ $group: {
_id: "$owner",
data : {$push : "$data"}
}},
{
$project: {
titles: {
$filter: {
input: "$data",
as: "item",
cond: { $lte: [ "$$item.date_created", "2011-03-01" ] }
}
}
}}
])
结果:
{ "_id" : "Sam", "titles" : [ { "date_created" : "2011-03-01", "title" : "" } ] }
{ "_id" : "Bob", "titles" : [ ] }
{ "_id" : "Jim", "titles" : [ { "date_created" : "2011-01-01", "title" : "abc" }, { "date_created" : "2011-03-01", "title" : "ghi" } ] }