这是mongodb游乐场中的代码。
我有一个查询,如下所示:
db.posts.aggregate({
$lookup: {
from: "users",
let: {comments: "$comments"},
pipeline: [
{$match: {$expr: {$in: ["$_id", "$$comments.userId"]} }},
{"$addFields":{"text": "$$comments.text"}}
],
as: "comments"
}
})
这个查询的问题是,我得到的text
值是一个包含所有comments
文本的数组。如果我尝试用userId
进行筛选,我会遇到另一个问题。如果用户评论了不止一次,则text
值将是一个包含其所有comments
的数组。
如何将查找到的用户和他们的评论作为一个对象?
编辑
我预计结果如下:
[
{
"_id": ObjectId("5a934e000102030405000000"),
"id": "1",
"comments": [
{
"_id": "u1",
"name": "James",
"username": "jamo",
"text": "Hi there, who are you?"
},
{
"_id": "u1",
"name": "James",
"username": "jamo",
"text": "Hi! Are you still there?"
}
],
}
]
$unwind
解构comments
数组- CCD_ 8加入用户集合
$unwind
获取user
的对象- 由
_id
重建$group
并用所需字段重建comments
db.posts.aggregate([
{ $unwind: "$comments" },
{
$lookup: {
from: "users",
localField: "comments.userId",
foreignField: "_id",
as: "comments.user"
}
},
{ $unwind: "$comments.user" },
{
$group: {
_id: "$_id",
id: { $first: "$id" },
comments: {
$push: {
_id: "$comments._id",
text: "$comments.text",
username: "$comments.user.username",
name: "$comments.user.name"
}
}
}
}
])
游乐场
第二个选项,不带$unwind
、
$lookup
和users
集合$map
迭代comments
数组的循环$filter
迭代查找users
数组并查找匹配的用户信息$arrayElemAt
从$filter返回已筛选用户的第一个对象$mergeObjects
将合并评论对象和用户信息
db.posts.aggregate([
{
$lookup: {
from: "users",
localField: "comments.userId",
foreignField: "_id",
as: "users"
}
},
{
$project: {
comments: {
$map: {
input: "$comments",
as: "c",
in: {
$mergeObjects: [
"$$c",
{
$arrayElemAt: [
{
$filter: {
input: "$users",
cond: { $eq: ["$$c.userId", "$$this._id"] }
}
},
0
]
}
]
}
}
}
}
}
])
游乐场
我还没有测试这两个查询的性能,请尝试使用合适的查询