公式のpythonドライバーでRethinkdb 1.10.1を使用しています。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)
MemoryError
これにより、インデックス関数を解析しようとしてPythonドライバーがチョークします(リスト内包表記はドライバーで実際にはサポートされていないと思います)。
だから、私は(確かに、さびた)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.
では、複合マルチインデックスを定義する正しい方法は何ですか? それとも、現時点ではサポートされていないものですか?