MongoDb - 如何在使用查找聚合时仅 return 嵌套子文档的字段?
MongoDb - How to only return field of nested subdocument when using lookup aggregation?
我对 MongoDb 很陌生,所以我习惯了 SQL。
现在我的数据库中有两个 collections:
1) 系列(具有嵌套的子文档)
2)评论(决定引用剧集子文档,因为会有很多评论)
查看这张图片可以更好地理解。
现在我要实现以下目标。对于每条评论(在本例中为两条),我想获取剧集名称。
我尝试了以下方法:
db.review.aggregate([
{
$lookup:{
from:"series",
localField:"episode",
foreignField:"seasons.episodes._id",
as:"episode_entry"
}
}
]).pretty()
问题是这个 returns(当然)不仅是引用剧集的标题,而且 returns 整季文档。
我目前的输出见下图
不知道怎么实现。请帮我。
我正在使用 Mongo 3.4.9
我会推荐以下系列结构,它将季节数组展开为多个文档,每个季节一个。
这将帮助您直接 inserting/updating 剧集。
类似于
db.series.insertMany([
{
"title": "Sherlock Holmes",
"nr": 1,
"episodes": [
{
"title": "A Study in Pink",
"nr": 1
},
{
"title": "The Blind Banker",
"nr": 2
}
]
},
{
"title": "Sherlock Holmes",
"nr": 2,
"episodes": [
{
"title": "A Scandal in Belgravia",
"nr": 1
},
{
"title": "The Hounds of Baskerville",
"nr": 2
}
]
}
])
查找查询会做这样的事情
episode: { $in: [ episodes._id1, episodes._id2, ... ] }
来自文档
If the field holds an array, then the $in operator selects the
documents whose field holds an array that contains at least one
element that matches a value in the specified array (e.g. , , etc.)
所以当有匹配项时,查找将 return 所有剧集。然后您可以过滤以仅保留与您的评论剧集相匹配的那一集。
所以查询看起来像
db.review.aggregate([
{
"$lookup": {
"from": "series",
"localField": "episode",
"foreignField": "episodes._id",
"as": "episode_entry"
}
},
{
"$addFields": {
"episode_entry": [
{
"$arrayElemAt": {
"$filter": {
"input": {
"$let": {
"vars": {
"season": {
"$arrayElemAt": [
"$episode_entry",
0
]
}
},
"in": "$$season.episodes"
}
},
"as": "result",
"cond": {
"$eq": [
"$$result._id",
"$episode"
]
}
}
}
},
0
]
}
}
])
我对 MongoDb 很陌生,所以我习惯了 SQL。 现在我的数据库中有两个 collections:
1) 系列(具有嵌套的子文档)
2)评论(决定引用剧集子文档,因为会有很多评论)
查看这张图片可以更好地理解。
现在我要实现以下目标。对于每条评论(在本例中为两条),我想获取剧集名称。
我尝试了以下方法:
db.review.aggregate([
{
$lookup:{
from:"series",
localField:"episode",
foreignField:"seasons.episodes._id",
as:"episode_entry"
}
}
]).pretty()
问题是这个 returns(当然)不仅是引用剧集的标题,而且 returns 整季文档。
我目前的输出见下图
不知道怎么实现。请帮我。 我正在使用 Mongo 3.4.9
我会推荐以下系列结构,它将季节数组展开为多个文档,每个季节一个。
这将帮助您直接 inserting/updating 剧集。
类似于
db.series.insertMany([
{
"title": "Sherlock Holmes",
"nr": 1,
"episodes": [
{
"title": "A Study in Pink",
"nr": 1
},
{
"title": "The Blind Banker",
"nr": 2
}
]
},
{
"title": "Sherlock Holmes",
"nr": 2,
"episodes": [
{
"title": "A Scandal in Belgravia",
"nr": 1
},
{
"title": "The Hounds of Baskerville",
"nr": 2
}
]
}
])
查找查询会做这样的事情
episode: { $in: [ episodes._id1, episodes._id2, ... ] }
来自文档
If the field holds an array, then the $in operator selects the documents whose field holds an array that contains at least one element that matches a value in the specified array (e.g. , , etc.)
所以当有匹配项时,查找将 return 所有剧集。然后您可以过滤以仅保留与您的评论剧集相匹配的那一集。
所以查询看起来像
db.review.aggregate([
{
"$lookup": {
"from": "series",
"localField": "episode",
"foreignField": "episodes._id",
"as": "episode_entry"
}
},
{
"$addFields": {
"episode_entry": [
{
"$arrayElemAt": {
"$filter": {
"input": {
"$let": {
"vars": {
"season": {
"$arrayElemAt": [
"$episode_entry",
0
]
}
},
"in": "$$season.episodes"
}
},
"as": "result",
"cond": {
"$eq": [
"$$result._id",
"$episode"
]
}
}
}
},
0
]
}
}
])