MongoDB - 具有嵌套子文档和投影的 findOne
MongoDB - findOne with nested subdocuments and projection
我目前正在 node.js 中使用下面的代码从 mongo 数据库中查找和 return 各种嵌套级别的数据。我想添加另一层嵌套(如#3 中所述)。
Collection:
[
{
"title": "Category A",
"link": "a",
"items": [
{
"title": "Item C",
"link": "a-c",
"series": [
{
"title": "Item C X",
"link": "a-c-x"
},
{
"title": "Item C Y",
"link": "a-c-y"
},
]
},
{
"title": "Item D",
"link": "a-d"
}
]
},
{
"title": "Category B",
"link": "b"
}
]
查询:
const doc = await ... .findOne(
{
$or: [
{ link: id },
{ "items.link": id },
{ "items.series.link": id }
],
},
{
projection: {
_id: 0,
title: 1,
link: 1,
items: { $elemMatch: { link: id } },
},
}
);
预期结果:
(有效)如果文档的 link
匹配,
(有效)应该只有一个带有标题的 object 和 link returned
例如
id 变量的值:"a"
预期查询结果:{ title: "Category A", link: "a"}
(有效)如果子文档的 items.link
匹配,
(有效)它应该与上面相同 + items 数组中的附加元素 returned.
例如
id 变量的值:"a-c"
预期查询结果:{ title: "Category A", link: "a", items: [{ title: "Item C", link: "a-c" }]}
(有效)如果 sub-subdocument 的 items.series.link
匹配
(为此苦苦挣扎) 它应该 return 与 2 中的相同。+ 匹配的 items.series
中的附加元素
例如
id 变量的值:"a-c-y"
预期查询结果:{ title: "Category A", link: "a", items: [{ title: "Item C", link: "a-c", series: [{ title: "Item C Y", link: "a-c-y" }]}]}
当前查询结果: 全部sub-documents
的整个A类文档
问题:
a.) 如何将投影也修改为 return #3 中的预期输出?
b.) 就非规范化结构的读取速度而言,上述方法是否可靠?我认为 link、items.link 和 items.series.link 可能需要索引,因为它们在文档中都是完全唯一的,但也许有一种方法可以实现上述目标完全不同的方法?
结束了通过 mongodb 的中途并获得了两者的完整项目 - 当项目 link 匹配且系列 link 匹配时:
projection: {
_id: 0,
title: 1,
link: 1,
items: { $elemMatch: { $or: [
{ link: id },
{"series.link": id }
]}},
}
之后javascript过滤series数组看是否匹配series:
doc?.items?.[0]?.series?.find(item => item.link === id)
如果 js 是真实的(returns 一个对象)我们匹配一个系列,如果有一个文档,但是 js 是假的我们匹配一个项目结果。
虽然不是完整的 mongodb 解决方案并且肯定有改进的余地,但上述似乎实现了能够区分类别、项目和系列结果的最终目标。
我目前正在 node.js 中使用下面的代码从 mongo 数据库中查找和 return 各种嵌套级别的数据。我想添加另一层嵌套(如#3 中所述)。
Collection:
[
{
"title": "Category A",
"link": "a",
"items": [
{
"title": "Item C",
"link": "a-c",
"series": [
{
"title": "Item C X",
"link": "a-c-x"
},
{
"title": "Item C Y",
"link": "a-c-y"
},
]
},
{
"title": "Item D",
"link": "a-d"
}
]
},
{
"title": "Category B",
"link": "b"
}
]
查询:
const doc = await ... .findOne(
{
$or: [
{ link: id },
{ "items.link": id },
{ "items.series.link": id }
],
},
{
projection: {
_id: 0,
title: 1,
link: 1,
items: { $elemMatch: { link: id } },
},
}
);
预期结果:
(有效)如果文档的
link
匹配,
(有效)应该只有一个带有标题的 object 和 link returned
例如
id 变量的值:"a"
预期查询结果:{ title: "Category A", link: "a"}
(有效)如果子文档的
items.link
匹配,
(有效)它应该与上面相同 + items 数组中的附加元素 returned.
例如
id 变量的值:"a-c"
预期查询结果:{ title: "Category A", link: "a", items: [{ title: "Item C", link: "a-c" }]}
(有效)如果 sub-subdocument 的
items.series.link
匹配
(为此苦苦挣扎) 它应该 return 与 2 中的相同。+ 匹配的items.series
中的附加元素 例如
id 变量的值:"a-c-y"
预期查询结果:{ title: "Category A", link: "a", items: [{ title: "Item C", link: "a-c", series: [{ title: "Item C Y", link: "a-c-y" }]}]}
当前查询结果: 全部sub-documents 的整个A类文档
问题:
a.) 如何将投影也修改为 return #3 中的预期输出?
b.) 就非规范化结构的读取速度而言,上述方法是否可靠?我认为 link、items.link 和 items.series.link 可能需要索引,因为它们在文档中都是完全唯一的,但也许有一种方法可以实现上述目标完全不同的方法?
结束了通过 mongodb 的中途并获得了两者的完整项目 - 当项目 link 匹配且系列 link 匹配时:
projection: {
_id: 0,
title: 1,
link: 1,
items: { $elemMatch: { $or: [
{ link: id },
{"series.link": id }
]}},
}
之后javascript过滤series数组看是否匹配series:
doc?.items?.[0]?.series?.find(item => item.link === id)
如果 js 是真实的(returns 一个对象)我们匹配一个系列,如果有一个文档,但是 js 是假的我们匹配一个项目结果。
虽然不是完整的 mongodb 解决方案并且肯定有改进的余地,但上述似乎实现了能够区分类别、项目和系列结果的最终目标。