在MongoDB中添加什么索引以支持嵌入式文档上的$ elemMatch查询

时间:2015-03-07 11:17:20

标签: mongodb nosql

假设我们有以下文件

{
   embedded:[
   {
      email:"abc@abc.com",
      active:true
   },
   {
      email:"def@abc.com",
      active:false
   }]
}

应该使用什么索引来支持电子邮件和嵌入式文档的活动字段上的$ elemMatch查询。

问题更新: -

db.foo.aggregate([{"$match":{"embedded":{"$elemMatch":{"email":"abc@abc.com","active":true}}}},{"$group":{_id:null,"total":{"$sum":1}}}],{explain:true});

在查询这个时我得到了关于聚合的解释输出: -

{
"stages" : [
    {
        "$cursor" : {
            "query" : {
                "embedded" : {
                    "$elemMatch" : {
                        "email" : "abc@abc.com",
                        "active" : true
                    }
                }
            },
            "fields" : {
                "_id" : 0,
                "$noFieldsNeeded" : 1
            },
            "planError" : "InternalError No plan available to provide stats"
        }
    },
    {
        "$group" : {
            "_id" : {
                "$const" : null
            },
            "total" : {
                "$sum" : {
                    "$const" : 1
                }
            }
        }
    }
],
"ok" : 1
}

我认为mongodb内部不使用索引进行此查询。

提前Thanx:)

更新db.foo.stats()

的输出
db.foo.stats()
{
    "ns" : "test.foo",
    "count" : 2,
    "size" : 480,
    "avgObjSize" : 240,
    "storageSize" : 8192,
    "numExtents" : 1,
    "nindexes" : 3,
    "lastExtentSize" : 8192,
    "paddingFactor" : 1,
    "systemFlags" : 0,
    "userFlags" : 1,
    "totalIndexSize" : 24528,
    "indexSizes" : {
        "_id_" : 8176,
        "embedded.email_1_embedded.active_1" : 8176,
        "name_1" : 8176
    },
    "ok" : 1
}


db.foo.getIndexes();
[
    {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "test.foo"
    },
    {
        "v" : 1,
        "key" : {
            "embedded.email" : 1,
            "embedded.active" : 1
        },
        "name" : "embedded.email_1_embedded.active_1",
        "ns" : "test.foo"
    },
    {
        "v" : 1,
        "key" : {
            "name" : 1
        },
        "name" : "name_1",
        "ns" : "test.foo"
    }
]

1 个答案:

答案 0 :(得分:1)

如果您决定坚持使用该数据模型和查询,请按照以下步骤创建与查询匹配的索引:

您可以简单地索引"embedded.email",或使用嵌入索引的复合键,例如

> db.foo.ensureIndex({"embedded.email" : 1 });
  - or -
> db.foo.ensureIndex({"embedded.email" : 1, "embedded.active" : 1});

索引布尔字段通常不太有用,因为它们的选择性很低。