Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb 为什么要在这里扫描任何对象?_Mongodb - Fatal编程技术网

Mongodb 为什么要在这里扫描任何对象?

Mongodb 为什么要在这里扫描任何对象?,mongodb,Mongodb,我有一个索引: {indices.textLc:1, group:1, lc:1, wordCount:1, pattern:1, clExists:1} Morphia会生成如下查询: { $and: [{ lc: "eng" }, { $or: [{ group: "cn" }, { group: "all" }] },

我有一个索引:

{indices.textLc:1, group:1, lc:1, wordCount:1, pattern:1, clExists:1} 
Morphia会生成如下查询:

{
    $and: [{
        lc: "eng"
    },
    {
        $or: [{
            group: "cn"
        },
        {
            group: "all"
        }]
    },
    {
        "indices.textLc": {
            $in: ["media strengthening", "strengthening", "media"]
        }
    },
    {
        wordCount: {
            $gte: 1
        }
    },
    {
        wordCount: {
            $lte: 2
        }
    }]
}
并解释:

{
    "cursor" : "BtreeCursor indices.textLc_1_group_1_lc_1_wordCount_1_pattern_1_clExists_1 multi",
    "nscanned" : 20287,
    "nscannedObjects" : 20272,
    "n" : 22,
    "millis" : 677,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "isMultiKey" : true,
    "indexOnly" : false,
    "indexBounds" : {
        "indices.textLc" : [
            [
                "media",
                "media"
            ],
            [
                "media strengthening",
                "media strengthening"
            ],
            [
                "strengthening",
                "strengthening"
            ]
        ],
        "group" : [
            [
                {
                    "$minElement" : 1
                },
                {
                    "$maxElement" : 1
                }
            ]
        ],
        "lc" : [
            [
                "eng",
                "eng"
            ]
        ],
        "wordCount" : [
            [
                1,
                1.7976931348623157e+308
            ]
        ],
        "pattern" : [
            [
                {
                    "$minElement" : 1
                },
                {
                    "$maxElement" : 1
                }
            ]
        ],
        "clExists" : [
            [
                {
                    "$minElement" : 1
                },
                {
                    "$maxElement" : 1
                }
            ]
        ]
    }
首先,我不明白为什么需要任何扫描,因为索引中的所有内容都可用。更具体地说,为什么indexBounds的wordCount部分看起来不像:

 "wordCount" : [
            [
                1,
                2
            ]
        ],

更新2012-03-20:如果这有助于解释什么的话,我正在运行MongoDB 2.0.3

在复合索引中,查询中的每个字段都可以使用,这几乎不说明它是否可以对查询中的每个子句使用一个索引。有一些事情需要考虑:

  • 除了顶级$or子句可以为每个子句使用索引外,每个MongoDB查询最多可以使用一个索引
  • 复合索引只有在复合中的每个后续字段都可以按顺序使用时才起作用,这意味着您的查询允许先过滤第一个索引字段,然后过滤第二个索引字段,依此类推。因此,如果您有一个索引{a:1,b:1},即使字段在复合索引中,查询{b:“Hi!”}也不会使用该索引
现在,您的查询需要扫描的原因是,您的索引只能优化“index.textLc”字段(您的第一个索引字段)的查询执行计划,在本例中是“lc”,因为它是$and中的一个单独子句

解释的“字数”部分实际上应为:

 "wordCount" : [
         [
                 1,
                 2
         ]
 ]
我刚刚在我的机器上测试了它,所以我认为你的Morphia/映射解决方案出了问题


复合索引和像您这样的复杂查询是一个棘手的问题。我现在没有时间查看您的查询和索引,看看它是否可以优化。今晚我会再来,如果可以的话,我会帮你。

谢谢你的回答,雷蒙!你有机会进一步探索吗?你在运行2.0.3吗?我检查过了,我的索引是v1格式的,所以不确定是什么导致了奇怪的字数范围。我运行的是2.0.3是。您应该重新索引()只是为了确定,但我不认为旧索引的wordCount子句应该有不同的值,不,没有机会进一步探讨。时间有点短;)