我想在带有条件的集合列表中获取多个字段。我尝试了一个聚合请求,但是我有一个错误。
我的要求
db.people.aggregate({$match:{createdDate:{$exists:true},"ad":"noc2"}},{$group:{value2:$value2}});
我的杰森:
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 } } }
我想得到这个json,例如,结果:
{id:p45,value:587},{id:p4578,value:47},{id:p6,value:2}
答案 0 :(得分:5)
您的示例文档和聚合有几个问题:
createdDate
字段现有$group()
operator适用于文档级别,需要_id
字段进行分组list
字段是嵌入式文档,而不是数组以下是调整后的示例文档,其中list
为数组,并且每个项目的一些唯一值恰好与您提到的value
数字相加:
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
operator来提取匹配的子文档。
目前的问题描述尚不清楚您尝试实现的$group
操作以及您是否确实需要$group
。
以下是使用聚合框架$add
(总计)每个列表项的三个值的示例:
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
数组中每个项目的一个结果文档。
在实际使用中,您可能希望按文档$group
或其他一些标准向_id
添加其他聚合步骤,具体取决于您尝试实现的结果。