Как агрегировать на 2 уровнях и хранить документы? - PullRequest
0 голосов
/ 02 октября 2018

Это то, что я использую для Elasticsearch, но я не могу найти, как это сделать с MongoDB.

Вот коллекция животных:

[
  { kind: "Dog", owner: "John", name: "Max" },
  { kind: "Dog", owner: "John", name: "Buddy" },
  { kind: "Dog", owner: "John", name: "Cooper" },
  { kind: "Cat", owner: "John", name: "Charlie" },
  { kind: "Dog", owner: "Peter", name: "Jack" },
]

Вотрезультат, который я ожидаю:

{
  Dog: {
    John: [
      { kind: "Dog", owner: "John", name: "Max" },
      { kind: "Dog", owner: "John", name: "Buddy" },
      { kind: "Dog", owner: "John", name: "Cooper" },
    ],
    Peter: [
      { kind: "Dog", owner: "Peter", name: "Jack" },
    ]
  }
  Cat: {
    John: [
      { kind: "Cat", owner: "John", name: "Charlie" }
    ]
  }
}

Есть идеи сделать это?Я экспериментировал с некоторыми агрегатами $group и $push, но не могу построить этот "вложенный" уровень Animal / Owner / Documents

1 Ответ

0 голосов
/ 02 октября 2018

Вы можете использовать агрегацию ниже в 3.6.

Структура вложенного массива

db.colname.aggregate([
  {"$group":{"_id":{"kind":"$kind","owner":"$owner"},"docs":{"$push":"$$ROOT"}}},
  {"$group":{"_id":"$_id.kind","ownerbykind":{"$push":{"owner":"$_id.owner","docs":"$docs"}}}}
])

ИЛИ

Используйте $mergeObjects с $arrayToObject для получения желаемой структуры.

db.colname.aggregate([
  {"$group":{"_id":{"kind":"$kind","owner":"$owner"},"a":{"$push":"$$ROOT"}}},
  {"$group":{"_id":"$_id.kind","b":{"$mergeObjects":{"$arrayToObject":[[["$_id.owner","$a"]]]}}}},
  {"$group":{"_id":null,"c":{"$mergeObjects":{"$arrayToObject":[[["$_id","$b"]]]}}}},
  {"$replaceRoot":{"newRoot":"$c"}}
])
...