2011-12-19 61 views
0

我有一个蒙戈集合,其中每个文件都有一套独特的嵌入式按键:蒙戈DB:优化独特的嵌入式密钥基于查询

{ 
    Facebook : 
    { 
     Archived:'False' //non unique 
     'fan_count_December_19_2011':12345, //unique 
     'unique_views_count_December_19_2011':12345, //unique 
     'post_count_December_19_2011':12345, //unique 
     ... 
     ... 
    } 
} 

我们查找这些文件,用下面的查询:

db.metrics.find({ 
    {'Facebook.fan_count_December_19_2011' : {'$ne':null}},'Archived':'False'} 
} 
).limit(1) 

问题是,有6000个这样的文件,它有点慢。看看Explain()日志;每个查询平均需要0.06秒才能执行,并且每次执行完整的集合扫描。 我们的服务必须做100次以上的查询(对于100个不同的密钥);在0.06 p/s的速度下,每次通话最多可以达到6秒(不包括提供数据的站点的开销)。 在一个批处理中发送所有的密钥,并执行一个大的查询将需要重写数据层;由于时间紧迫,我试图避免这种情况。 我一直在查看文档,并且似乎没有办法获得基于关键字的索引。该文件说你可以在嵌入式密钥上索引;但这似乎只是指数值。这对我也没什么好处。因为系统中的每个密钥都是唯一的;每个新密钥都必须有一个索引。

短期重新设计我们的文档结构的(这需要一个大的变化);无论如何,我能做些什么来加速对当前格式的现有集合的查询?

任何建设性输入不胜感激。

感谢, 弗兰克

+1

为什么特定日期的粉丝数量是唯一的?不能有两个具有相同日期的粉丝数量的收集项目吗?或者你想*键*是唯一的,而不是值? – mnemosyn 2011-12-19 21:21:40

+0

这些键必须是唯一的,因为它们是我们用来查找给定日期的指标的。我们正在从一个网站上获取这些数据,这些数据可以反映一个月内facebook粉丝的增长情况,我们需要日常的历史记录才能做到这一点。 – 2011-12-19 22:32:13

+0

当你说键时,你是指字段名称还是字段值?我不确定我现在明白这一点... – Iain 2011-12-20 00:33:57

回答

1

假设你已存档的字段设置为true你处理的文档后,你可以对刚才的存档字段创建索引。

通常情况下,您不会在基数较低的字段上创建索引,但在这种情况下它可能适用于您,但只能假设没有很多归档字段为false的文档。

从长远来看,你应该重新设计你的文档,所以你没有这么多独特的字段名称(沿着Iain建议的“Facebook.date”字段)。这样你就可以创建一个索引。

0

这是一个猜测,但我怀疑它做,因为无论是范围扫描:

  1. 您还没有指定的字段上的索引,或
  2. 你正在做不等于过滤器,这可能不会使用索引...在蒙戈DOC它说:“MongoDB的$ NE或$宁运营商的效率不高与指标。”

我建议您将字段'Facebook.fan_count_December_19_2011'编入索引,并且使用大于运算符。

db.metrics.find({ 
    {'Facebook.fan_count_December_19_2011' : {'$gte':1}},'Archived':'False'} 
} 
).limit(1) 

当然,您需要创建很多索引,但是您可以在脚本中高级地完成这些工作,而不需要太多的工作。

您也可以考虑存储日期作为一个字段,那么你可以像下面这样:

db.metrics.find({ 
    {'Facebook.date' : {'$gte':'2011-12-01'}},'Archived':'False'} 
} 
).limit(100) 

你需要的指数无论哪种方式,这是不可避免的。