当前位置: 首页 > 知识库问答 >
问题:

MongoDB不使用复合索引_id

庄元龙
2023-03-14

我在MongoDB有一个收藏,里面有以下文档。

/* 0 */
{
    "T" : [ 
        374135056604448742
    ],
    "_id" : {
        "#" : 7778532275691,
        "ts" : ISODate("2013-07-26T02:25:00Z")
    }
}

/* 1 */
{
    "T" : [ 
        1056188940167152853
    ],
    "_id" : {
        "#" : 34103385525388,
        "ts" : ISODate("2013-07-30T03:00:00Z")
    }
}

/* 2 */
{
    "T" : [ 
        1056188940167152853
    ],
    "_id" : {
        "#" : 34103385525388,
        "ts" : ISODate("2013-07-30T03:18:00Z")
    }
}

现在,我尝试使用以下查询查询一些文档。

db.entries.find({
    '_id.ts': {'$gte': beginTS, '$lte': endTS}, 
    '_id.#' : 884327843395156951
    }).hint([('_id', 1)]).explain()

根据我的理解,由于\u id是一个复合字段,并且Mongo总是在\u id上维护一个索引,因此要回答上述查询,Mongo应该在“\u id”上使用索引。然而,上述问题的答案如下:

{u'allPlans': [{u'cursor': u'BtreeCursor _id_',
   u'indexBounds': {u'_id': [[{u'$minElement': 1}, {u'$maxElement': 1}]]},
   u'n': 2803,
   u'nscanned': 4869528,
   u'nscannedObjects': 4869528}],
 u'cursor': u'BtreeCursor _id_',
 u'indexBounds': {u'_id': [[{u'$minElement': 1}, {u'$maxElement': 1}]]},
 u'indexOnly': False,
 u'isMultiKey': False,
 u'millis': 128415,
 u'n': 2803,
 u'nChunkSkips': 0,
 u'nYields': 132,
 u'nscanned': 4869528,
 u'nscannedAllPlans': 4869528,
 u'nscannedObjects': 4869528,
 u'nscannedObjectsAllPlans': 4869528,
 u'scanAndOrder': False,

可以观察到,MongoDB正在对DB进行一次完整的扫描,以查找少量文档。我不知道这里到底怎么了。

我试图改变查询的顺序,但结果相同。我不知道这里发生了什么。如果深表感谢,任何帮助。

使现代化

我理解这里的细微差别。\u id不是复合索引,它只是一个精确的索引。这意味着,如果\u id是一个文档,那么不管文档的结构以及它可能有多少嵌套属性或子文档,\u id索引将只包含一个\u id字段条目。假设此条目是\u id文档的哈希,并且将保持唯一。

共有1个答案

周涵畅
2023-03-14

您正在使用对象作为键,但此处未使用计算索引。

id索引有点特殊,因为它是自动创建的,并且总是唯一的。通常,索引id是一个ObjectId、一个UUID、一个整数或一个包含某种哈希的字符串。MongoDB支持将复杂对象作为键。然而,对于MongoDB来说,这仍然只是一个文档。它可以与其他文档进行比较,具有相同字段和值的文档将是相等的。但是,由于您没有创建索引键(并且无法手动创建该索引),MongoDB不知道它包含一个字段和一个字段。

另一方面,复合索引明确地引用文档的字段,例如{“product.quantity”:1,“product.created”:-1}。创建索引时必须指定此选项。

似乎您正在尝试在主键中基本上存储时间戳。MongoDB的ObjectId已经包含时间戳,因此您可以直接对ObjectIds进行基于日期的范围查询。

 类似资料:
  • 我有一个MongoDB版本3.0.3集合,其中包含具有2个字段的文档: 数字长id 我在数组上构建了一个多键索引,并通过使用方法确认该索引存在并且是多键的。但是,当我查询数组中特定字段的2个范围的交集时,Mongo不使用此索引,尽管集合中有1,000,000个文档。我可以从方法的输出中看到这一点。更奇怪的是,当我使用指定索引时,Mongo遍历了所有1,000,000个文档和60,000,000个索

  • 主要内容:createIndex() 方法,dropIndex() 方法,dropIndexes() 方法,getIndexes() 方法索引是特殊的数据结构,存储在一个方便遍历和读取的数据集合中。索引在任何数据库中都非常重要,通过使用索引,可以大大提高查询语句的执行效率。 举个简单的例子,假如您有一个集合,其中包含了数千甚至上万个没有索引的文档,当我们在集合中查找某个文档时,MongoDB 需要扫描整个集合来寻找所需的文档,这种扫描效率极低,特别是在处理大量的数据时,可能需要花费几十秒甚至几分

  • 主要内容:额外开销,RAM 使用,查询限制,索引键限制,插入超过索引键限制的文档,最大范围本节我们来介绍以下使用索引时的一些限制和注意事项。 额外开销 每个索引都会占用一些空间,并且在每次执行插入、更新和删除等操作时也需要对索引进行操作,导致额外的开销。因此,如果您很少将某个集合用于读取操作,最好不要在集合中使用索引。 RAM 使用 由于索引存储在 RAM(内存)中,因此应确保索引的总大小不超过 RAM 的限制。如果总大小大于 RAM 的大小,那么 MongoDB 将删除一些索引,这就

  • 问题内容: 我想知道Elasticsearch是否需要先定义复合索引。通过复合索引,我的意思是像mongodb一样。 db.collection.ensureIndex({field1:1,field2:1,field3:1}) 或类似mysql db的东西。 在mytable(field1,field2,field3)上创建索引adhoc_index; 所以我要处理的数据非常平坦(大多数只是cs

  • 我想知道elasticsearch是否需要定义一个优先级的复合索引。通过复合索引,我的意思是像mongoDB一样的东西。 db.collection.ensure索引 或者类似mysql db的功能。 在mytable上创建索引adhoc_index(field 1, field 2, field 3); 因此,我处理的数据非常简单(大部分只是csv格式)。为完整起见,如下所示。 字段1,字段2。

  • 本文向大家介绍MongoDB的索引,包括了MongoDB的索引的使用技巧和注意事项,需要的朋友参考一下 1、简介 它就像是一本书的目录,如果没有它,我们就需要对整个书籍进行查找来获取需要的结果,即所说的全盘扫描; 而有了目录(索引)之后就可以通过它帮我们定位到目标所在的位置,快速的获取我们想要的结果。 2、演示 第一步,向用户集合users中插入100W条数据 LZ的渣渣I3和4G内存总共耗时了4