mongo中的数组复合索引

时间:2014-07-02 00:21:56

标签: mongodb indexing

我有一个mongodb集合,其中的文档包含以下字段(文档有很多字段,但我删除了它们以便理解):

{
   "_id": ObjectId("53aad11444d0e2fd648b4567"),
   "id": NumberLong(238790),
   "rid": NumberLong(12),
   "parent_id": {
        "0": NumberLong(12),
        "1": NumberLong(2) 
    },
   "coid": NumberLong(3159),
   "reid": NumberLong(4312),
   "cid": NumberLong(4400) 
}

当我运行查询时,我得到了

> db.ads2.find({coid:3159, parent_id : 2}).sort({inserdate:1}).explain()
{
    "cursor" : "BtreeCursor coid_1_parent_id_1_insertdate_-1",
    "isMultiKey" : true,
    "n" : 20444,
    "nscannedObjects" : 20444,
    "nscanned" : 20444,
    "nscannedObjectsAllPlans" : 20444,
    "nscannedAllPlans" : 20444,
    "scanAndOrder" : true,
    "indexOnly" : false,
    "nYields" : 319,
    "nChunkSkips" : 0,
    "millis" : 274,
    "indexBounds" : {
        "coid" : [
            [
                3159,
                3159
            ]
        ],
        "parent_id" : [
            [
                2,
                2
            ]
        ],
        "insertdate" : [
            [
                {
                    "$maxElement" : 1
                },
                {
                    "$minElement" : 1
                }
            ]
        ]
    },
    "server" : "myserver.com:27017",
    "filterSet" : false
}

问题是如何更改索引以使mongo正确使用它?

1 个答案:

答案 0 :(得分:0)

首先,您的查询和您发布的文档结构不匹配。如果对包含具有此类结构的文档的集合运行此查询,则不会得到任何结果。

但是,由于您的查询产生了20444结果,我猜您的结构实际上是这样的:

{
   ...
   "parent_id": [
        "0": NumberLong(12),
        "1": NumberLong(2) 
    ],
    ...
}

这是您创建的索引:

   db.x.ensureIndex({coid : 1, parent_id : 1, insertdate : -1});

explain()输出中可以看到MongoDB正在使用索引查找文档(因为扫描文档的数量等于返回文档的数量n == nscanned)。但是,"scanAndOrder" : true表示MongoDB没有使用索引来对文档进行排序。

您的索引应该用于匹配和排序如果您用于排序的字段存在于文档中。

但问题是我在你的结构中看不到insertdate字段。因此,如果您按文档中不存在的字段进行排序,通常MongoDB不能使用索引进行排序。

修改

在您对原始问题进行评论和检查后,我可能会发现导致您出现问题的原因。您正在执行的查询中有拼写错误。您将sort参数指定为inserdate,而索引字段的名称为insertdate