1

Ich habe eine große Sammlung Messages, wie so genannt:Wie wird nur das erste Vorkommen einer ID mit Mongoose zurückgegeben?

{ 
    user: 94fg844f, 
    event: null, 
    group: null, 
    name: "Jake", 
    text: "Hello world" 
}, { 
    user: fje93jrg4, 
    event: null, 
    group: null, 
    name: "Bob" 
    text: "Testing" 
}, { 
    user: fje93jrg4, 
    event: null, 
    group: null, 
    name: "Bob" 
    text: "Text here" 
}, { 
    user: null, 
    event: d0j3n9fn3, 
    group: null, 
    name: "My Event" 
    text: "Testing 2" 
}, { 
    user: null, 
    event: d0j3n9fn3, 
    group: null, 
    name: "My Event" 
    text: "Another text" 
} 

Ich brauche das erste Auftreten der Benutzer, Veranstaltungen und Gruppen zu erhalten.

Da beispielsweise Benutzer fje93jrg4 zweimal auftritt, ich will nur das Dokument wieder mit dem Text von Testing seit dem bekommen mit dem Text von Text here älter ist als sie. Dasselbe gilt für die event von d0j3n9fn3. Es tritt zweimal auf, obwohl ich nur das erste Dokument davon mit dem Text Testing 2 erhalten möchte.

Ich sah in distinct obwohl es scheint nur einen Suchbegriff zu unterstützen, wie user statt user, event und group.

Das Endergebnis der oben wäre:

{ 
    user: 94fg844f, 
    event: null, 
    group: null, 
    name: "Jake", 
    text: "Hello world" 
}, { 
    user: fje93jrg4, 
    event: null, 
    group: null, 
    name: "Bob" 
    text: "Testing" 
}, , { 
    user: null, 
    event: d0j3n9fn3, 
    group: null, 
    name: "My Event" 
    text: "Testing 2" 
} 

Meine Vermutung ist, dass ich wahrscheinlich ein aggregate mit $first oder etwas in diese Richtung verwenden werden müssen. Das Problem mit 3 verschiedenen Abfragen ist, dass ich ein Limit anwenden muss, damit ich immer 10 Ergebnisse zurückbekomme. Zum Beispiel könnte es keine aktuellen group s in der Mischung geben, nur event s und user s.

+1

Könnten Sie zusammen die drei Such anhängen? Auch diese 3 Suchen scheinen sehr unterschiedlich zu sein. Ein Array für die Ausgabe erscheint fast unpassend, weil der Index bedeutungslos ist. – 4castle

+0

@ 4castle - Nur damit kann ein Limit nicht angewendet werden. – Fizzix

+0

Wie identifizieren Sie das erste und letzte Dokument für jeden Benutzer. Sie können sich nicht auf die Reihenfolge der Dokumente in der Sammlung verlassen. – styvane

Antwort

1

können wir Verwenden Sie dazu das Aggregations-Framework. Zuerst müssen wir $sort von user und "_id". Von dort gehen wir dann $group von "user" und verwenden den $last Akku-Operator, um das letzte Dokument für jeden Benutzer zurückzugeben. Beachten Sie, dass wir auch den Akkumulatoroperator $first verwenden können, wenn wir unsere Dokumente in absteigender Reihenfolge sortieren, aber die Sortierung in aufsteigender Reihenfolge und unter Verwendung von $last machen unsere Absicht klar.

db.collection.aggregate([ 
    { "$sort": { "user": 1, "_id": -1 } }, 
    { "$group": { 
     "_id": "$user", 
     "user": { "$last": "$$ROOT" } 
    }} 
]) 

, die produziert:

{ 
    "_id" : "fje93jrg4", 
    "user" : { 
     "_id" : 2, 
     "user" : "fje93jrg4", 
     "event" : null, 
     "group" : null, 
     "name" : "Bob", 
     "text" : "Testing" 
    } 
} 
{ 
    "_id" : "94fg844f", 
    "user" : { 
     "_id" : 1, 
     "user" : "94fg844f", 
     "event" : null, 
     "group" : null, 
     "name" : "Jake", 
     "text" : "Hello world" 
    } 
} 
{ 
    "_id" : null, 
    "user" : { 
     "_id" : 4, 
     "user" : null, 
     "event" : "d0j3n9fn3", 
     "group" : null, 
     "name" : "My Event", 
     "text" : "Testing 2" 
    } 
} 

Wir möchten eine $project unserer Pipeline hinzuzufügen, aber damit wird ein Leistungsabfall verursachen. Es reduziert jedoch sowohl die Menge der über die Verbindung gesendeten Daten als auch die Zeit und den Arbeitsspeicher, die zum Dekodieren von Dokumenten auf der Clientseite verwendet werden, wenn nicht alle Schlüssel/Wert-Paare in einem zurückgegebenen Dokument benötigt werden.

Die $project Bühne sieht wie folgt aus:

{ "$project": { 
    "_id": "$user._id", 
    "user": "$user.user", 
    "event": "$user.event", 
    "group": "$user.group", 
    "name": "$user.name", 
    "text": "$user.text" 
}} 
+0

Sieht gut aus! Was aber passiert, wenn "Benutzer" und "Ereignis" selten dieselbe ID haben? Sie sind unterschiedliche Sammlungen, und meine Sammlung "Nachrichten" verweist nur auf ihre IDs. – Fizzix

+0

Sie müssen das Feld "event" hier nicht berücksichtigen. Alles, was Sie brauchen, ist das "user" und das "_id" oder das "created" Feld, wie Sie in Ihrem [comment] erwähnt haben (https://stackoverflow.com/questions/37582331/how-to-return-only-the- Erstes Vorkommen einer-ID-mit-Mungo/37662481? Noredirect = 1 # Kommentar62794852_37582331) – styvane

+0

Eigentlich ja du hast Recht. Super, danke! – Fizzix

-1

funktioniert perfekt.

db.getCollection ('Mytest') Aggregat ([{$ match: {user: "fje93jrg4"}}, {$ Limit: 1}])

+0

Ich glaube nicht, dass Sie die Frage überhaupt gelesen haben.Ich bin nicht auf der Suche nach einem bestimmten Benutzer, ich muss das erste Ergebnis jedes Benutzers, Gruppe und Ereignis zurückgeben ... – Fizzix

Verwandte Themen