Heim > Artikel > Backend-Entwicklung > Aggregation, Einfügen von Daten aus einer Sammlung in eine andere Sammlung
In diesem Artikel stellt Ihnen der PHP-Editor Youzi eine gängige Operation vor – die Aggregation, bei der Daten aus einer Sammlung in eine andere Sammlung eingefügt werden. Aggregationsvorgänge sind in der Programmierung weit verbreitet und können in verschiedenen Szenarien wie dem Zusammenführen von Daten, der Deduplizierung und dem Filtern verwendet werden. Durch Aggregationsvorgänge können wir Daten einfach verarbeiten und verwalten und so die Effizienz und Lesbarkeit des Codes verbessern. Als nächstes werden wir die Verwendung von Aggregationsoperationen und Vorsichtsmaßnahmen im Detail vorstellen, um allen zu helfen, diese Technik besser zu beherrschen.
Ich versuche Folgendes zu tun, um für jeden Chat die letzte Nachricht aus der chat
集合中获取聊天列表,并将发送的 message
-Sammlung eines bestimmten Benutzers zu dieser Liste hinzuzufügen.
Wie das funktioniert, habe ich zwei Methoden, wie unten beschrieben
Zuerst erhalte ich einfach die Liste der Chats mithilfe der Chat-Mitglieder-ID, die zweite Methode verwendet Aggregation, um die letzte Nachricht jedes Chats zu finden, und dann ordne ich einfach die Nachricht der Chat-ID zu
Lieblingschat:
type chat struct { id string `json:"id" bson:"id"` participants []string `json:"participants" bson:"participants"` lastmessage *message `json:"last_message,omitempty" bson:"last_message"` ... }
P.S.
lastmessage
- ist immer Null, ich brauche es nur, um eine Antwort für den Benutzer zu schreiben.
Sammlungmessage
:
type message struct { id string `json:"id" bson:"id"` chatid string `json:"chat_id" bson:"chat_id"` fromid string `json:"from_id" bson:"from_id"` createdate int64 `json:"create_date" bson:"create_date"` body string `json:"body" bson:"body"` updateat int64 `json:"update_at" bson:"update_at"` ... }
Erste Methode: Ich benötige diese Methode, um die aktive Chat-Liste eines bestimmten Chat-Teilnehmers abzurufen.
func activechats(ctx context.context, uid string) ([]*chat, error) { ... filter := bson.d{primitive.e{key: "participants", value: uid}} cursor, err := r.col.find(ctx, filter, nil) if err != nil {...} var ch []*chat if err = cursor.all(ctx, &ch); err != nil {...} if err = cursor.close(ctx); err != nil {...} ... }
Zweite Methode: Ich benötige diese Methode, um die letzte Nachricht jedes Chats abzurufen. Die Eingabe besteht aus einer Reihe von Chat-IDs, und für jeden Chat suche ich nach der letzten Nachricht, falls vorhanden. Dazu verwende ich Aggregation.
func lastmessages(ctx context.context, chatids []string) (map[string]*message, error) { matchstage := bson.d{ primitive.e{ key: "$match", value: bson.d{ primitive.e{ key: "chat_id", value: bson.d{ primitive.e{key: "$in", value: chatids}, }, }, }, }} sortstage := bson.d{primitive.e{key: "$sort", value: bson.d{primitive.e{key: "created", value: -1}}}} groupstage := bson.d{primitive.e{ key: "$group", value: bson.d{ primitive.e{ key: "_id", value: bson.d{ primitive.e{key: "chat_id", value: "$chat_id"}, }, }, primitive.e{ key: "message", value: bson.d{ primitive.e{key: "$first", value: "$$root"}, }, }, }, }} cursor, err := r.colmessage.aggregate(ctx, mongo.pipeline{matchstage, groupstage, sortstage}) if err != nil {...} var res []*aggregationresultgenerated if err = cursor.all(ctx, &res); err != nil {...} ... }
Ich weiß, das ist eine wirklich schlechte Lösung, aber das ist alles, was mir bisher einfällt, und es ist sehr traurig (funktioniert nicht). Ich versuche dieses Problem zu lösen
db.chat.aggregate([ { $match: { participants: "participant_id", }, { $lookup: { from: "message", // other table name localfield: "id", // name of chat table field foreignfield: "chat_id", // name of message table field as: "msg", } }, { $unwind: "$msg", }, { $match: { chat_id : { $in: ["$$root._id"], }, }, }, { $sort: { "created": -1, }, }, { $group: { "_id": { "chat_id": "$chat_id" }, "doc": { "$last": "$$root" } } }, { $project: { last_message: "$msg", } } ])
Meine Frage ist: Wie verwende ich die Aggregation, um eine Liste von Chats für einen bestimmten Benutzer zu erhalten und für jeden Chat die letzte Nachricht im Feld last_message im Objekt chat
aus der message
集合中添加对象 chat
-Sammlung hinzuzufügen?
So funktioniert es jetzt:
{ "chats": [ { "id": "4hWsHam3ZZpoyIw44q3D", "title": "Chat example", "create-date": 1674476855918, "participants": [ "63ce54460aeee5e72c778d90", "63ce54460aeee5e72c778d92" ], "owner_id": "63ce54460aeee5e72c778d90", "last_message": { "id": "tzwekCiCLSXJ4tfdQuHH", "chat_id": "4hWsHam3ZZpoyIw44q3D", "from_id": "63ce54460aeee5e72c778d92", "create_date": 1674557062031, "body": "text", "update_at": 0, "viewed": false }, "unread": 5 }, { "id": "Anjrr9RCWFzq030Cwz7S", "title": "New chat One", "create-date": 1674476909054, "participants": [ "63ce54460aeee5e72c778d90", "63ce54460aeee5e72c778d96" ], "owner_id": "63ce54460aeee5e72c778d90", "last_message": { "id": "7YqhhS1-EfMRSZtGCH0Z", "chat_id": "Anjrr9RCWFzq030Cwz7S", "from_id": "63ce54460aeee5e72c778d96", "create_date": 1674575017115, "body": "text", "update_at": 0, }, "unread": 1 }, ] }
EDIT: Wie im OP in den Kommentaren erwähnt, ist eine Aktualisierung/$merge
der Sammlung nicht erforderlich.
Sie können einfach die Methode $sort
+ $limit
in der Subpipeline von $lookup
ausführen. Führen Sie $unwind
aus, um die Suchergebnisse in das Feld last_message
zu schreiben. Führen Sie abschließend $lookup
的子管道中执行 $sort
+ $limit
方法。执行 $unwind
将查找结果写入 last_message
字段。最后,执行 $merge
以更新回 chat
aus, um wieder auf die chat
-Sammlung zu aktualisieren.
db.chat.aggregate([ { $match: { participants: "63ce54460aeee5e72c778d90", } }, { $lookup: { from: "message", localField: "id", foreignField: "chat_id", pipeline: [ { $sort: { created: -1 } }, { $limit: 1 } ], as: "last_message", } }, { $unwind: { path: "$last_message", preserveNullAndEmptyArrays: true } }, { $project: { last_message: "$last_message" } } ])
Hier ist ein alter Mongo-Spielplatz mit $merge
, der zu einer Sammlung aktualisiert wurde.
Das obige ist der detaillierte Inhalt vonAggregation, Einfügen von Daten aus einer Sammlung in eine andere Sammlung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!