rethinkdb:如何对两个属性进行排序并在其中之一之间使用

时间:2018-07-25 20:37:05

标签: node.js database rethinkdb rethinkdb-javascript reql

我们有一个带有门票的rethinkdb。它们具有一个createdAt,带有一个以毫秒为单位的时间戳和一个priority属性。

例如

{
  createdAt: 12345,
  priority: 4,
  owner: "Bob",
  description: "test",
  status: "new"
}

rethinkdb.db('dev').table(tableId)
        .orderBy({index: 'createdAt'})
        .between(timeFrom,timeTo)
        .filter(filter)
        .skip(paginator).limit(20).run(this.connection);

我们现在有以下问题。我们想要一个执行两个ord​​erBy ...的查询,第一个将是orderBy“ priority”,也可以是“ createdAt”。因此,在给定过滤器和时间跨度的情况下,它应该返回优先级最高的票证,而优先级最高的票证应该排在最前面。

我们尝试构建具有优先级和createdAt的复合索引。那确实有效,但是.between之间的作用不符合该索引的预期。

rethinkdb.db('dev').table('tickets').indexCreate('prioAndCreatedAt' [rethinkdb.row('priority'), rethinkdb.row('createdAt')]).run(this.connection)

与查询:

rethinkdb.db('dev').table(tableId)
        .orderBy({index: 'prioAndCreatedAt'})
        .between([rethinkdb.minval, timeFrom],[rethinkdb.maxval , timeTo])
        .filter(filter)
        .skip(paginator).limit(20).run(this.connection);

在我们的思维中,应该先按优先级排序,然后再按createdAt并使用.between进行排序,我们将忽略优先级(因为.minval和.maxval),而只是获取timeFrom和timeTo之间的所有票据。 >

Buuuut还返回了createdAt小于timeFrom的票证。因此,这并不像我们计划的那样有效。 就像这样的“问题”:RethinkDB Compound Index Weirdness Using Between

但是我们无法找到另一种方式。

2 个答案:

答案 0 :(得分:0)

因为

  

它应该返回优先级最高的票证,并且优先级最高的票证应该排在最前面

是否有理由不简单使用2 orderBy

r.db('dev').table('tickets')
  .between(timeFrom, timeTo, {index: 'createdAt'})
  .orderBy('createdAt')
  .orderBy(r.desc('priority'))

然后,您可以在此选择上使用过滤器/分页器。它将提供正确范围内的票证,票证的优先级由 then 降序排列,由创建日期的升序排列(SQL考虑ORDER BY priority, createdAt的方式)。而且它避免了between具有复合索引的(documented)行为。

答案 1 :(得分:0)

我认为只有当createdAt也是主键时,您的查询才应该起作用。是吗?否则,您可以在createdAt字段上创建一个附加索引,并在您的between语句中使用它:

r.db('dev').table('tickets').indexCreate('createdAt', r.row('createdAt'))

r.db...
.between([rethinkdb.minval, timeFrom],[rethinkdb.maxval , timeTo], {index:"createdAt"})

您还可以按照@Stock Overflaw的说明使用多个orderby,但是只有将两个条件都放在一个orderBy语句中,它才能正确运行:

r.db('dev').table('tickets')
  .between(timeFrom, timeTo, {index: 'createdAt'})
  .orderBy(r.asc('createdAt'), r.asc('priority'))

请记住,由于它不使用索引,因此性能较低。