索引MongoDB中的多个数组



我有这样的文档:

...
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的所有文档

我的问题是:

如何最有效地查询数组文档?

我是OP,我想我找到了最佳的"方法:regex

例如,不存储

propA:[0, 2, 6],
propB:[2, 14, 24, 39],
propC:[1, 14, 29], 

存储

props: "a0a2a6b2b14b24b39c1c14c29" //a string, really

创建索引.createIndex({"props": "text"})

例如,要搜索包含a1, b5, b7而不包含a3, b4和c8的文档,您可以查询:

mongo.db.collection('things').find({
props: {
$regex: /.*a1.*^a3.*^b4.*b5.*b7.*c8/
}
})

考虑到它,我不知道如何在几毫秒内查询具有数百万个文档的集合,但好的事情是它是。

只有一个"small"问题:

  • 查询高于所有文档的属性。

奇怪的是,如果集合的最大propA是19,而您查询20 mongo确实扫描所有文档而不是使用索引,我想一个简单的修复方法是添加"x999"在系列之间,但仍然很丑。

例如,存储:

props: "a0a2a6a999b2b14b24b39b999c1c14c29c999" //another string

我仍然期待更好的选择,的确,你不能像.createIndex({"location": "2dsphere", "props": "text"})那样做一个复合指数。

最新更新