Concat два агрегатных запроса MongoDB - PullRequest
0 голосов
/ 28 апреля 2020

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

{'start': '2011-01-29',
  'target': [0.0, 2.0],
  'cat': [0, 0, 0, 0, 0],
  'state': 0},
...

Мне пришлось выполнить некоторые агрегации в этой коллекции, используя db.collections.aggregate([]), и из-за проблем с производительностью мне пришлось разделить на два запроса.

Первый возвращает меня:

{'_id': {'state': 0, 'id': 0},
  'start': '2011-01-29',
  'cat': [0, 0, 0, 0, 0]}
...

Второй возвращает меня:

{'_id': {'state': 0, 'id': 0},
  'target': [0, 2, 1]
  }
...

Что я хотел бы знать, если есть способ присоединиться снова результаты на основе _id?

Или есть способ объявить оба запроса независимо в один и тот же?

db.collections.aggregate([
query1: {},
query2: {}
concat(query1,query2) ])

Мой желаемый результат:

Снова объединить оба вывода

{'_id': {'state': 0, 'id': 0},
  'start': '2011-01-29',
  'cat': [0, 0, 0, 0, 0]}
...

{'_id': {'state': 0, 'id': 0},
  'target': [0, 2, 1]
  }
...

В этом

{'_id': {'state': 0, 'id': 0},
  'start': '2011-01-29',
  'target': [0, 2, 1]
  'cat': [0, 0, 0, 0, 0]}
...

До сих пор моим решением было использование pymon go:

x1 = db.collection.aggregate(query1)

x2 = db.collection.aggregate(query2)

for i, j in zip(x1, x2):
    j['target'] = i['target']

Ответы [ 2 ]

1 голос
/ 29 апреля 2020

Вы можете получить такое поведение с помощью стадии $ facet , а затем использовать $group, чтобы собрать их вместе

db.collection.aggregate([
   {$facet:{
       query1:[pipeline1],
       query2:[pipeline2]
   }},
   {$project:{
       result:{$concatArrays:["$query1","$query2"]}
   }},
   {$unwind: "$result"},
   {$group: {
         _id:"$_id",
         document: {$mergeObjects:"$$ROOT"}
   }},
   {$replaceRoot:{ newRoot: "$document"}}
])
1 голос
/ 28 апреля 2020

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

Технически вы можете создать две временные коллекции, вставить каждый набор результатов в соответствующую коллекцию, а затем выполнить другую агрегацию ...

...