我自己找到这个问题的答案时遇到了一些困难:
在mongo文档中存储键/值对的最佳方法是什么,并在其上放置索引以执行多标准搜索。
我有一个存储在mongo数据库中的文档,如下所示:
{
_id:xxxxxxxxxx,
name : "x1",
tags : [
{key:"color", value:"blue"},
{key:"size", value:"L"},
{key:"weight", value:5}
]
}
“tags”属性的每个键都是唯一的(每个文档的颜色或大小不能超过1个),每个键都是optionnal(我可以指定没有“color”的文档)。
根据"Indexes FAQ",我创建了一个这样的索引:
{
"tags.key":1, "tags.value":1
}
要对此索引执行查询,我使用此查询(返回所有蓝色项目):
.find({
tags:{$elemMatch:{"key":"color","value":"blue"}}
})
explain()显示查询使用索引。好!
但是现在,如果我想进行多标准搜索,我会使用此查询(返回所有大小为“L”的蓝色项目):
.find({
$and:[
{tags:{$elemMatch:{"key":"color","value":"blue"}}},
{tags:{$elemMatch:{"key":"size","value":"L"}}}
]
})
此查询正在运行,但执行计划显示的IXSAN扫描的文档多于返回的数量:
{
"cursor" : "BtreeCursor Keys",
"isMultiKey" : true,
"n" : 22,
"nscannedObjects" : 53,
"nscanned" : 53,
"nscannedObjectsAllPlans" : 53,
"nscannedAllPlans" : 109,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 2,
"indexBounds" : {
"tags.key" : [
[
"color",
"color"
]
],
"tags.value" : [
[
"blue",
"blue"
]
]
},
"server" : "BLABLABLA:27017",
"filterSet" : false,
"stats" : {
"type" : "PROJECTION",
"works" : 55,
"yields" : 0,
"unyields" : 0,
"invalidates" : 0,
"advanced" : 22,
"needTime" : 0,
"needFetch" : 0,
"isEOF" : 1,
"children" : [
{
"type" : "KEEP_MUTATIONS",
"works" : 55,
"yields" : 0,
"unyields" : 0,
"invalidates" : 0,
"advanced" : 22,
"needTime" : 31,
"needFetch" : 0,
"isEOF" : 1,
"children" : [
{
"type" : "FETCH",
"works" : 54,
"yields" : 0,
"unyields" : 0,
"invalidates" : 0,
"advanced" : 22,
"needTime" : 31,
"needFetch" : 0,
"isEOF" : 1,
"alreadyHasObj" : 0,
"forcedFetches" : 0,
"matchTested" : 22,
"children" : [
{
"type" : "IXSCAN",
"works" : 53,
"yields" : 0,
"unyields" : 0,
"invalidates" : 0,
"advanced" : 53,
"needTime" : 0,
"needFetch" : 0,
"isEOF" : 1,
"keyPattern" : "{ tags.key: 1.0, tags.value: 1.0 }",
"boundsVerbose" : "field #0['tags.key']: [\"color\", \"userid\"], field #1['Keys.v']: [\"4189\", \"4189\"]",
"isMultiKey" : 1,
"yieldMovedCursor" : 0,
"dupsTested" : 53,
"dupsDropped" : 0,
"seenInvalidated" : 0,
"matchTested" : 0,
"keysExamined" : 53,
"children" : []
}
]
}
]
}
]
}
}
似乎在IXSCAN中只考虑了第一个$ elemMatch。
那么,有没有办法改善这个或没有? 要么通过更改我的文档设计来更改查询?
欢迎您的帮助!
佛瑞德