Подтвердить что ты не робот

Mongo group и 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: "$.*"},
}}

Спасибо

4b9b3361

Ответ 2

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

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

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

Вот как вы справляетесь с массивами в агрегации.

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

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

Ответ 3

Если проблема заключается в том, что вы не хотите явно писать все поля (если в вашем документе есть много полей, и вам нужно все это в результате), вы также можете попытаться сделать это с помощью 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; } 
    }
)