【问题标题】:RethinkDB GetNearest and Filter for Multi-IndexRethinkDB GetNearest 和 Filter for Multi-Index
【发布时间】:2015-11-12 01:33:47
【问题描述】:

是否可以查询与一个或多个标签匹配的附近点? 这是我拥有的数据:

r.db("test").table("Member"):

{ "POSTALCODE":  "526494" ,
"lat":  "1.3640" , "lon":  "103.9531" ,
"memberId":  "22b99a77-5f73-4331-a5da-dcdc46a4b4e7" ,
"membertags": ["tag1" ,"tag2" , "tag3" ] ,
"point": { "$reql_type$":  "GEOMETRY" , "coordinates": [103.9531 ,1.364],"type":  "Point"}
} {
"POSTALCODE":  "525842" ,
"lat":  "1.3516" , "lon":  "103.9384" ,
"memberId":  "79844285-7781-4bd4-819e-db54f90b8c8d" ,
"membertags": ["tag2" ,"tag3" ,"tag4" ,"tag5"] ,
"point": {"$reql_type$":  "GEOMETRY" ,"coordinates": [103.9384 ,1.3516] ,"type":  "Point" }
}

正如How do I run a filter on a getNearest() query in RethinkDB? 中强调的那样,我可以使用eq 过滤getNearest

var point = r.point(103.9531,1.364);  
r.db('test')
.table('Member')
.getNearest(point, {index: 'point', unit :'km'})
.filter(function(user) {
   return user('doc')('POSTALCODE').eq('525842') //1 RESULT
   //return user('doc')('membertags').eq('tag2') //EMPTY RESULT
})

但我无法得到rethinkdb with filter and getNearest commands(选项#1)中建议的多索引(例如成员标签)的结果 - 使用.filter({membertags : 'tag2'})

二级索引是使用r.db("test").table("Member").index_create("membertags", multi=True) 创建的。我知道过滤器不支持二级索引,但找不到使用 getNearest 的替代解决方案。

【问题讨论】:

    标签: javascript rethinkdb reql


    【解决方案1】:

    如果你可以牺牲性能来使用filter而不是索引,我们可以这样做:

    var point = r.point(103.9531,1.364);  
    r.db('test')
    .table('Member')
    .getNearest(point, {index: 'point', unit :'km'})
    .filter(function(user) {
      return user('doc')('membertags').contains('tag2')
    })
    

    我们现在使用contains 来过滤membertags 字段包含标签的结果,而不是使用eq

    缺点是filter 不使用索引,所以性能可能不是那么好。

    【讨论】:

    • 谢谢! - 我现在可以使用return user('doc')('membertags').contains(function (tag) {return tag.eq('tag1').or(tag.eq('tag2'));})(代码:pastebin.com/vTjChN0z)将其扩展为与任一标签匹配,但这不适用于.and 条件(即返回匹配> 1 个标签的每条记录)。我错过了什么吗?
    • and 将始终返回 false,因为单个标签一次不能等于两个值。在谓词函数内部,每次都会将数组的一个元素传递给谓词函数。因此您不能将它与and 一起使用。一种检查方法是使用setIntersection,如下所示:filter(function(user) { return user('doc')('membertags').setIntersection(['tag2', 'tag4']).count().eq(2) }) setIntersection 返回值出现在两个数组中,然后计算结果数组的大小
    猜你喜欢
    • 2015-06-26
    • 2021-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-11
    • 1970-01-01
    • 2018-10-01
    • 1970-01-01
    相关资源
    最近更新 更多