2014-03-03 10 views
19

Gibt es einen einfachen Weg, um „$ Push“ alle Felder eines Dokuments? Zum Beispiel:Mongo Gruppe und Push: Schieben Sie alle Felder

sagen, dass ich eine Mongo Sammlung der Bücher habe:

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

ich sie zu einer Gruppe von Autor möchte - für jeden Autor, listet seine gesamten Objekte Buch:

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

ich kann dies erreichen, indem er explizit alle Felder drängen:

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

Aber gibt es eine Abkürzung, etwas in den Zeilen:

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

Dank

Antwort

1

Eigentlich kann nicht Sie erreichen, was Sie überhaupt sagen, Sie brauchen $unwind

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

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

Das ist, wie Sie beschäftigen sich mit Arrays in Aggregation.

Und was Sie suchen, um alle Felder Tastaturkürzel eingeben existiert nicht, noch nicht.

Aber speziell wegen dem, was Sie tun müssen, dann Sie könnten nicht, dass sowieso, wie Sie in einer Art und Weise sind, das Dokument Umformung.

+0

Vielen Dank für die Antwort, aber meine Abfrage funktioniert (getestet auf mongo 2.4.9). Vielleicht war meine Beschreibung nicht klar - Entschuldigung, wenn das der Fall ist. Ich beginne mit einer flachen Mongo-Sammlung von Büchern (total "un-wunde") und möchte sie in das erwähnte Format von Autor + seiner Liste von Büchern * gruppieren. –

0

Wenn das Problem ist, dass Sie nicht wollen, explizit alle Felder schreiben (wenn Ihr Dokument viele Felder haben, und Sie müssen alle von ihnen in Folge), können Sie auch versuchen, es zu tun mit 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; } 
    } 
) 
+1

Schön, danke :) IMHO ist es eine Schande, dass solch ein "This" nicht direkt in $ push unterstützt wird, für "Pipeline" -Syntax. Aber vielen Dank für diese interessante Alternative. –

Verwandte Themen