复合指数+;MongoDB中的regexp
我试图使用复杂的mongoDB索引解决一个简单的问题。我有一个复合指数+;MongoDB中的regexp,regex,mongodb,indexing,Regex,Mongodb,Indexing,我试图使用复杂的mongoDB索引解决一个简单的问题。我有一个events集合和一个participants集合。参与者集合中的文档有一个可搜索的\u关键字字段,它是一个数组 我的guests收藏中有以下复合索引: event_id_1_searchable_keywords_1 显然,我在guests集合上有一个简单的索引event\u id字段 当我运行以下查询时: eventId = db.events.findOne()["_id"]; db.guests.find({"event_i
events
集合和一个participants
集合。参与者
集合中的文档有一个可搜索的\u关键字
字段,它是一个数组
我的guests
收藏中有以下复合索引:
event_id_1_searchable_keywords_1
显然,我在guests
集合上有一个简单的索引event\u id
字段
当我运行以下查询时:
eventId = db.events.findOne()["_id"];
db.guests.find({"event_id": eventId, "searchable_keywords": "engineer"}).explain()
我可以看到使用了正确的索引
问题是当我使用正则表达式搜索运行它时:
db.guests.find({"event_id": eventId, "searchable_keywords": /^engin/}).explain(true)
结果如下:
{
"cursor" : "BtreeCursor event_id_1",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 11,
"nscanned" : 11,
"nscannedObjectsAllPlans" : 40,
"nscannedAllPlans" : 48,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 1,
"indexBounds" : {
"event_id" : [
[
ObjectId("532c5a5887512e567a00067a"),
ObjectId("532c5a5887512e567a00067a")
]
]
},
"allPlans" : [
{
"cursor" : "BtreeCursor event_id_1",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 11,
"nscanned" : 11,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"event_id" : [
[
ObjectId("532c5a5887512e567a00067a"),
ObjectId("532c5a5887512e567a00067a")
]
]
}
},
{
"cursor" : "BtreeCursor deleted_at_1_event_id_1_updated_at_1_created_at_-1",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 11,
"nscanned" : 11,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"deleted_at" : [
[
null,
null
]
],
"event_id" : [
[
ObjectId("532c5a5887512e567a00067a"),
ObjectId("532c5a5887512e567a00067a")
]
],
"updated_at" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"created_at" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
]
}
},
{
"cursor" : "BtreeCursor event_id_1_searchable_keywords_1_created_at_-1",
"isMultiKey" : true,
"n" : 0,
"nscannedObjects" : 9,
"nscanned" : 13,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"event_id" : [
[
ObjectId("532c5a5887512e567a00067a"),
ObjectId("532c5a5887512e567a00067a")
]
],
"searchable_keywords" : [
[
"",
{
}
],
[
/engin/,
/engin/
]
],
"created_at" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
]
}
},
{
"cursor" : "BtreeCursor deleted_at_1_event_id_1_searchable_keywords_1_created_at_-1",
"isMultiKey" : true,
"n" : 0,
"nscannedObjects" : 9,
"nscanned" : 13,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"deleted_at" : [
[
null,
null
]
],
"event_id" : [
[
ObjectId("532c5a5887512e567a00067a"),
ObjectId("532c5a5887512e567a00067a")
]
],
"searchable_keywords" : [
[
"",
{
}
],
[
/engin/,
/engin/
]
],
"created_at" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
]
}
}
],
"server" : "Romains-MacBook-Pro-2.local:27017",
"filterSet" : false,
"stats" : {
"type" : "KEEP_MUTATIONS",
"works" : 13,
"yields" : 0,
"unyields" : 0,
"invalidates" : 0,
"advanced" : 0,
"needTime" : 11,
"needFetch" : 0,
"isEOF" : 1,
"children" : [
{
"type" : "FETCH",
"works" : 12,
"yields" : 0,
"unyields" : 0,
"invalidates" : 0,
"advanced" : 0,
"needTime" : 11,
"needFetch" : 0,
"isEOF" : 1,
"alreadyHasObj" : 0,
"forcedFetches" : 0,
"matchTested" : 0,
"children" : [
{
"type" : "IXSCAN",
"works" : 11,
"yields" : 0,
"unyields" : 0,
"invalidates" : 0,
"advanced" : 11,
"needTime" : 0,
"needFetch" : 0,
"isEOF" : 1,
"keyPattern" : "{ event_id: 1 }",
"boundsVerbose" : "field #0['event_id']: [ObjectId('532c5a5887512e567a00067a'), ObjectId('532c5a5887512e567a00067a')]",
"isMultiKey" : 0,
"yieldMovedCursor" : 0,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0,
"matchTested" : 0,
"keysExamined" : 11,
"children" : [ ]
}
]
}
]
}
}
是否确实可以在MongoDB中对复合索引执行正则表达式搜索?对“是否确实可以在MongoDB中对复合索引执行正则表达式搜索”的回答是肯定的(我使用MongoDB 2.6.3设置了一个快速测试以确保)。如果简单索引是复合索引的适当子集,那么实际上不需要两者都有,这样就可以删除
{event\u id:1}
索引(这只会增加开销);当比较候选查询计划时,第一个索引可能会更快地返回这些值的结果。您是否尝试过为eventId
和searchable_关键字
使用不同的值?如果您想进一步挖掘,可以从mongo
shell发布此查询的explain(true)
结果吗?这将显示查询计划评估的详细信息(而不仅仅是获胜的计划)。此外,您使用什么界面来explain()
查询。。我注意到您使用的是where()
而不是find()
?您好,我实际上使用的是mongoid,但我在MongoShell上重现了这个问题。我会马上更新我的帖子,谢谢。@Stennie,我不知道查询优化器是基于数据的。实际上,我在一个生产数据库中发现了一个缓慢的查询,并试图在development中重现它,但在这两种情况下,都没有使用预期的索引。