0

我想在带有条件的集合列表中获取多个字段。我尝试了聚合请求,但出现错误。

我的请求

db.people.aggregate({$match:{createdDate:{$exists:true},"ad":"noc2"}},{$group:{value2:$value2}});

我的杰森:

    db.test.findOne();
{
        “_id”:ObjectId(“51e7dd16d2f8db27b56ea282”),
        “广告”:“noc2”,
        “列表” : {
                “p45”:{
                        “id”:“p45”,
                        “日期”:ISODate(“2014-01-01T12:18:30.568Z”),
                        “价值3”:21,
                        “价值1”:100,
                        “价值2”:489
                },
                “p6”:{
                        “id”:“p6”
                        “日期”:ISODate(“2013-07-18T12:18:30.568Z”),
                        “价值3”:21,
                        “价值1”:100,
                        “价值2”:489
                },
                “p4578”:{
                       “身份证”:“4578”
                        “日期”:ISODate(“2013-07-18T12:18:30.568Z”),
                        “价值3”:21,
                        “价值1”:100,
                        “价值2”:489
                }
        }
}

例如,我想在结果中获取这个 json:

{id:p45,value:587},{id:p4578,value:47},{id:p6,value:2}
4

1 回答 1

6

您的示例文档和聚合存在几个问题:

  • 示例文档将与您的聚合查询不匹配,因为您正在匹配createdDate现有字段
  • $group()操作员在文档级别工作,需要一个_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运算符来提取匹配的子文档。

从当前的问题描述中不清楚$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,具体取决于您尝试实现的结果。

于 2013-07-20T00:54:37.300 回答