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二级索引,然后使用getAll或between因为使用索引的查询总是更快.您可以解决的一种方法是false,如果表中的所有行都没有位置,那么表中的所有行都会为其位置设置值.然后,您将为位置创建二级索引.最后,您可以getAll根据需要查询表格!
为此,您需要先插入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每次添加一个文件而不进行位置的时间.
现在所有文档都有一个location字段,我们可以创建一个二级索引location.
r.db("mydb").table("mytable")
.indexCreate('location')
Run Code Online (Sandbox Code Playgroud)
请记住,您只需添加{ location: false }和创建索引一次.
getAll现在我们可以使用索引getAll来查询文档location.
r.db("mydb").table("mytable")
.getAll(false, { index: 'location' })
Run Code Online (Sandbox Code Playgroud)
这可能会比上面的查询更快.
使用二级索引(函数)
您还可以将辅助索引创建为函数.基本上,您创建一个函数,然后使用查询该函数的结果getAll.这可能比我之前提出的更简单,更直接.
这里是:
r.db("mydb").table("mytable")
.indexCreate('has_location',
function(x) { return x.hasFields('location');
})
Run Code Online (Sandbox Code Playgroud)
getAll.这里是:
r.db("mydb").table("mytable")
.getAll(false, { index: 'has_location' })
Run Code Online (Sandbox Code Playgroud)