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 } },
        },
    }
);

预期结果:

  1. (有效)如果文档的 link 匹配,
    (有效)应该只有一个带有标题的 object 和 link returned
    例如
    id 变量的值:"a"
    预期查询结果:{ title: "Category A", link: "a"}

  2. (有效)如果子文档的 items.link 匹配,
    (有效)它应该与上面相同 + items 数组中的附加元素 returned.
    例如
    id 变量的值:"a-c"
    预期查询结果:{ title: "Category A", link: "a", items: [{ title: "Item C", link: "a-c" }]}

  3. (有效)如果 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

  4. 的整个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 解决方案并且肯定有改进的余地,但上述似乎实现了能够区分类别、项目和系列结果的最终目标。