совокупный запрос MongoDB

Я хотел бы получить несколько полей в списке коллекций с условием. Я попробовал агрегированный запрос, но у меня есть ошибка.

Мой запрос

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}

person jonn    schedule 19.07.2013    source источник
comment
Какую ошибку вы получаете?   -  person Makis Tsantekidis    schedule 19.07.2013
comment
Пожалуйста, измените свой result на читаемый Json.   -  person chaliasos    schedule 19.07.2013
comment
ошибка результата: пятница, 19 июля, 12:47:05.623 Ошибка выполнения JavaScript: ReferenceError: $value2 не определено   -  person jonn    schedule 19.07.2013
comment
Я не пытался воспроизвести эту ошибку, а просто быстро проверил, работает ли она. Вы можете попробовать заключить $value2 в двойные кавычки? нравится db.people.aggregate({$match:{createdDate:{$exists:true},"ad":"noc2"}},{$group:{value2:"$value2"}});   -  person Satheesh Kumar    schedule 19.07.2013
comment
У меня есть эта ошибка с цитатой: Ошибка: печать трассировки стека в printStackTrace (src/mongo/shell/utils.js:37:15) в DBCollection.aggregate (src/mongo/shell/collection.js:897:9) в ( оболочка): 1:11 Пт, 19 июля, 13:41:48.026 Сбой выполнения JavaScript: сбой агрегата: { errmsg : исключение: поле группового агрегата 'value2' должно быть определено как выражение внутри объекта, код: 15951, ok: 0 } в src/mongo/shell/collection.js:L898   -  person jonn    schedule 19.07.2013
comment
Вам не нужно повторять эту ошибку, почему? Удалось ли вам бежать?   -  person jonn    schedule 19.07.2013
comment
Можете ли вы показать документы JSON, соответствующие результатам, которые вы хотите получить? Образец JSON, который вы даете, кажется, отличается от результата образца, который вы хотите получить.   -  person innoSPG    schedule 19.07.2013
comment
как это: {id: p45, значение: 587}, {id: p4578, значение: 47}, {id: p6, значение: 2}   -  person jonn    schedule 19.07.2013
comment
Вы подсчитываете, сколько раз значение2 встречается для каждого поля идентификатора? Какой именно результат вы хотите получить? Хотя вы дали нам пример формата результата, он не показывает, какой тип агрегации вы хотите выполнить здесь, в примере. Вы хотите подсчитать количество вхождений или суммировать значения и т. д.? Спасибо.   -  person Sai    schedule 20.07.2013


Ответы (1)


Есть несколько проблем с образцом документа и агрегацией:

  • образец документа не будет соответствовать вашему запросу агрегации, потому что вы сопоставляете 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.

Вот пример использования Aggregation Framework для $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 или некоторым другим критериям, в зависимости от результата, которого вы пытаетесь достичь.

person Stennie    schedule 20.07.2013