我们有一个带有门票的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);
我们现在有以下问题。我们想要一个执行两个orderBy ...的查询,第一个将是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
但是我们无法找到另一种方式。
答案 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'))
请记住,由于它不使用索引,因此性能较低。