将某种行号添加到mongodb聚合命令/管道中

ic3*_*ic3 4 mongodb mongodb-query aggregation-framework

我们的想法是将一种行号返回给mongodb聚合命令/管道.与我们在RDBM中的情况类似.

它应该是唯一的数字,如果它与行/数字完全匹配则不重要.

对于像这样的查询:

  [   { $match: { "author" : { $ne: 1 } }}  , { $limit: 1000000 } ]
Run Code Online (Sandbox Code Playgroud)

回报 :

{ "rownum" : 0, "title" : "The Banquet", "author" : "Dante", "copies" : 2 }
{ "rownum" : 1, "title" : "Divine Comedy", "author" : "Dante", "copies" : 1 }
{ "rownum" : 2, "title" : "Eclogues", "author" : "Dante", "copies" : 2 }
{ "rownum" : 3, "title" : "The Odyssey", "author" : "Homer", "copies" : 10 }
{ "rownum" : 4, "title" : "Iliad", "author" : "Homer", "copies" : 10 }
Run Code Online (Sandbox Code Playgroud)

是否有可能在mongodb中生成这个rownum?

小智 7

不确定大查询中的性能,但这至少是一个选项.

您可以通过分组/推送将结果添加到数组中,然后includeArrayIndex像这样放松:

[
  {$match: {author: {$ne: 1}}},
  {$limit: 10000},
  {$group: {
    _id: 1,
    book: {$push: {title: '$title', author: '$author', copies: '$copies'}}
  }},
  {$unwind: {path: '$book', includeArrayIndex: 'rownum'}},
  {$project: {
    author: '$book.author',
    title: '$book.title',
    copies: '$book.copies',
    rownum: 1
  }}
]
Run Code Online (Sandbox Code Playgroud)

现在,如果您的数据库包含大量记录,并且您打算进行分页,则可以使用$ skip阶段,然后使用$ limit限制10或20或每页显示的任何内容,只需添加$ skip中的数字进入你的rownum,你将得到真正的位置,而不必推动你的所有结果来枚举它们.

  • 这看起来非常低效,但这正是我所需要的并回答了这个问题. (2认同)

Xav*_*hot 6

从 开始Mongo 5,它是新$setWindowFields 聚合运算符及其$documentNumber操作的完美用例:

// { x: "a" }
// { x: "b" }
// { x: "c" }
// { x: "d" }
db.collection.aggregate([
  { $setWindowFields: {
    sortBy: { _id: 1 },
    output: { rowNumber: { $documentNumber: {} } }
  }}
])
// { x: "a", rowNumber: 1 }
// { x: "b", rowNumber: 2 }
// { x: "c", rowNumber: 3 }
// { x: "d", rowNumber: 4 }
Run Code Online (Sandbox Code Playgroud)

$setWindowFields使我们能够在了解先前或后续文档的情况下处理每个文档。这里我们只需要文档在整个集合(或聚合中间结果)中的位置信息,如 提供的$documentNumber

请注意,我们排序是_id因为sortBy参数是必需的,但实际上,由于您不关心行的顺序,因此它可以是您想要的任何内容。