【问题标题】:Rethinkdb join with filterRethinkdb 加入过滤器
【发布时间】:2016-04-08 02:47:18
【问题描述】:

我正在尝试使用 rethinkdb,我想知道将以下 SQL 查询转换为 ReQL 的最佳方法是什么。

SELECT requests.id, users.name FROM requests JOIN users 
    ON requests.userid = users.id and users.valid_until IN NULL

基本上,我有一个只供用户使用的表,我在其中设置了行上的 valid_until 日期,有些地方发生了变化,并在新行中使用更改后的值进行了复制。

我想根据“用户”对象的最新版本获取所有请求的列表以及发出请求的用户的用户名。

我试过了:

r.table('requests').eq_join(
   r.row['webob_adhoc_attrs']['id'],
   r.table('users')
    .filter(lambda user: not user.has_fields('valid_until')), 
   index='id').run(conn)

但显然它不起作用。

谢谢!

【问题讨论】:

    标签: rethinkdb


    【解决方案1】:

    我看到您使用的是 Python 的 not,但您应该在 ReQL 查询的开头使用 ~ 或在结尾使用 .not_()。

    https://rethinkdb.com/api/python/not/

    我自己没有遇到的问题是,由于eq_join 语句中的重叠索引使用冲突,无法在eq_join 中执行过滤器。这些选项中的任何一个都应该起作用:

    选项 1 - 之后执行过滤器:

    r.table('requests').eq_join(
        r.row['webob_adhoc_attrs']['id'],
        r.table("users")
      )\
      .filter(lambda row: ~row.has_fields('valid_until')\
      .run(conn)
    

    选项 2 - 之前执行过滤器:

    由于eq_join 的第一个参数试图匹配第二个表上每个文档的索引结果,我们必须创建一个新索引。基本上我们正在尝试匹配table('users')['id'] == document in the index for table('requests)

    # Create index first because of the embedded id field
    r.table('requests').index_create('requests_id', r.row['webob_adhoc_attrs']['id'])
    # Then can properly join on filtered
    r.table('users').filter(\
        lambda row: ~row.has_fields('valid_until'))\
        .eq_join( 
          r.row['id'],
          r.table('requests'),
          index = 'requests_id'
        )
    

    然后更进一步,.filter 不能使用索引。但是,您可以将.get_all 与索引一起使用以使其更快。

    r.table("requests")\
       .index_create('not_has_valid_until', ~r.row.has_fields('valid_until'))
    
    r.table("requests")\
       .get_all(r.expr(True), index='not_has_valid_until')\
       .eq_join( 
         r.row['id'],
         r.table('requests'),
         index = 'requests_id'
       )
    

    我在本地测试了这个更精细的部分,但显然没有你相同的数据集。选项 1 非常简洁易读,但我估计您在使用选项 2 的大型数据集上会获得更好的性能,在我的小型测试数据集上,使用 RethinkDB 2.3 的结果几乎相同。

    希望能为您解决问题!如果您需要更详细的帮助,请在#help 中的slack.rethinkdb.com 提问(并找到我@dalanmiller)!

    【讨论】:

    • 谢谢!我试过了,但我现在得到 rethinkdb.errors.ReqlServerCompileError: Cannot use r.row in nested queries。使用函数代替: r.table('requests').eq_join(lambda var_2: r.row['webob_adhoc_attrs']['userid'], lambda var_3: r.table('users').filter(lambda var_1: (~r.row.has_fields('valid_until'))), index='uuid')
    • 再次感谢。很抱歉一直打扰你。现在我得到了与我的版本相同的错误:“rethinkdb.errors.ReqlQueryLogicError: Expected type TABLE but found SELECTION:”。加入期间是否可能不支持过滤器?
    • 咨询了 RethinkDB 首席工程师,并对此进行了更多测试。让我知道其中一项是否适合您!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多