我想在带有条件的集合列表中获得多个字段。我尝试了一个聚合请求,但我有一个错误。
我的请求
db.people.aggregate({$match:{createddate:{$exists:true},“ad”:“noc2”}},{$group:{value2:$value2}});
我的Json:
db.test.findOne(); { "_id" : ObjectId("51e7dd16d2f8db27b56ea282"), "ad" : "noc2", "list" : { "p45" : { "id" : "p45", "date" : ISODate("2014-01-01T12:18:30.568Z"), "value3" : 21, "value1" : 100, "value2" : 489 }, "p6" : { "id" : "p6" "date" : ISODate("2013-07-18T12:18:30.568Z"), "value3" : 21, "value1" : 100, "value2" : 489 }, "p4578" : { "id" : "4578" "date" : ISODate("2013-07-18T12:18:30.568Z"), "value3" : 21, "value1" : 100, "value2" : 489 } } }
例如,我想在result中获得这个json:
{id:p45,value:587},{id:p4578,value:47},{id:p6,value:2}
示例文档和聚合有几个问题:
createddate
字段已存在$group()
运算符在文档级别上工作,需要_id
字段来分组列表
字段是嵌入式文档,而不是数组下面是一个经过调整的示例文档,其中列表
是一个数组,并且每个项目都有一些唯一的值,这些值恰好与您提到的值
数字相加:
db.people.insert({
"ad" : "noc2",
"createdDate" : ISODate(),
"list" : [
{
"id" : "p45",
"date" : ISODate("2014-01-01T12:18:30.568Z"),
"value3" : 21,
"value1" : 77,
"value2" : 489
},
{
"id" : "p6",
"date" : ISODate("2013-07-18T12:18:30.568Z"),
"value3" : 20,
"value1" : 20,
"value2" : 7
},
{
"id" : "4578",
"date" : ISODate("2013-07-18T12:18:30.568Z"),
"value3" : 21,
"value1" : 300,
"value2" : -319
}
]
})
现在可以使用$Unwind
运算符提取匹配的子文档。
从当前的问题描述中不清楚您试图实现什么$group
操作,以及您是否实际需要$group
。
下面是使用聚合框架为每个列表项$add
(total)的三个值的示例:
db.people.aggregate(
// Find relevant docs (can use index if available)
{ $match: {
createdDate: { $exists:true },
"ad":"noc2"
}},
// Convert list array to stream of documents
{ $unwind: "$list" },
// Add (value1, value2, value3) for each list item
{ $project: {
_id: "$list.id",
value: { $add: [ "$list.value1", "$list.value2", "$list.value3"] }
}}
);
示例输出:
{
"result" : [
{
"_id" : "p45",
"value" : 587
},
{
"_id" : "p6",
"value" : 47
},
{
"_id" : "4578",
"value" : 2
}
],
"ok" : 1
}
注意,在本例中,我只使用了一个文档进行聚合,输出的结果文档将是list
数组中的每个项的一个结果文档。
在实际使用中,您可能希望通过文档_id
或其他一些条件向$group
添加一个附加的聚合步骤,这取决于您试图实现的结果。