提问者:小点点

聚合请求MongoDB


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

我的请求

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}

共1个答案

匿名用户

示例文档和聚合有几个问题:

  • 示例文档将与您的聚合查询不匹配,因为您匹配的是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添加一个附加的聚合步骤,这取决于您试图实现的结果。