1

I want to match multiple start strings in mongo. explain() shows that it's using the indexedfield index for this query:

db.mycol.find({indexedfield:/^startstring/,nonindexedfield:/somesubstring/});

However, the following query for multiple start strings is really slow. When I run explain I get an error. Judging by the faults I can see in mongostat (7k a second) it's scanning the entire collection. It's also alternating between 0% locked and 90-95% locked every few seconds.

db.mycol.find({indexedfield:/^(startstring1|startstring2)/,nonindexedfield:/somesubstring/}).explain();

JavaScript execution failed: error: { "$err" : "assertion src/mongo/db/key.cpp:421" } at src/mongo/shell/query.js:L128

Can anyone shed some light on how I can do this or what is causing the explain error?

UPDATE - more info

Ok, so I managed to get explain to work on the more complex query by limiting the number of results. The difference is this:

For a single substring, "^/BA1/" (yes it's postcodes)

"cursor" : "BtreeCursor pc_1 multi",
"isMultiKey" : false,
"n" : 10,
"nscannedObjects" : 10,
"nscanned" : 10,
"nscannedObjectsAllPlans" : 19,
"nscannedAllPlans" : 19,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
    "indexedfield" : [
        [
            "BA1",
            "BA2"
        ],
        [
            /^BA1/,
            /^BA1/
        ]
    ]
}

For multiple substrings "^(BA1|BA2)/"

"cursor" : "BtreeCursor pc_1 multi",
"isMultiKey" : false,
"n" : 10,
"nscannedObjects" : 10,
"nscanned" : 1075276,
"nscannedObjectsAllPlans" : 1075285,
"nscannedAllPlans" : 2150551,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 5,
"nChunkSkips" : 0,
"millis" : 4596,
"indexBounds" : {
    "indexedfield" : [
        [
            "",
            {

            }
        ],
        [
            /^(BA1|BA2)/,
            /^(BA1|BA2)/
        ]
    ]
}

which doesn't look very good.

4

1 回答 1

0

$or 解决了使用索引的问题(感谢 EddieJamsession)。查询现在正在快速减少。

db.mycoll.find({$or: [{indexedfield:/^startstring1/},{indexedfield:/^startstring2/],nonindexedfield:/somesubstring/})

但是,如果可能的话,我仍然想用正则表达式来做这件事,所以我把这个问题留了下来。尤其是因为我现在必须重构我的应用程序以考虑这些类型的查询。

于 2013-11-04T15:16:38.667 回答