【问题标题】:How to implement Cursor based pagination for mongodb in node.js using official mongodb client when _id is overrided?当_id被覆盖时,如何使用官方mongodb客户端在node.js中为mongodb实现基于游标的分页?
【发布时间】:2019-12-12 19:15:21
【问题描述】:

我想在node.js 环境中使用offical mongodb packagemongodb 实现分页。

我有 mongodb 集合,其行类似于
db.registrations.findOne()

{ "_id" : {"mtid" : 156568417304061, "uid" : 156568728002501}, "tid" : 2 }  

这里_id 不是 ObjectId() 的实例,也不是数字。如何在此集合上实现基于光标的分页?我会避免offset-basedtime-based 分页。
我很想使用https://stackoverflow.com/a/58411020/1762051 中给出的想法,但我想这不适合我的情况,因为_id 不是数字。

【问题讨论】:

标签: node.js mongodb pagination


【解决方案1】:

我不认为你有太多事情要做。

默认情况下,您在_id 上有一个索引,根据mongodoc,您索引的字段可以是整个嵌入文档,其(子)字段 order 很重要。

{mtid, uid} 是您的嵌入式文档,只要您以相同的(子)字段顺序查询就可以了。

然后您只需按_id 排序。

生成一些数据:

arr = Array(25).fill(0).map((x,i)=>i).sort(x=>Math.random()-0.5).map(x=>[(x-x%5)/5,x%5])
arr.forEach(([mtid, uid],i)=>db.dums.insert({_id:{mtid, uid},n:i}))

就我而言:

{ "_id" : { "mtid" : 2, "uid" : 4 }, "n" : 0 }
{ "_id" : { "mtid" : 2, "uid" : 2 }, "n" : 1 }
{ "_id" : { "mtid" : 0, "uid" : 1 }, "n" : 2 }
{ "_id" : { "mtid" : 0, "uid" : 0 }, "n" : 3 }
{ "_id" : { "mtid" : 0, "uid" : 2 }, "n" : 4 }
{ "_id" : { "mtid" : 2, "uid" : 3 }, "n" : 5 }
{ "_id" : { "mtid" : 3, "uid" : 1 }, "n" : 6 }
...

考虑下面的查询

function query(str){
  let [mtid, uid] = str.split('_')
  mtid = parseInt(mtid)
  uid = parseInt(uid)

  const res = db.dums.find({
    _id: {
      $gt: { mtid, uid }
    }
  }).limit(2).sort({ _id: 1 }).toArray()

  if(!res.length) return {items:[], next:null}
  const last = res[res.length-1]._id
  const next = last.mtid + '_' + last.uid
  print(res.map(x=>x._id.mtid+'_'+x._id.uid).join(';'))
  return {
    items: res,
    next,
    goNext(){return query(next)}
  }
}

结果:

> var a=query('0_0');
0_1;0_2
> var a=a.goNext();
0_3;0_4
> var a=a.goNext();
1_0;1_1
> var a=a.goNext();
1_2;1_3
> var a=a.goNext();
1_4;2_0
> var a=a.goNext();
2_1;2_2

我们可以观察到项目确实是按mtid、uid排序的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-12
    • 2020-06-30
    • 1970-01-01
    • 2011-10-30
    • 2018-08-20
    • 2015-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多