【问题标题】:What does indexing a key of an embedded document really mean?索引嵌入文档的键的真正含义是什么?
【发布时间】:2015-07-16 08:16:11
【问题描述】:

我仍然不明白如何真正为嵌入文档的键编制索引。
假设我有以下博文集:

{
    _id:0,
    author: 'John Doe',
    content: 'How indexing an embedded document work?',
    comments:
    [
      {
        sender:'Jane Doe',
        content: 'I can\'t make it out either.'
      },
      etc...
    ]
},
etc...

假设我现在在 cmets 中的 sender 属性上设置一个索引:

db.blog.createIndex({'comments.sender':1})

现在的问题:
这是否意味着无论它们在哪个数组中,都会为发送者按升序排序的所有元素创建一个大索引?还是为每个数组创建一个索引?
为了更清楚:当我这样做时

blog.find({'comments.sender':'Jane Doe'}).toArray(function(err, array){})

它是否会遍历每篇博文并查找每个数组,直到在该数组中找到一条记录并在下一篇文章中移动到下一个数组?或者有一个大索引,其中每条记录(按发送者排序)映射到该匹配所在的原始数组?

【问题讨论】:

    标签: arrays node.js mongodb indexing embedded-documents


    【解决方案1】:

    这将创建一个索引,每个评论一个条目。如果您有 2 篇博客文章,每篇文章有 3 个 cmets,那么您将有一个包含 6 个条目的索引,由评论发件人名称索引。您的第二个假设是正确的:您的搜索将使用该索引有效地找到具有正确发件人的所有 cmets,然后返回相应的博客文章。

    如此简短的回答:是的,这样做,它有效,您将获得最佳查询时间。

    您可以使用 explain 轻松检查查询的复杂性:

    > db.blog.insert({'comments': [{'sender': 'Jane'}]})
    WriteResult({ "nInserted" : 1 })
    > db.blog.insert({'comments': [{'sender': 'Jane'}, {'sender': 'Joe'}]})
    WriteResult({ "nInserted" : 1 })
    > db.blog.insert({'comments': [{'sender': 'Joe'}]})
    WriteResult({ "nInserted" : 1 })
    > db.blog.ensureIndex({'comments.sender': 1})
    {
            "createdCollectionAutomatically" : false,
            "numIndexesBefore" : 1,
            "numIndexesAfter" : 2,
            "ok" : 1
    }
    > db.blog.find({'comments.sender': 'Jane'}).count()
    2
    > db.blog.find({'comments.sender': 'Jane'}).explain()
    {
            "cursor" : "BtreeCursor comments.sender_1",
            "isMultiKey" : true,
            "n" : 2,
            "nscannedObjects" : 2,
            "nscanned" : 2,
            "nscannedObjectsAllPlans" : 2,
            "nscannedAllPlans" : 2,
            "scanAndOrder" : false,
            "indexOnly" : false,
            "nYields" : 0,
            "nChunkSkips" : 0,
            "millis" : 0,
            "indexBounds" : {
                    "comments.sender" : [
                            [
                                    "Jane",
                                    "Jane"
                            ]
                    ]
            },
            "server" : "metrics.9.0.api.production.infinit.io:27017",
            "filterSet" : false
    }
    

    这里我们看到确实使用了索引(“BtreeCursor”)并且只扫描了 2 个对象,而不是全部 3 个。删除索引,您将获得表扫描:

    > db.blog.dropIndex({'comments.sender': 1})
    { "nIndexesWas" : 2, "ok" : 1 }
    > db.blog.find({'comments.sender': 'Jane'}).explain()
    {
            "cursor" : "BasicCursor",
            "isMultiKey" : false,
            "n" : 2,
            "nscannedObjects" : 3,
            "nscanned" : 3,
            "nscannedObjectsAllPlans" : 3,
            "nscannedAllPlans" : 3,
            "scanAndOrder" : false,
            "indexOnly" : false,
            "nYields" : 0,
            "nChunkSkips" : 0,
            "millis" : 0,
            "server" : "metrics.9.0.api.production.infinit.io:27017",
            "filterSet" : false
    }
    

    【讨论】:

      猜你喜欢
      • 2014-10-13
      • 2014-10-10
      • 2017-05-06
      • 2012-03-30
      • 2011-10-10
      • 2012-08-03
      • 2012-01-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多