【问题标题】:How do I pick then sort MongoDB documents and then find next document to mine?如何选择然后对 MongoDB 文档进行排序,然后找到下一个要挖掘的文档?
【发布时间】:2021-11-21 22:22:30
【问题描述】:

我有一个文档集合,我需要首先按设置的条件缩小范围,然后按这些文档中的字符串值按字母顺序排序——假设这是一个“搜索结果”。然后我需要找到与给定 _id 匹配的文档,然后从上面的“搜索结果”中选择它旁边的文档(之前或之后)。

背景:

我使用猫鼬通过 Node.js 查询我的数据库。

我的博客中有一组“特殊部分”,其中包含所有文章,这些文章必须在文档中的键中关联三个特定条件。我可以像这样获取属于所述部分的文章列表:

const specialSectionListQuery = Article.find({
  tag: { $ne: "excluded" },
  [`collections.cameras`]: { $exists: true },
  status: "published",
})

要完成“特殊部分”的创建,我必须通过它们的title 属性按字母顺序对文档进行排序:

.sort({ [`collections.cameras.as.title`]: "asc" })

现在我想在此类文章的底部添加指向“同一特殊部分中的下一篇文章”的链接。我知道_id 以及当前文章所需的任何其他值。上面的查询为我提供了该部分中的有序文档列表,因此我可以在该列表中轻松找到它specialSectionListQuery.findOne({ _id: "xxx" }).exec()

但是,我需要在上面的列表中找到下一篇文章。我该怎么做?

到目前为止我的尝试:

我试图通过聚合创建文章列表,但结果一无所获(我只是让我的应用程序做同样的事情——为“特殊部门”创建一个列表):

Article.aggregate([
  {
    $match: {
      tag: { $ne: "excluded" },
      [`collections.cameras`]: { $exists: true },
      status: "published",
    },
  },
  {
    $sort: {
      [`collections.cameras.as.title`]: 1,
    },
  }
]).exec()

但我终其一生都无法弄清楚如何正确地迭代到列表中的下一个文档。

我曾想过将列表保存在 Node.js 内存(变量)中,然后通过 JavaScript 找到我需要的内容,但这无法扩展。

我考虑过创建一个新集合并将上面的列表保存在那里,但这需要我 1) 每次通过 Node.js 更改/添加/删除文档时都执行此操作 — 这需要大量代码如果我以另一种方式与数据库交互,可能会中断 2) 每次运行查询时都重建集合,但感觉它会缺乏性能。

请帮忙,谢谢!

附: 示例集合应该涵盖我要解决的大多数情况:

[
  {
    _id: 1,
    name: "Canon",
    collections: { cameras: { as: { title: "Half-Frame" } } },
    tag: "included",
    status: "published"
  },
  {
    _id: 2,
    name: "Pentax",
    collections: { cameras: { as: { title: "Full-Frame" } } },
    tag: "included",
    status: "published"
  },
  {
    _id: 3,
    name: "Kodak",
    collections: { film: { as: { title: "35mm Film" } } },
    tag: "included",
    status: "published"
  },
  {
    _id: 4,
    name: "Ricoh",
    collections: { cameras: { as: { title: "Full-Frame" } } },
    tag: "included",
    status: "published"
  },
  {
    _id: 5,
    name: "Minolta",
    collections: { cameras: { as: { title: "Half-Frame Review" } } },
    tag: "excluded",
    status: "published"
  },
  {
    _id: 4,
    name: "FED",
    collections: { cameras: { as: { title: "Full-Frame" } } },
    tag: "included",
    status: "draft"
  }
]

【问题讨论】:

    标签: javascript node.js mongodb mongoose nosql


    【解决方案1】:

    您可以尝试的一件事是通过添加 _id 来扩展您的 $sort,以便它始终以确定的顺序返回文档:

    {
        $sort: {
            "collections.cameras.as.title": 1,
            _id: 1
        }
    },
    {
        $limit: 1
    }
    

    一旦您的第一个查询返回带有_id: 2collections.cameras.as.title: Full-Frame 的文档,您可以使用以下查询来获取后续文档:

    {
        $match: {
            $and: [
                {
                    tag: { $ne: "excluded" },
                    "collections.cameras": { $exists: true },
                    status: "published",
                },
                {
                    $or: [
                        { 
                            $and: [
                                { "collections.cameras.as.title": {  $eq: "Full-Frame" } },
                                { "_id": { $gt: 2 } }
                            ]
                        },
                        { "collections.cameras.as.title": {  $gt: "Full-Frame" } }
                    ]
                }
            ]
        }
    },
    {
        $sort: {
            "collections.cameras.as.title": 1,
            _id: 1
        }
    },
    {
        $limit: 1
    }
    

    在这种情况下,由于确定性$sort,您可以通过添加额外的过滤条件来排除以前找到的文档,并且应该保留顺序。

    Mongo Playground

    【讨论】:

      猜你喜欢
      • 2018-03-22
      • 1970-01-01
      • 1970-01-01
      • 2021-11-05
      • 1970-01-01
      • 1970-01-01
      • 2014-08-14
      • 1970-01-01
      • 2013-08-02
      相关资源
      最近更新 更多