Rethinkdb与过滤器连接

时间:2016-04-06 21:38:18

标签: rethinkdb

我正在尝试使用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)

但它显然不起作用。

谢谢!

1 个答案:

答案 0 :(得分:0)

我看到你正在使用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({找到我@dalanmiller)的slack.rethinkdb.com提问!