C# Mongo DB:优化唯一的基于密钥的嵌入式查询

C# Mongo DB:优化唯一的基于密钥的嵌入式查询,c#,.net,mongodb,C#,.net,Mongodb,我有一个Mongo集合,其中每个文档都有一组唯一的嵌入密钥: { 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

我有一个Mongo集合,其中每个文档都有一组唯一的嵌入密钥:

{
    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秒(不包括提供数据的站点的开销)。 在一批中发送所有密钥并执行一个大型查询需要对数据层进行重大重写;由于最后期限很紧,所以我尽量避免这样做。 我一直在浏览文档,但似乎没有一种方法可以创建基于键的索引。文档中说你可以在一个嵌入的键上建立索引;但这似乎只是指数的价值。这对我也没什么好处;因为系统中的每个键都是唯一的;每个新键都必须有一个索引

没有重新设计我们的文档结构(这需要进行重大更改);对于当前格式的现有集合,我是否可以加快查询速度

非常感谢任何建设性的意见

谢谢,
弗兰克

这只是猜测,但我怀疑它正在进行范围扫描,因为:

  • 您尚未在字段上指定索引,或者
  • 您正在执行一个不相等的筛选器,它可能不使用索引。。。Mongo文档上写着“MongoDB的$ne或$nin操作符的索引效率不高。”
  • 我建议您索引“Facebook.fan\u count\u December\u 19\u 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)
    

    不管怎样,你都需要一个索引,这是不可避免的

    假设在处理文档后将存档字段设置为true,则可以仅在存档字段上创建索引

    通常情况下,您不会在基数较低的字段上创建索引,但在这种情况下,它可能对您有用,但前提是没有太多文档的归档字段为false


    从长远来看,你应该重新设计你的文档,这样你就不会有那么多独特的字段名(类似于Iain建议的“Facebook.date”字段)。这样,您就可以创建索引了。

    为什么特定日期的粉丝数量是唯一的?在给定的日期,不能有两个拥有相同数量粉丝的收藏项目吗?或者您希望键是唯一的,而不是值?键必须是唯一的,因为它们是我们用来查找给定日期的度量的。我们从一个网站上获取这些数据,该网站记录了facebook粉丝在一个月内的增长情况,我们需要每天的历史记录才能做到这一点。当你说“键”时,你是指字段名还是字段值?我不确定我现在明白了。。。