2

有没有办法只在 MongoDB 中的部分字段上创建索引,例如前 10 个字符?我找不到它的记录(或在这里询问)。

MySQL 的等价物是CREATE INDEX part_of_name ON customer (name(10));.

原因:我有一个包含单个字段的集合,长度从几个字符到 1000 多个字符不等,平均 50 个字符。由于有大约一亿个文档,因此很难将完整的索引放在内存中(根据统计数据,用 8% 的数据进行测试,索引已经是 400MB)。仅对字段的第一部分进行索引将使索引大小减少约 75%。在大多数情况下,搜索词很短,它不是全文搜索。

一种解决方法是为每个项目添加 10 个(小写)字符的第二个字段,对其进行索引,然后如果搜索词超过 10 个字符,则添加逻辑以过滤结果(并且可能无论如何都需要额外的字段以用于案例- 不敏感的搜索,除非有人有更好的方法)。不过,这似乎是一种丑陋的方式。

[稍后添加]

我尝试添加第二个字段,其中包含主字段的前 12 个字符,小写。这不是一个很大的成功。

以前,平均对象大小为 50 字节,但我忘了包括 _id 和其他开销,所以我的主要字段长度(只有一个)平均接近 30 字节而不是 50。然后,第二个字段索引包含 _id 和其他开销。

最终结果(对于我的 8% 样本)是主字段上的索引是 415MB,而 12 字节字段上的索引是 330MB - 只节省了 20% 的空间,不值得。我可以复制整个字段(以解决不区分大小写的搜索问题),但实际上我应该重新考虑 MongoDB 是否是适合这项工作的工具(或者只是购买更多内存并使用两倍的磁盘空间)。

[更晚添加]

这是一个典型的文档,包含源字段和简短的小写字段:

{ "_id" : ObjectId("505d0e89f56588f20f000041"), "q" : "Continental Airlines", "f" : "continental " }

索引:

db.test.ensureIndex({q:1});

db.test.ensureIndex({f:1});

在较短的字段上工作的“f”索引是“q”索引大小的 80%。我并不是要暗示我在索引中包含了 _id,只是它需要在某个地方使用它来显示索引将指向的位置,因此这是一种开销,可能有助于解释为什么较短的键几乎没有什么区别。

对索引的访问基本上是随机的,没有任何部分比其他任何部分更可能被访问。完整文件的总索引大小可能为 5GB,因此对于该索引来说并不是极端的。为其他搜索案例添加一些其他字段,以及它们的相关索引,以及小写的数据副本,确实开始加起来,并使分页和交换更有可能(它是一个 8GB 服务器),这就是我开始研究更多简洁的索引。

4

1 回答 1

2

MongoDB 无法在字段值的一部分上创建索引。正如您所建议的,您最好的方法是创建第二个字段。

由于无论如何您都需要第二个字段来进行有效的不区分大小写的搜索,因此没有理由不创建它。

索引不存储文档的“_id”字段,它们存储一个 DiscLoc 结构,这是一个低级得多的结构:有关详细信息,请参阅此处

另外,请注意,“丑”实际上是“关系思维”的产物。(作为一个长期使用 SQL 的我自己,我经常发现学习 MongoDB 最难的部分是学习我的关系思维。)在面向文档的数据库中,非规范化和复制数据实际上是最佳实践。

于 2012-09-22T01:03:36.543 回答