Rethinkdb 加入过滤器
Rethinkdb join with filter
我正在试验 rethinkdb,我想知道将以下 SQL 查询转换为 ReQL 的最佳方法是什么。
SELECT requests.id, users.name FROM requests JOIN users
ON requests.userid = users.id and users.valid_until IN NULL
基本上我只为用户插入 table,我在行中设置 valid_until 日期,有些东西发生了变化,并在新行中使用更改后的值进行复制。
我想根据 'user' 对象的最新版本获取所有请求的列表以及发出请求的用户的用户名。
我试过了:
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)
但这显然行不通。
谢谢!
我看到您正在使用 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 上每个文档的索引结果,我们必须创建一个新索引。基本上我们试图匹配 if 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,我想知道将以下 SQL 查询转换为 ReQL 的最佳方法是什么。
SELECT requests.id, users.name FROM requests JOIN users
ON requests.userid = users.id and users.valid_until IN NULL
基本上我只为用户插入 table,我在行中设置 valid_until 日期,有些东西发生了变化,并在新行中使用更改后的值进行复制。
我想根据 'user' 对象的最新版本获取所有请求的列表以及发出请求的用户的用户名。
我试过了:
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)
但这显然行不通。
谢谢!
我看到您正在使用 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 上每个文档的索引结果,我们必须创建一个新索引。基本上我们试图匹配 if 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)!