Rethinkdb 如何在数据库中创建复合多索引?

Rethinkdb 如何在数据库中创建复合多索引?,rethinkdb,rethinkdb-python,Rethinkdb,Rethinkdb Python,我在官方python驱动程序中使用的是RejectionDB1.10.1。我有一个与一个用户关联的标记内容表: { "id": "PK", "user_id": "USER_PK", "tags": ["list", "of", "strings"], // Other fields... } 我想通过user\u id和tag进行查询(比如,通过用户“tawmas”和标记“tag”查找所有内容)。从DB 1.10开始,我可以创建如下多索引: r.table('

我在官方python驱动程序中使用的是RejectionDB1.10.1。我有一个与一个用户关联的标记内容表:

{
    "id": "PK",
    "user_id": "USER_PK",
    "tags": ["list", "of", "strings"],
    // Other fields...
}
我想通过
user\u id
tag
进行查询(比如,通过用户“tawmas”和标记“tag”查找所有内容)。从DB 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\u 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)
r.table('things')。创建索引(
“用户标签”,
r、 js(
“(每个功能){
var结果=[];
var user_id=每个[“user_id”];
var标记=每个[“标记”];
对于(var i=0;i
服务器拒绝了此操作,但出现了一个奇怪的异常:
referencedb.errors.RqlRuntimeError:无法证明函数是确定性的。索引函数必须是确定性的。

那么,定义复合多索引的正确方法是什么?还是什么 目前不支持哪一项?

简短回答:

列表理解在ReQL函数中不起作用。您需要像这样使用
map

r.table('things').index_create(
    'user_tags',
    lambda each: each["tags"].map(lambda tag: [each['user_id'], tag]),
    multi=True).run(conn)

长话短说

这实际上是DB驱动程序如何工作的一个微妙方面。所以这不起作用的原因是python代码实际上并没有看到每个文档的真实副本。因此,在表达式中:

lambda each: [[each['user_id'], tag] for tag in each['tags']]
每个
都不会绑定到数据库中的实际文档,而是绑定到一个表示文档的特殊python变量。实际上,我会尝试运行以下内容来演示:

q = r.table('things').index_create(
       'user_tags',
       lambda each: print(each)) #only works in python 3
它将打印出如下内容:

<RqlQuery instance: var_1 >


驱动程序只知道这是函数中的一个变量,特别是它不知道
每个[“tags”]
是一个数组还是什么(它实际上只是另一个非常类似的抽象对象)。所以python不知道如何迭代该字段。javascript中基本上存在相同的问题。

非常感谢!我完全忽略了文档中的映射功能。在重新思考python驱动程序的最新版本中,当我运行此程序时,会收到一条错误消息,解释我做错了什么。你可能已经安装了旧版本的驱动程序吗?我已经安装了1.10.0-0版,我上周安装了。PyPI上似乎没有发布更新的版本。你指的是开发版本吗?