1

我有一个文档集合,我需要首先按设定的条件缩小范围,然后按这些文档中的字符串值按字母顺序排序——假设这是一个“搜索结果”。然后我需要找到与给定文件匹配的文档,_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)每次运行查询时都重建集合,但感觉它会缺乏性能。

请帮忙,谢谢!

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

[
  {
    _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"
  }
]
4

1 回答 1

1

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

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

一旦您的第一个查询返回带有_id: 2and的文档collections.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,您可以通过添加额外的过滤条件来排除以前找到的文档,并且应该保留顺序。

蒙戈游乐场

于 2021-09-30T09:40:10.110 回答