Многоуровневая группа $, использующая mongodb - PullRequest
2 голосов
/ 26 мая 2019

Я пытаюсь получить счетчик всех различных значений ключа в моем MongoDB.Я также получаю счет, но я получаю его с двумя различными объектами.

{ "_id" : ObjectId("596f6e95b6a1aa8d363befeb"), produce:"potato","variety" : "abc", "state" : 'PA' }

{ "_id" : ObjectId("596f6e95b6a1aa8d363befec"), produce:"potato", "variety" : "abc", "state" : 'PA' }

{ "_id" : ObjectId("596f6e95b6a1aa8d363befed"), produce:"potato", "variety" : "def", "state" : 'IA' }

{ "_id" : ObjectId("596f6e95b6a1aa8d363befee"), produce:"potato", "variety" : "def", "state" : 'IA' }

{ "_id" : ObjectId("596f6e95b6a1aa8d363befef"), produce:"potato", "variety" : "abc", "state" : 'DA' }

{ "_id" : ObjectId("596f6e95b6a1aa8d363befeg"), produce:"potato", "variety" : "abc", "state" : 'DA' }

{ "_id" : ObjectId("596f6e95b6a1aa8d363befeh"), produce:"potato", "variety" : "def", "state" : 'DA' }

{ "_id" : ObjectId("596f6e95b6a1aa8d363befei"), produce:"potato", "variety" : "abc", "state" : 'IA' }

db.aggregate([


    {
       $match:{produce: "potato"}
    },
    {
       "$group":{
          "_id":{"variety":"$variety","state":"$state"},
          "count":{"$sum":1}
        }    
    },
    {
       "$group":{
           "_id":null,
                "counts":{
                    "$push": {"filterkey":"$_id.variety","state":"$_id.state","count":"$count"}
                }
         }
     },
])

Фактический результат: - рассчитывает

[

    { filterkey: 'abc', state: 'PA', count: 2},
    { filterkey: 'abc', state: 'IA', count: 1},
    { filterkey: 'abc', state: 'DA', count: 2},
    { filterkey: 'def', state: 'IA', count: 2},
    { filterkey: 'def', state: 'DA', count: 1}
]

Ожидаемый результат: - рассчитывает

[

    { filterkey: 'abc', states:{'PA':2,'IA':1,'DA':2},
    { filterkey: 'def', states:{'IA':2,'DA':1}
]

Есть ли какой-нибудь способ получить такие данные?

1 Ответ

1 голос
/ 26 мая 2019

Вам необходимо использовать многоуровневый $group ing здесь. Сначала вам нужно использовать $group с полями variety и state и вам нужно $sum, чтобы получить общее количество уникальных документов на variety и state.

Затем, во-вторых, вам нужно использовать $group с variety, чтобы получить количество уникальных документов на variety.

И, наконец, $arrayToObject, чтобы сгладить массив states.

db.collection.aggregate([
  { "$match": { "produce": "potato" }},
  { "$group": {
    "_id": { "variety": "$variety", "state": "$state" },
    "count": { "$sum": 1 }
  }},
  { "$group": {
    "_id": "$_id.variety",
    "states": {
      "$push": {
        "k": "$_id.state",
        "v": "$count"
      }
    }
  }},
  { "$addFields": {
    "states": {
      "$arrayToObject": "$states"
    }
  }}
])

Вы можете удалить этапы один за другим здесь и посмотреть, что на самом деле происходит.

выход

[
  {
    "_id": "def",
    "states": {
      "DA": 1,
      "IA": 2
    }
  },
  {
    "_id": "abc",
    "states": {
      "DA": 2,
      "IA": 1,
      "PA": 2
    }
  }
]
...