mongodb:优化一个唯一的嵌入式关键字查询

本文关键字:唯一 嵌入式 关键字 查询 一个 优化 mongodb | 更新日期: 2023-09-27 18:18:32

我有一个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)

问题是,有6,000个这样的文档,它有点慢。查看Explain()日志;每个查询的执行时间平均为0.06秒,并且每次都执行一次完整的集合扫描。我们的服务必须执行上述查询大约100次(针对100个不同的键);在0.06 p/s的速度下,每次调用总共需要6秒(不包括提供数据的站点的开销)。批量发送所有键并执行一次大型查询将需要对数据层进行大量重写;我一直在努力避免,因为截止日期快到了。我一直在看文档,似乎没有办法有一个基于键的索引。文档说你可以在一个嵌入的键上建立索引;但这似乎只是索引值。这对我也没什么好处;因为系统中的每个密钥都是唯一的;每个新键都必须有一个索引。

缺少重新设计我们的文档结构(这将需要一个重大的改变);无论如何,我可以做的是加快这个查询对现有的集合在它的当前格式?

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

谢谢,弗兰克。

mongodb:优化一个唯一的嵌入式关键字查询

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

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

从长远来看,你应该重新设计你的文档,这样你就不会有那么多唯一的字段名(类似于Iain建议的"Facebook")。日期"字段)。这样你就可以在上面创建索引了

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

  1. 您没有在字段上指定索引,或者
  2. 你正在做一个不相等的过滤器,它可能不使用索引…在MongoDB文档中,它说"MongoDB的$ne或$nin操作符对索引的效率不高。"

我建议你索引"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)

无论哪种方式都需要索引,这是不可避免的。