Mongo中的子文档索引

43

当我调用ensureIndex(data)时,对于典型的数据data:{name: "A",age:"B", job : "C"},究竟会发生什么?它会创建一个跨这三个字段的复合索引还是只创建一个适用于请求数据中任何内容的索引,或者完全不同的东西?


2
很容易检查。只需创建一个测试集合并使用.explain()发出几个查询即可。这就是我会做的。我自己也不确定Mongo会做什么。 - Sergio Tulentsev
2个回答

54

你可以选择以下任意一项:

> db.collection.ensureIndex({"data.name": 1,"data.age":1, "data.job" : 1})
> db.collection.ensureIndex({"data": 1})

这在文档中讨论了,具体内容请查看嵌入字段索引子文档索引

子文档部分的重要内容是:“当在子文档上执行相等匹配时,字段顺序很重要,子文档必须完全匹配。”

这意味着对于简单查询,这两个索引是相同的。

然而,正如子文档示例所显示的,如果您只是索引整个子文档而不是特定字段,然后执行比较运算符(如$gte),您可以获得一些有趣的结果(可能超出您的预期)- 如果您索引特定的子字段,则会获得一个不太灵活但潜在更有用的索引。

这真的取决于您的使用情况。

无论如何,一旦创建了索引,您可以使用以下命令检查所创建的内容:

> db.collection.getIndexes()
[
{
    "v" : 1,
    "key" : {
        "_id" : 1
    },
    "ns" : "test.collection",
    "name" : "_id_"
},
{
    "v" : 1,
    "key" : {
        "data.name" : 1,
        "data.age" : 1,
        "data.job" : 1
    },
    "ns" : "test.collection",
    "name" : "data.name_1_data.age_1_data.job_1"
}

从输出结果可以看出,它创建了一个名为data.name_1_data.age_1_data.job_1的新键(_id_索引始终会被创建)。

如果您想测试新索引,则可以执行以下操作:

> db.collection.insert({data:{name: "A",age:"B", job : "C"}})
> db.collection.insert({data:{name: "A1",age:"B", job : "C"}})
> db.collection.find({"data.name" : "A"}).explain()
{
    "cursor" : "BtreeCursor data.name_1_data.age_1_data.job_1",
     .... more stuff

最重要的是您可以看到使用了新索引(游标字段中的BtreeCursor data.name_1_data.age_1_data.job_1表明了这一点)。如果您看到"cursor" : "BasicCursor",则说明没有使用您的索引。

欲了解更详细的信息,请查看此处


-3
你可以尝试这个:
db.collection.ensureIndex({"data.name": 1,"data.age":1, "data.job" : 1})

4
这并没有回答问题,即做这件事的结果是什么。 - Christophe
这并不是有益的。这种问题的重点在于为有类似问题的人节省时间。 - Nic Szerman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接