[英]Mongodb populate aggregated field
I want to use $lookup for joining 3 different collections in mongoDB, and populate a ref array with the coresponding data of the ref which is the client collection.我想使用 $lookup 在 mongoDB 中加入 3 个不同的 collections,并使用作为客户端集合的 ref 的对应数据填充一个 ref 数组。
Conversation:对话:
{
_id: mongoose.Schema.Types.ObjectId,
participants: [{ type: mongoose.Schema.Types.ObjectId, ref: "client" }],
created_at: { type: Date, default: Date.now },
}
Message:信息:
{
_id: mongoose.Schema.Types.ObjectId,
conversation_id: { type: mongoose.Schema.Types.ObjectId, ref: "Conversation",
message: { type: String, default: "" },
sender: {type: mongoose.Schema.Types.ObjectId,ref: "Client",default: null},
reciever: {type: mongoose.Schema.Types.ObjectId,ref: "Client",default: null,},
created_at: { type: Date, default: Date.now }
}
Client:客户:
{
_id: mongoose.Schema.Types.ObjectId,
email: {type: String, required: true, unique: true},
name: { type: String, default: "" },
job: { type: String, default: "" },
company: { type: String, default: "" },
school: { type: String, default: "" },
}
Here is what i am usgin now without the populate:这是我现在在没有填充的情况下使用的内容:
Conversation.aggregate([
{ $match: { participants: { $all: [mongoose.Types.ObjectId(myId)] } } },
{
$lookup: {
from: "messages",
localField: "_id",
foreignField: "conversation_id",
as: "messages",
},
},
{
$unwind: { path: "$messages", preserveNullAndEmptyArrays: true },
},
{ $sort: { "messages.created_at": -1 } },
{
$group: {
_id: "$_id",
messages: { $first: "$messages" },
doc: { $first: "$$ROOT" },
},
},
{ $replaceRoot: { newRoot: "$doc" } },
])
This is the result i get:这是我得到的结果:
[
{
"_id": "5f29ca6fc410a01e6fd53ca1",
"participants": [
"5f1c4685546a7741b8c6e801",
"5f1c80d1f52da506603278f1"
],
"messages": {
"_id": "5f2aff3715db59002458f650",
"message": "Thanks man",
"sender": "5f1c80d1f52da506603278f1",
"reciever": "5f1c4685546a7741b8c6e801",
"conversation_id": "5f29ca6fc410a01e6fd53ca1",
"created_at": "2020-08-05T18:49:27.752Z",
"__v": 0
}
},
{
"_id": "5f29c944c410a01e6fd4aa2b",
"participants": [
"5f1c4685546a7741b8c6e801",
"5f05d5e20db0174bd4b55b29"
]
}
]
I want to populate the participants array when i aggregate the conversation with message .当我用message聚合对话时,我想填充参与者数组。
Thank you.谢谢你。
Using aggregate() ,使用聚合() ,
here you can use lookup with pipeline , it can to add all pipelines lookup level,在这里您可以使用管道查找,它可以添加所有管道查找级别,
no need to $unwind and $group无需 $unwind 和 $group
Conversation.aggregate([
{
$match: {
participants: {
$all: [
mongoose.Types.ObjectId(myId)
]
}
}
},
{
$lookup: {
from: "Message",
let: {
conversation_id: "$_id"
},
pipeline: [
{
$match: {
$expr: {
$eq: [
"$$conversation_id",
"$conversation_id"
]
}
}
},
{
$sort: {
"created_at": -1
}
}
],
as: "messages"
}
},
{
$lookup: {
from: "Client",
let: {
participants: "$participants"
},
pipeline: [
{
$match: {
$expr: {
$in: [
"$_id",
"$$participants"
]
}
}
},
{
$sort: {
"created_at": -1
}
}
],
as: "participants"
}
}
])
Playground: https://mongoplayground.net/p/Pz5ojJ_dGGY游乐场: https://mongoplayground.net/p/Pz5ojJ_dGGY
Note: I have assumed the name of the collections so you can correct and change as per your requirement.注意:我假设了 collections 的名称,因此您可以根据您的要求进行更正和更改。
this is the code i got, i changed the id to string only:这是我得到的代码,我将 id 更改为仅字符串:
Conversation.aggregate([
{ $match: { participants: { $all: [mongoose.Types.ObjectId(myId)] } } },
{
$lookup: {
from: "messages",
let: { conversationId: { $toObjectId: "$_id" }},
pipeline: [
{
$match: { $expr: {$eq: ["$$conversationId", "$conversation_id"]}},
},
{
$sort: { create_at: -1 },
},
{ $limit: 1 },
],
as: "messages",
},
},
{
$lookup: {
from: "clients",
let: {participants: "$participants"},
pipeline: [
{
$match: {
$expr: {
$and: [
{ $in: ["$_id", "$$participants"] },
{ $ne: ["$_id", mongoose.Types.ObjectId(myId)] },
]},
},
},
{
$sort: { created_at: -1 },
},
],
as: "participants",
},
},
{
$project: {
_id: 1,
messages: 1,
"participants.name": 1,
"participants.company": 1,
"participants.school": 1,
},
},
])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.