


Aggregation, inserting data from one collection into another collection
php editor Youzi will introduce you to a common operation in this article - aggregation, that is, inserting data from one collection into another collection. Aggregation operations are very common in programming and can be used in various scenarios such as merging data, deduplication, and filtering. Through aggregation operations, we can easily process and manage data, improving the efficiency and readability of the code. Next, we will introduce the use and precautions of aggregation operations in detail to help everyone better master this technique.
Question content
I'm trying to do the following to get the list of chats from a specific user's chat
collection and send the message
collection The last message in is added to this list for each chat.
Now how this works, I have two methods as described below
First, I just get the list of chats using the chat member id, the second method uses aggregation to find the last message of each chat, then I just match the message with the chat id
Favorites Chat:
type chat struct { id string `json:"id" bson:"id"` participants []string `json:"participants" bson:"participants"` lastmessage *message `json:"last_message,omitempty" bson:"last_message"` ... }
Note
lastmessage
- is always zero, I only need it to write a response for the user.
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"` ... }
First method: I need this method to get the active chat list of a specific chat participant.
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 {...} ... }
Second method: I need this method to get the last message of each chat, the input is a set of chat ids, and for each chat I search for the last message (if there is ). For this I use 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 {...} ... }
I know this is a really bad solution, but this is all I can think of so far and it's a shame (doesn't work). I try to solve this problem
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", } } ])
My question is: How to use aggregation to get a list of chats for a specific user and for each chat add the last message in the field last_message in the object chat
from the message
collection information?
How it works now:
{ "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 }, ] }
Workaround
Edit: As the OP mentioned in the comments, update/$merge
to the collection is not necessary.
You can simply execute the $sort
$limit
method in a sub-pipeline of $lookup
. Execute $unwind
to write the search results into the last_message
field. Finally, execute $merge
to update back the chat
collection.
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" } } ])
Here is an old mongo playground updated with $merge
to a collection.
The above is the detailed content of Aggregation, inserting data from one collection into another collection. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics











Go language performs well in building efficient and scalable systems. Its advantages include: 1. High performance: compiled into machine code, fast running speed; 2. Concurrent programming: simplify multitasking through goroutines and channels; 3. Simplicity: concise syntax, reducing learning and maintenance costs; 4. Cross-platform: supports cross-platform compilation, easy deployment.

Golang is better than C in concurrency, while C is better than Golang in raw speed. 1) Golang achieves efficient concurrency through goroutine and channel, which is suitable for handling a large number of concurrent tasks. 2)C Through compiler optimization and standard library, it provides high performance close to hardware, suitable for applications that require extreme optimization.

Golang and Python each have their own advantages: Golang is suitable for high performance and concurrent programming, while Python is suitable for data science and web development. Golang is known for its concurrency model and efficient performance, while Python is known for its concise syntax and rich library ecosystem.

Golang is better than Python in terms of performance and scalability. 1) Golang's compilation-type characteristics and efficient concurrency model make it perform well in high concurrency scenarios. 2) Python, as an interpreted language, executes slowly, but can optimize performance through tools such as Cython.

Goimpactsdevelopmentpositivelythroughspeed,efficiency,andsimplicity.1)Speed:Gocompilesquicklyandrunsefficiently,idealforlargeprojects.2)Efficiency:Itscomprehensivestandardlibraryreducesexternaldependencies,enhancingdevelopmentefficiency.3)Simplicity:

C is more suitable for scenarios where direct control of hardware resources and high performance optimization is required, while Golang is more suitable for scenarios where rapid development and high concurrency processing are required. 1.C's advantage lies in its close to hardware characteristics and high optimization capabilities, which are suitable for high-performance needs such as game development. 2.Golang's advantage lies in its concise syntax and natural concurrency support, which is suitable for high concurrency service development.

Golang and C each have their own advantages in performance competitions: 1) Golang is suitable for high concurrency and rapid development, and 2) C provides higher performance and fine-grained control. The selection should be based on project requirements and team technology stack.

The performance differences between Golang and C are mainly reflected in memory management, compilation optimization and runtime efficiency. 1) Golang's garbage collection mechanism is convenient but may affect performance, 2) C's manual memory management and compiler optimization are more efficient in recursive computing.
