Монго групп и пуш: пуш все поля

Есть ли простой способ "$push" для всех полей документа? Например:

Скажем, у меня есть монгольская коллекция книг:

{author: "tolstoy", title:"war & peace", price:100, pages:800}
{author: "tolstoy", title:"Ivan Ilyich", price:50,  pages:100}

Я хотел бы сгруппировать их по автору - для каждого автора перечислите целые объекты его книги:

{ author: "tolstoy",
  books: [
     {author: "tolstoy", title:"war & peace", price:100, pages:800}
     {author: "tolstoy", title:"Ivan Ilyich", price:50,  pages:100}
  ]
}

Я могу добиться этого, явно нажав на все поля:

{$group: {
     _id: "$author",
     books:{$push: {author:"$author", title:"$title", price:"$price", pages:"$pages"}},
}}

Но есть ли какой-нибудь ярлык, что-то вроде:

// Fictional syntax...
{$group: {
    _id: "$author",
    books:{$push: "$.*"},
}}

3 ответа

Решение

Вы можете использовать $$ROOT

{ $group : {
            _id : "$author",
            books: { $push : "$$ROOT" }
        }}

Найдено здесь: как использовать агрегат mongodb и получать целые документы

На самом деле вы не можете добиться того, что говорите, вам нужно $ раскрутить

db.collection.aggregate([
    {$unwind: "$books"},

    {$group: {
         _id: "$author",
         books:{$push: {
             author:"$books.author",
             title:"$books.title",
             price:"$books.price",
             pages:"$books.pages"
         }},
    }}
])

Вот как вы работаете с массивами в агрегации.

И то, что вы ищете для быстрого набора всех полей, еще не существует.

Но, в частности, из-за того, что вы должны сделать, вы не могли бы сделать это в любом случае, изменяя форму документа.

Если проблема заключается в том, что вы не хотите явно писать все поля (если в вашем документе много полей, и вам все они нужны в результате), вы также можете попробовать сделать это с помощью Map-Reduce:

db.books.mapReduce(
    function () { emit(this.author, this); },
    function (key, values) { return { books: values }; },
    { 
        out: { inline: 1 },
        finalize: function (key, reducedVal) { return reducedVal.books; } 
    }
) 
Другие вопросы по тегам