Агрегация MongoDB `$ group`: указать оператор по умолчанию? - PullRequest
0 голосов
/ 08 сентября 2018

Я делаю $group в моем конвейере агрегации, где я $push одно свойство для массива, а для всех оставшихся свойств я просто беру $first:

{ $group: { 
  '_id': '$_id', 
  property1: { $push: '$property1' }, 
  property2: { $first: '$property2' }, 
  property3: { $first: '$property3' }, 
  property4: { $first: '$property4' }, 
  property5: { $first: '$property5' }, 
  property6: { $first: '$property6' }, 
  property7: { $first: '$property7' }, 
  // …
}},

Есть ли возможность указать это более кратко? Я надеюсь на что-то вроде следующего (которое не работает), чтобы сказать «используйте $push для property1 и $first для чего-либо еще»:

{ $group: { 
  '_id': '$_id', 
  property1: { $push: '$property1' }, 
  '*': { $first: '$*' }
}},

Ответы [ 2 ]

0 голосов
/ 11 сентября 2018

Как указывалось выше Энтони Винцлетом, этого добиться невозможно с помощью оператора $group. Однако я использовал следующий обходной путь, который избавил меня от необходимости перечислять все эти свойства явно. Вероятно, это не стоит хлопот из-за небольшого количества свойств, и если вам не нужно заботиться о гибкости, дополнительные могут быть добавлены позже, но в моем случае это имело смысл.

Вот идея конвейера агрегации:

  1. Используйте $addFields, чтобы добавить весь корневой документ как временную копию.
  2. Укажите групповой этап, в котором вы добавляете $push для требуемого свойства и для всего скопированного поддокумента, указанного ранее, используйте оператор $first.
  3. Используйте $replaceRoot и $mergeObjects, чтобы взять скопированный корневой документ, и замените свойство агрегацией $push.

Вот пример:

db.getCollection('test').aggregate([
  { $addFields: { tempRoot: '$$ROOT' } },
  { $group: { '_id': '$property1', 'property2': { $push: '$property2' }, 'tempRoot': { $first: '$tempRoot' } } },
  { $replaceRoot: { newRoot: { $mergeObjects: [ '$tempRoot', { property2: '$property2' } ] } } }
]);
0 голосов
/ 11 сентября 2018

Нет, другого пути нет. Необходимо указать каждое поле с аккумулятором $first на этапе $group.

Но вы можете не указывать $first для каждого поля. Как то так

{ "$group": { 
  "_id": "$_id", 
  "property1": { "$push": "$property1" }, 
  "data": {
    "$first": {
      "property2": "$property2", 
      "property3": "$property3", 
      "property4": "$property4", 
      "property5": "$property5", 
      "property6": "$property6", 
      "property7": "$property7"
    }
  }
}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...