2015-02-11 62 views
0

可以说,我有一个用户集合,其中一个文件看起来像这样索引策略应该支持哪些查询是不同字段的组合?

{ “名”: “星爵”, “时代”:24, “性别”: “男”, “高度“:180, ‘重’:230, ‘爱好’:‘飞飞船’ }

现在,我希望有人能够基于一个或多个域的搜索用户。所以我按照上面的顺序添加一个包含所有这些字段的复合索引。

问题是,当查询字段是索引字段的前缀时,MongoDB索引工作效果很好。例如,如果我通过name,agegender查询,则查询的性能很好。如果我通过name,genderweight进行查询,那么查询的性能不是很好(尽管它仍然使用索引并且比无索引更快)。

当你有这样的用例时,你使用了什么索引策略?

+0

您是否能够解决有关索引策略的问题? – 2015-02-26 23:22:01

+0

我意识到,MongoDB不是这个用例的正确工具,并决定使用Elasticsearch – 2015-02-27 07:08:43

+1

好的。是的,ElasticSearch非常棒。我很高兴你能解决你所面临的问题。 – 2015-02-27 11:57:59

回答

0

如果您需要能够查询所有组合,则索引数量需要快速爆炸。该救援功能称为"index intersection"

在每个字段上创建一个简单的索引并相信查询优化器执行正确的索引交集。这个功能相对比较新(从2.6开始),而不像已知的RBDMSses那样功能完整。跟踪Jira Ticket for index intersections以了解限制是有意义的,因为限制非常严重。仔细混合简单索引(可以相交)和复合索引(用于非常常见的查询)通常是有意义的。

在您的具体情况下,您可以利用许多字段为数字并且有效值范围非常有限(例如年龄,身高和体重)的事实。 gender字段具有较低的选择性,不应在任何情况下进行索引。在最后一步中过滤性别,因为它平均只会使必须处理的数据量增加一倍。

创建n!复合索引几乎肯定不会n > 3一个选项...

+0

不幸的是,索引交集只适用于MongoDB 2.6中的两个索引的交集。所以,如果我为他们每个人都有单独的索引,并且我的查询包含字段'name'和'age',那么它就可以工作。但是,如果它包含“名称”,“年龄”和“性别” - 它将不起作用。 – 2015-02-11 09:16:27

+0

是的。我稍微更新了答案。最后,目前还没有解决这个问题的万能解决方案。 – mnemosyn 2015-02-11 09:19:38

1

之所以查询由nameagegender的伟大工程,同时通过namegenderweight查询不会是因为对于MongoDB中的复合索引,这些字段的顺序非常重要,特别是索引的前缀。如文档中的this page所述,复合索引可以支持对其字段的任何前缀进行查询。因此,假设您按照您提供的字段顺序创建索引,name,agegender的查询是您的化合物索引的前缀,而namegenderweight只能利用索引的name部分。

支持在这些字段上查询的所有可能的组合将需要您创建足够的复合索引,以便所有可能的查询都是索引的前缀。我会说这不是你想要做的事情。由于您的问题是针对具有多个字段的查询编制索引策略,因此我建议您查看对您的数据集最有用的特定数据访问模式,并创建一些支持这些模式的复合索引,以利用前缀概念和从索引中省略某些低基数的字段,如gender