具有多个键的 Rethinkdb

Rethinkdb between with multiple keys

我有以下结构:

Item {
  id string,
  title string
  tags []string,
  time int,
  parent string
}

我想要的,list all items with tags [tag1, tag2, ... etc] of parent "parent-1" and order by time

所以我这样做了

r.db("db").table("tb").indexCreate("allByTime", function(row){
  return row("tags").map(function(tag){
    return [row("parent"), tag, row("time")]
  })
})

它适用于这样的查询

r.db("db").table("tb").between(["parent-1", "tag1", 0], ["parent-1", "tag1", <some-bigger-timestamp>], {index: "allByTime"}).orderBy(...)

但我也想要这样的东西

r.db("db").table("tb").between(["parent-1", ["tag1", "tag2"], 0], ["parent-1", ["tag1", "tag2"], <some-bigger-timestamp>], {index: "allByTime"}).orderBy(...)

有什么建议吗?

注意 -> 我不想使用 r.filter(...)

我试过这样的东西

r.union(<between-query-1>, <between-query-2>, ...)

但我不知道在查询之间有很多开销 table。

老实说,我不认为你想要的真的是可能的。如果你考虑一下,你想要的是一个复合索引,里面有一个多索引,我认为在 RethinkDB 中没有任何方法可以表达它。

在此查询中:

r.db("db").table("tb")
 .between(
    ["parent-1", ["tag1", "tag2"], 0], 
    ["parent-1", ["tag1", "tag2"], <some-bigger-timestamp>], 
    {index: "allByTime"}
  )
  .orderBy(...)

看来您想要的是:所有 parent 为 'parent1' 并且 'tag1''tag2' 的时间戳介于 0 之间的所有文档] 和 <some-bigger-timestamp>。看来,如果是这种情况,那么 union 就不会真正起作用,因为您不能通过多个值查询字段。

我建议的解决方案:只需使用 filter!

在您之前的查询中:

r.db("db").table("tb")
 .between(
   ["parent-1", "tag1", 0], 
   ["parent-1", "tag1", <some-bigger-timestamp>], 
   {index: "allByTime"}
 )
 .orderBy(...)

您可能正在将数据缩小到可以使用 filter 的数据部分。我认为 filter 的意义在于你永远不应该使用它。 filter 的要点是在(使用大型数据集)您已经巧妙地使用了索引(您拥有)时巧妙地使用它。如果 between 查询的结果超过几千,那么你可能会有问题,但如果不是,我不会担心。如果是,那么也许您可以使用更多关于您的数据(有多少不同的 parent 、标签、时间戳)以及使单个文档独一无二的内容来更新您的问题。