RethinkDB - 查找缺少字段的文档

amb*_*ent 9 query-optimization rethinkdb

我正在尝试编写最优的查询来查找没有特定字段的所有文档.有没有比我下面列出的例子更好的方法呢?

// Get the ids of all documents missing "location"
r.db("mydb").table("mytable").filter({location: null},{default: true}).pluck("id")

// Get a count of all documents missing "location"
r.db("mydb").table("mytable").filter({location: null},{default: true}).count()
Run Code Online (Sandbox Code Playgroud)

现在,这些查询在一个包含~40k文档的表上大约需要300-400ms,这看起来相当慢.此外,在这种特定情况下,"位置"属性包含纬度/经度并具有地理空间索引.

有没有办法实现这个目标?谢谢!

Jor*_*lva 16

一个天真的建议

您可以使用该hasFields方法以及not方法来过滤掉不需要的文档:

r.db("mydb").table("mytable")
  .filter(function (row) {
    return row.hasFields({ location: true }).not()
  })
Run Code Online (Sandbox Code Playgroud)

这可能会或可能不会更快,但值得尝试.

使用二级索引

理想情况下,您需要一种方法来创建location二级索引,然后使用getAllbetween因为使用索引的查询总是更快.您可以解决的一种方法是false,如果表中的所有行都没有位置,那么表中的所有行都会为其位置设置值.然后,您将为位置创建二级索引.最后,您可以getAll根据需要查询表格!

  1. 将位置属性添加到没有位置的所有字段

为此,您需要先插入location: false所有没有位置的行.你可以这样做:

r.db("mydb").table("mytable")
  .filter(function (row) {
    return row.hasFields({ location: true }).not()
  })
  .update({
    location: false
  })
Run Code Online (Sandbox Code Playgroud)

在此之后,你需要找到一个方法来插入location: false每次添加一个文件而不进行位置的时间.

  1. 为表创建二级索引

现在所有文档都有一个location字段,我们可以创建一个二级索引location.

r.db("mydb").table("mytable")
 .indexCreate('location')
Run Code Online (Sandbox Code Playgroud)

请记住,您只需添加{ location: false }和创建索引一次.

  1. 使用 getAll

现在我们可以使用索引getAll来查询文档location.

r.db("mydb").table("mytable")
 .getAll(false, { index: 'location' })
Run Code Online (Sandbox Code Playgroud)

这可能会比上面的查询更快.

使用二级索引(函数)

您还可以将辅助索引创建为函数.基本上,您创建一个函数,然后使用查询该函数的结果getAll.这可能比我之前提出的更简单,更直接.

  1. 创建索引

这里是:

r.db("mydb").table("mytable")
 .indexCreate('has_location', 
   function(x) { return x.hasFields('location'); 
 })
Run Code Online (Sandbox Code Playgroud)
  1. 使用getAll.

这里是:

r.db("mydb").table("mytable")
 .getAll(false, { index: 'has_location' })
Run Code Online (Sandbox Code Playgroud)