我在下面一个名为numbers
的空RethinkDB表中有文档,其中包含嵌套对象。我在内部对象内的一对数字上创建了一个二级索引,一个复合索引和一个多索引。复合是因为我想使用2-元素数组作为辅助索引,而multi是因为同一个2-元素数组可能对应于多个文档。
在这里,我创建了辅助索引,并在Data Explorer浏览器视图中插入一些文档:
r.db('test')
.table('numbers')
.indexCreate('idx', [ r.row('group')('a'), r.row('group')('b') ],
{multi : true});
r.db('test').table('numbers').insert([
{name : 'Foo', group : {a : 2, b : 3}},
{name : 'Bar', group : {a : 2, b : 9}},
{name : 'Baz', group : {a : 2, b : 3}},
{name : 'Qwer', group : {a : 4, b : 4}}
]);
现在我将使用between
运行一个查询。对于这个例子,我希望看到三个文档返回,但我没有返回任何文档:
r.db('test').table('numbers').between([ 2, 0 ], [ 3, 5 ], {index : 'idx'});
// No results returned.
困惑的是,我只用标量查找测试了这个辅助索引(所以假装idx
不是复合索引):它返回文档!
r.db('test').table('numbers').between(2, 3, {index : 'idx'})
// 3 rows returned: Foo, Bar, Baz
什么?为什么要将idx
辅助数组视为标量索引(而不是数组)并返回三个文档?我的复合指数怎么了?
将rightBound
设置为closed
似乎没有任何作用。此外,使用函数构建索引键,即将function(obj) {return [obj('group')('a'), obj('group')('b')];}
传递给indexCreate
并没有产生差异。
我测试了另一个键为[string,number,number]的复合多索引,between
非常适合这种多情况:它可以查找文档。为什么两个数字的多案例在这里不起作用?
我认为这里的主要问题是不需要多索引。
了解多索引
multi,因为同一个2-pair可能对应于多个文档
对于任何辅助索引,索引都假定该属性的值(在本例中为值对)对应于多个文档。在RethinkDB中,因为它是一个分布式数据库,所以只能保证主索引的值是唯一的。
多索引适用于您想要其中一个值的值数组。标签就是一个例子:
{
"title": "...",
"content": "...",
"tags": [ <tag1>, <tag2>, ... ]
}
// Create the multi index based on the field tags
r.table("posts").indexCreate("tags", { multi: true })
// Your query
r.table("posts").getAll(<tag1>, { index: "tags" })
您的查询
因此,您可以创建相同的复合索引,而不必将其作为多索引。
r.db('test')
.table('numbers')
.indexCreate('idx', [ r.row('group')('a'), r.row('group')('b') ]);
然后您的查询将按预期返回:
r.db('test').table('numbers').between([ 2, 0 ], [ 3, 5 ], {index : 'idx'});
退货:
{
"group": {
"a": 2 ,
"b": 3
} ,
"id": "f711dae4-7e91-4864-9977-956221a10a08" ,
"name": "Foo"
}, {
"group": {
"a": 2 ,
"b": 3
} ,
"id": "29732f5f-a6e6-45e6-aaaf-fd2c9d1bb3fe" ,
"name": "Baz"
}, {
"group": {
"a": 2 ,
"b": 9
} ,
"id": "1881eafb-4349-43c8-9fb2-d453720b09a6" ,
"name": "Bar"
}