rethinkdb with filter和getNearest命令

dlo*_*odu 3 nearest-neighbor rethinkdb

如何执行getNearest查询其他命令的结果,例如过滤命令?

var point = r.point(-122.422876,37.777128);  
r.db('test').table('users').
   filter({tags : 'tag'}).
   getNearest(point, {index: 'geodata', maxResults: 30, unit :'km'})
Run Code Online (Sandbox Code Playgroud)

我有一个'用户'表:

 [ 
   {id: 1, tags : ['music', 'cups'], geodata: r.point()} 
   {id: 2, tags: ['music', 'play'], geodata: r.point()} 
 ] 
Run Code Online (Sandbox Code Playgroud)

首先,我想通过'tags'字段过滤,然后返回最近的字段.

我指定的查询不正确,返回以下错误:" RqlRuntimeError:预期类型TABLE但找到SELECTION "

Jor*_*lva 5

您的查询抛出错误的原因是因为.getNearest只适用于表.这就是文档所说的.

选项1

您可以通过反转命令的顺序来解决您的问题:

var point = r.point(-122.422876,37.777128);  
r.db('test')
 .table('users')
 .getNearest(point, {index: 'geodata', maxResults: 30, unit :'km'})
 .filter({tags : 'tag'})
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为.getNearest返回一个数组并.filter可以在数组上工作.

var point = r.point(-122.422876,37.777128);  
r.db('test')
 .table('users')
 .getNearest(point, {index: 'geodata', unit :'km'})
 .filter({tags : 'tag'})
 .limit(30)
Run Code Online (Sandbox Code Playgroud)

这种方法的问题在于,为了保证所有可能的结果都存在,您不能将maxResults选项传递给getNearest,这意味着将查询每个行然后进行过滤.

此方案最适用于大多数项目将通过筛选器的情况.

根据您的数据,还可以编写一个maxResults递增的函数,直到它获得所需的所有结果,但这可能很复杂而且不是很优雅.

选项2

如果过滤器将过滤掉大部分结果,那么您可以使用getAll(创建tags索引)getAll过滤结果并首先过滤结果,然后根据距离对结果进行排序:

var point = r.point(-122.422876,37.777128);
r.table('users')
 .getAll('tag', {index: 'tags'})
 .orderBy(r.row('geodata')
 .distance(point))
 .limit(30)
Run Code Online (Sandbox Code Playgroud)

数据类型

您可以随时使用该.typeOf方法获取任何内容的类型.

例:

r.db('test')
 .table('users').typeOf() // "TABLE"

r.db('test')
 .table('users')
 .filter({tags : 'tag'}).typeOf() // "STREAM"
Run Code Online (Sandbox Code Playgroud)

如果您想了解有关ReQL数据类型的更多信息,可以查看我撰写的这篇博文,其中介绍了ReQL数据类型及其不同之处.