我的文档如下所示:
...
propA:[0, 2, 6], //Array of unique numbers of length max. ~50
propB:[2, 14, 24, 39],//Array of unique numbers of length max. ~50
propC:[1, 14, 29], //Array of unique numbers of length max. ~50
...
我希望能够以这样一种方式查询它们:
- 我可以匹配具有特定属性的所有文档
- 我可以匹配所有没有特定属性的文档
例如,现在我使用查询:
mongo.db.collection('things').find({
propA:{$all:[...], $nin:[...]},
propB:{$all:[...], $nin:[...]},
propC:{$all:[...], $nin:[...]},
})
但它的速度非常慢,伸缩性也非常差,因为mongo必须扫描每一份文档。
使mongo查询更快的解决方案是:
- 建立索引
- 更改文档架构
- 两者皆可
问题是我不能.createIndex({propA:1, propB:1, propC: 1})
,因为mongo不接受对多个数组字段进行索引(理由很充分)。
但是当我使用另一个模式时,比如:
...
props:["a0", "a2", "a6", "b2", "b14", "b24", "b39", "c1", "c14", "c29"]
...
然后在{props: 1}
上创建一个索引,以上面相同的方式执行查询,如下所示:
- 第一阶段:IXSCAN,速度快得令人难以置信,但它只选择第一个属性(例如:“a0”)
- 第二阶段:FETCH非常慢,必须扫描通过IXSCAN的所有文档
所以我的问题是:
如何最有效地查询具有数组的文档?
1条答案
按热度按时间k3fezbri1#
我是OP,我想我找到了“最优”的做法:正则表达式
例如,与存储
您的商店
创建索引
.createIndex({"props": "text"})
例如,要搜索包含a1、b5、b7而不包含a3、b4和c8的文档,您可以查询:
想想看,我不知道如何在几毫秒内查询一个拥有数百万文档的集合,但好的一面是它确实是。
只有一个“小”问题:
奇怪的是,如果集合的最大propA是19,而您查询了20个mongo确实扫描了所有文档,而不是使用索引,我猜一个简单的修复方法是在序列之间添加“x999”,但仍然很难看。
例如,您可以储存:
我仍然期待着更好的替代方案,确实,你不能做出像
.createIndex({"location": "2dsphere", "props": "text"})
这样的复合指数。