0

我有以下结构:

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>, ...)

但我不知道在查询之间有很多的大表中开销是多少。

4

1 回答 1

1

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

在此查询中:

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

看来您在这里想要的是:所有具有AND 父级'parent1''tag1'AND'tag2'以及 BETWEEN0和时间戳的文档<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查询的结果超过几千,那么您可能会遇到问题,但如果不是,我不会担心。如果是,那么也许您可以用更多关于您的数据(存在多少不同的父级、标签、时间戳)以及使单个文档独一无二的原因来更新您的问题。

于 2015-10-03T19:03:16.523 回答