Maison > Article > développement back-end > Agrégation, insertion de données d'une collection dans une autre collection
Dans cet article, l'éditeur PHP Youzi vous présentera une opération courante : l'agrégation, qui consiste à insérer des données d'une collection dans une autre collection. Les opérations d'agrégation sont très courantes en programmation et peuvent être utilisées dans divers scénarios tels que la fusion de données, la déduplication et le filtrage. Grâce aux opérations d'agrégation, nous pouvons facilement traiter et gérer les données, améliorant ainsi l'efficacité et la lisibilité du code. Ensuite, nous présenterons en détail l’utilisation des opérations d’agrégation et les précautions pour aider chacun à mieux maîtriser cette technique.
J'essaie de faire ce qui suit pour ajouter le dernier message de la collection chat
集合中获取聊天列表,并将发送的 message
d'un utilisateur spécifique à cette liste pour chaque discussion.
Maintenant, comment cela fonctionne, j'ai deux méthodes décrites ci-dessous
Tout d'abord, j'obtiens simplement la liste des discussions en utilisant l'identifiant du membre du chat, la deuxième méthode utilise l'agrégation pour trouver le dernier message de chaque discussion, puis je fais simplement correspondre le message avec l'identifiant du chat
Chat préféré :
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
- est toujours zéro, j'en ai seulement besoin pour écrire une réponse pour l'utilisateur.
Collectionmessage
:
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"` ... }
Première méthode : J'ai besoin de cette méthode pour obtenir la liste de discussion active d'un participant au chat spécifique.
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 {...} ... }
Deuxième méthode : j'ai besoin de cette méthode pour obtenir le dernier message de chaque discussion, l'entrée est un ensemble d'identifiants de discussion, et pour chaque discussion, je recherche le dernier message, le cas échéant. Pour cela, j'utilise l'agrégation.
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 {...} ... }
Je sais que c'est une très mauvaise solution mais c'est tout ce à quoi je pense jusqu'à présent et c'est dommage (ne fonctionne pas). J'essaie de résoudre ce problème
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", } } ])
Ma question est : Comment utiliser l'agrégation pour obtenir une liste de chats pour un utilisateur spécifique et pour chaque chat ajouter le dernier message dans le champ last_message dans l'objet chat
de la collection message
集合中添加对象 chat
?
Comment ça marche maintenant :
{ "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 : Comme l'OP l'a mentionné dans les commentaires, la mise à jour/$merge
de la collection n'est pas nécessaire.
Vous pouvez simplement exécuter la méthode $sort
+ $limit
dans le sous-pipeline de $lookup
. Exécutez $unwind
pour écrire les résultats de la recherche dans le champ last_message
. Enfin, exécutez $lookup
的子管道中执行 $sort
+ $limit
方法。执行 $unwind
将查找结果写入 last_message
字段。最后,执行 $merge
以更新回 chat
pour revenir à la collection chat
.
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" } } ])
Voici un ancien terrain de jeu mongo avec $merge
mis à jour dans une collection.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!