如果我有文件并且我正在聚合,我想要提交一个字段,如:
{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}}]}}}
但我无法弄清楚如何将所创建日期的数据投放到所需的空白时间之后,以便将其与空白标题分组。
答案 0 :(得分:2)
希望这会有所帮助。您可以根据日期进行条件推送,然后从titles数组中过滤掉空白项目。
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" }
答案 1 :(得分:1)
如果在没有符合条件的项目时没有严格要求空数组,那么这将使其更加简单。如果是这种情况,您只需使用$match
或$group
执行$push
和$addToSet
。
例如:
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" } ] }