猫鼬嵌套查找,数组中包含 3 个子级别
Mongoose nested lookup with 3 child levels included in arrays
我是 MongoDB 和猫鼬的新手。
我正在尝试从数据库中检索整个对象层次结构数组作为 JSON。
通过搜索,我学会了如何在没有数组的情况下将嵌套查找与 3 个子级别分组,但问题是我找不到处理嵌套数组的方法。
这就是我正在努力解决的问题。
用户:
[
{
_id: ObjectId("a1"),
username: "user1",
name: "name1"
},
{
_id: ObjectId("a2"),
username: "user2",
name: "name2"
},
{
_id: ObjectId("a3"),
username: "user2",
name: "name2"
},
...
]
回复:
[
{
_id: ObjectId("a"),
author: {ObjectId("a3")},
title: {"Reply1"};
body: {"Hello World!"}
},
{
_id: ObjectId("b"),
author: {ObjectId("a1")},
title: {"Reply2"};
body: {"Hello World!"}
},
{
_id: ObjectId("c"),
author: {ObjectId("a2")},
title: {"Reply3"};
body: {"Hello World!"}
},
{
_id: ObjectId("d"),
author: {ObjectId("a2")},
title: {"Reply4"};
body: {"Hello World!"}
}
...
]
post:
[
//First post
{
_id: ObjectId("0"),
title: 'post title',
author: {ObjectId("a1")},
reply: [{ObjectId("a")}, {ObjectId("b")}, ...],
},
//Second Post
{
_id: ObjectId("1"),
title: 'post title2',
author: {ObjectId("a2")},
reply: [{ObjectId("c")}, {ObjectId("d")}, ...],
},
...
]
预期示例:
[
//First post
{
_id: ObjectId("0"),
title: 'post title',
author: {
_id: ObjectId("a1"),
username: "user1",
name: "name1"
},
reply: [{
_id: ObjectId("a"),
author: {
_id: ObjectId("a3"),
username: "user2",
name: "name2"
},
title: {"Reply1"},
body: {"Hello World!"}
},
{
_id: ObjectId("b"),
author: {
_id: ObjectId("a1"),
username: "user1",
name: "name1"
},
title: {"Reply2"};
body: {"Hello World!"}
},
...
],
},
{
//Second post
},
...
]
这是我使用的代码。
posts = await Post.aggregate([{
$match: searchQuery
},
{
$lookup: {
from: 'users',
localField: 'author',
foreignField: '_id',
as: 'author'
}
},
{
$lookup: {
from: 'replies',
localField: 'reply',
foreignField: '_id',
as: 'reply'
}
},
{
$unwind: '$author',
},
{
$lookup: {
from: 'users',
localField: 'reply.author',
foreignField: '_id',
as: 'reply.author'
}
},
{
$project: {
title: 1,
author: 1,
reply: 1
}
},
]).exec();
如果想得到预期的例子,应该怎么改代码呢?
谢谢。
这是一种方法。 post
的作者 "$lookup"
,post
的 reply
,reply
的作者 id,然后匹配 _id
的作者文档。
db.post.aggregate([
{
"$lookup": {
"from": "user",
"localField": "author",
"foreignField": "_id",
"as": "author"
}
},
{
"$set": {
"author": {
"$first": "$author"
}
}
},
{
"$lookup": {
"from": "reply",
"localField": "reply",
"foreignField": "_id",
"as": "reply"
}
},
{
"$lookup": {
"from": "user",
"localField": "reply.author",
"foreignField": "_id",
"as": "replyAuthors"
}
},
{
"$project": {
"title": 1,
"author": 1,
"reply": {
"$map": {
"input": "$reply",
"as": "repObj",
"in": {
"$mergeObjects": [
"$$repObj",
{
"author": {
"$first": {
"$filter": {
"input": "$replyAuthors",
"as": "repA",
"cond": {
"$eq": [
"$$repA._id",
"$$repObj.author"
]
}
}
}
}
}
]
}
}
}
}
}
])
在 mongoplayground.net 上试用。
我是 MongoDB 和猫鼬的新手。
我正在尝试从数据库中检索整个对象层次结构数组作为 JSON。
通过搜索,我学会了如何在没有数组的情况下将嵌套查找与 3 个子级别分组,但问题是我找不到处理嵌套数组的方法。
这就是我正在努力解决的问题。
用户:
[
{
_id: ObjectId("a1"),
username: "user1",
name: "name1"
},
{
_id: ObjectId("a2"),
username: "user2",
name: "name2"
},
{
_id: ObjectId("a3"),
username: "user2",
name: "name2"
},
...
]
回复:
[
{
_id: ObjectId("a"),
author: {ObjectId("a3")},
title: {"Reply1"};
body: {"Hello World!"}
},
{
_id: ObjectId("b"),
author: {ObjectId("a1")},
title: {"Reply2"};
body: {"Hello World!"}
},
{
_id: ObjectId("c"),
author: {ObjectId("a2")},
title: {"Reply3"};
body: {"Hello World!"}
},
{
_id: ObjectId("d"),
author: {ObjectId("a2")},
title: {"Reply4"};
body: {"Hello World!"}
}
...
]
post:
[
//First post
{
_id: ObjectId("0"),
title: 'post title',
author: {ObjectId("a1")},
reply: [{ObjectId("a")}, {ObjectId("b")}, ...],
},
//Second Post
{
_id: ObjectId("1"),
title: 'post title2',
author: {ObjectId("a2")},
reply: [{ObjectId("c")}, {ObjectId("d")}, ...],
},
...
]
预期示例:
[
//First post
{
_id: ObjectId("0"),
title: 'post title',
author: {
_id: ObjectId("a1"),
username: "user1",
name: "name1"
},
reply: [{
_id: ObjectId("a"),
author: {
_id: ObjectId("a3"),
username: "user2",
name: "name2"
},
title: {"Reply1"},
body: {"Hello World!"}
},
{
_id: ObjectId("b"),
author: {
_id: ObjectId("a1"),
username: "user1",
name: "name1"
},
title: {"Reply2"};
body: {"Hello World!"}
},
...
],
},
{
//Second post
},
...
]
这是我使用的代码。
posts = await Post.aggregate([{
$match: searchQuery
},
{
$lookup: {
from: 'users',
localField: 'author',
foreignField: '_id',
as: 'author'
}
},
{
$lookup: {
from: 'replies',
localField: 'reply',
foreignField: '_id',
as: 'reply'
}
},
{
$unwind: '$author',
},
{
$lookup: {
from: 'users',
localField: 'reply.author',
foreignField: '_id',
as: 'reply.author'
}
},
{
$project: {
title: 1,
author: 1,
reply: 1
}
},
]).exec();
如果想得到预期的例子,应该怎么改代码呢? 谢谢。
这是一种方法。 post
的作者 "$lookup"
,post
的 reply
,reply
的作者 id,然后匹配 _id
的作者文档。
db.post.aggregate([
{
"$lookup": {
"from": "user",
"localField": "author",
"foreignField": "_id",
"as": "author"
}
},
{
"$set": {
"author": {
"$first": "$author"
}
}
},
{
"$lookup": {
"from": "reply",
"localField": "reply",
"foreignField": "_id",
"as": "reply"
}
},
{
"$lookup": {
"from": "user",
"localField": "reply.author",
"foreignField": "_id",
"as": "replyAuthors"
}
},
{
"$project": {
"title": 1,
"author": 1,
"reply": {
"$map": {
"input": "$reply",
"as": "repObj",
"in": {
"$mergeObjects": [
"$$repObj",
{
"author": {
"$first": {
"$filter": {
"input": "$replyAuthors",
"as": "repA",
"cond": {
"$eq": [
"$$repA._id",
"$$repObj.author"
]
}
}
}
}
}
]
}
}
}
}
}
])
在 mongoplayground.net 上试用。