Спасибо, Нил, за то, что указал мне правильное направление.

goDB, если бы у меня была коллекция, которая выглядела следующим образом,

{
    "auctionId" : 22,
    "startDt" : "2017-08-28T06:00:00.000Z",
    "endDt" : "2017-09-04T06:00:00.000Z",
    "status" : "Open",
    "pickupDt" : "2017-09-07T06:00:00.000Z",
    "itmLst" : 
    [ 
        {
            "itemId" : 1,
            "location" : "Open",
            "currentBid" : 13.0,
            "highBidder" : 1897,
            "bidCnt" : 4,
            "catgegory" : "ANTIQUES"
             ...

Как я могу запросить его с помощью агрегатной функции, чтобы получить количество отдельных категорий для auctionId = 22, сгруппированных по itmLst.category, чтобы он возвращал набор результатов, который был бы похож на это:

{
    "ANTIQUES": 56,
    "TOOLS": 89,
    "JEWLRY": 45,
    ...
}
 vikasgupta05 сент. 2017 г., 05:12
Что вы пробовалиНик

Ответы на вопрос(1)

Основной случай здесь заключается в использовании.aggregate() с участием$unwind потому что вам нужен доступ к значениям в массиве в качестве ключей группировки и, конечно,$group потому что именно так вы «группируете» вещи:

db.collection.aggregate([
  { "$match": { "auctionId": 22 } },
  { "$unwind": "$itmLst" },
  { "$group": {
    "_id": "$itmLst.category",
    "count": { "$sum": 1 }
  }}
])

Это даст вам вывод, как:

{ "_id": "ANTIQUES", "count": 56 }
{ "_id": "TOOLS", "count": 89 }
{ "_id": "JEWLRY", "count":  45 }

Теперь вы действительно должны научиться жить с этим, потому что «список» в формате курсора по умолчанию - это хорошая вещь, которая естественным образом повторяется. Кроме того, именованные ключи IMHO, естественно, не пригодны для представления данных, и вы обычно хотите иметь общее свойство в итерируемом списке.

Если вы действительно хотите использовать вывод именованных ключей, то вам понадобится MongoDB 3.4.4 или выше, чтобы иметь доступ к$arrayToObject это позволит вам использовать значения в качестве имен ключей, и, конечно,$replaceRoot чтобы использовать это выражение вывода в качестве нового документа для создания:

db.collection.aggregate([
  { "$match": { "auctionId": 22 } },
  { "$unwind": "$itmLst" },
  { "$group": {
    "_id": "$itmLst.category",
    "count": { "$sum": 1 }
  }},
  { "$group": {
    "_id": null,
    "data": { "$push": { "k": "$_id", "v": "$count" } }
  }},
  { "$replaceRoot": {
    "newRoot": {
      "$arrayToObject": "$data"
    }
  }}
])

Или, если у вас нет этой опции, то вместо этого вы должны конвертировать вывод курсора в код:

db.collection.aggregate([
  { "$match": { "auctionId": 22 } },
  { "$unwind": "$itmLst" },
  { "$group": {
    "_id": "$itmLst.category",
    "count": { "$sum": 1 }
  }}
]).toArray().reduce((acc,curr) => 
  Object.assign(acc,{ [curr._id]: curr.count }),
  {}
)

Оба сливаются в один объект с именованными ключами из исходного агрегированного вывода:

{
    "ANTIQUES": 56,
    "TOOLS": 89,
    "JEWLRY": 45,
    ...
}

И это говорит о том, что исходный результат вывода был действительно достаточным, и что обычно вы хотите, чтобы такого рода «окончательное изменение формы» выполнялось в коде, использующем вывод курсора, если вам действительно даже нужно это изменение формы с момента базового необходимые данные были возвращены в любом случае.

 Neil Lunn09 сент. 2017 г., 01:50
@NickKicher Потому что ваш массив элементов, кажется, названitmLst и нетitmList
 Nick Kicher08 сент. 2017 г., 21:35
Спасибо за ваш ответ, Нил, и я согласен с выводом вашего первого решения, но когда я его пробую, он возвращает 0 записей. Ты знаешь, почему это так. Я делаю db.auctions.aggregate ([{"$ match": {"auctionId": 22}}, {"$ unwind": "$ itmList"}, {"$ group": {"_id": "$ itmList.category "," count ": {" $ sum ": 1}}}])

Ваш ответ на вопрос