我正在使用带有官方 python 驱动程序的 Rethinkdb 1.10.1。我有一个与一个用户关联的标记事物表:
{
"id": "PK",
"user_id": "USER_PK",
"tags": ["list", "of", "strings"],
// Other fields...
}
我想通过user_id
and查询tag
(例如,通过用户“tawmas”查找所有带有标签“tag”的东西)。从 Rethinkdb 1.10 开始,我可以像这样创建一个多索引:
r.table('things').index_create('tags', multi=True).run(conn)
我的查询将是:
res = (r.table('things')
.get_all('TAG', index='tags')
.filter(r.row['user_id'] == 'USER_PK').run(conn))
但是,这个查询仍然需要扫描所有带有给定标签的文档,所以我想创建一个基于 user_id 和 tags 字段的复合索引。这样的索引将允许我查询:
res = r.table('things').get_all(['USER_PK', 'TAG'], index='user_tags').run(conn)
文档中没有关于复合多索引的内容。但是,我尝试使用自定义索引函数,通过返回对列表来结合复合索引和多索引的要求["USER_PK", "tag"]
。
我的第一次尝试是在 python 中:
r.table('things').index_create(
'user_tags',
lambda each: [[each['user_id'], tag] for tag in each['tags']],
multi=True).run(conn)
这使得 python 驱动程序因MemoryError
试图解析索引函数而窒息(我猜驱动程序并不真正支持列表推导)。
所以,我转向我的(诚然,生锈的)javascript并想出了这个:
r.table('things').index_create(
'user_tags',
r.js(
"""(function (each) {
var result = [];
var user_id = each["user_id"];
var tags = each["tags"];
for (var i = 0; i < tags.length; i++) {
result.push([user_id, tags[i]]);
}
return result;
})
"""),
multi=True).run(conn)
这被服务器拒绝了一个奇怪的例外:rethinkdb.errors.RqlRuntimeError: Could not prove function deterministic. Index functions must be deterministic.
那么,定义复合多索引的正确方法是什么?还是目前不支持的东西?