如何选择然后对 MongoDB 文档进行排序,然后找到下一个要挖掘的文档?

Posted

技术标签:

【中文标题】如何选择然后对 MongoDB 文档进行排序,然后找到下一个要挖掘的文档?【英文标题】:How do I pick then sort MongoDB documents and then find next document to mine? 【发布时间】: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"
  
]

【问题讨论】:

【参考方案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

【讨论】:

以上是关于如何选择然后对 MongoDB 文档进行排序,然后找到下一个要挖掘的文档?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 MongoDB 中搜索动态字段并首先对最佳匹配结果进行排序

MongoDB:使用 $or 运算符按条件顺序查询时如何对文档进行排序?

Mongodb $near 二级排序顺序

如何在mongodb中高效分页[重复]

如何对 mongoose/mongodb 和 nodejs 中的对象数组进行排序?

MongoDB:对文档集进行设置操作,如何操作?