我有一个集合,其中包含许多具有此结构的产品文档。每个文档代表一个笛卡尔产品记录,并附带产品价格。
{
"name": "PRD_SV_HB2_SVH",
"criterias": [
{
"type": "PREMIUM_REGION",
"value": "COD_RP_KZH"
},
{
"type": "ACCIDENT",
"value": "COD_UZ_EIN"
},
{
"type": "AGE_GROUP",
"value": "COD_LA_G36"
},
{
"type": "PRICE_MODEL",
"value": "COD_TM_HO2"
},
{
"type": "PRICE_TABLE",
"value": "PRT_SU_HB2_V001_2009010"
},
{
"type": "DEDUCTIBLE",
"value": "COD_SB_HO4"
}
],
"price": {
"pricingElements": {
"BASE_PRICE": {
"currency": "CHF",
"amount": 67.8
}
}
},
"priceType": "STANDARD",
"_class": "a.b.c.Product"
}
当查询集合中唯一的笛卡尔积记录时,我使用以下查询:
db.product.find({ "name": "PRD_SV_HB2_SVH", "$and": [
{ "criterias": { "$elemMatch": { "value": "COD_LA_G36" } } },
{ "criterias": { "$elemMatch": { "value": "COD_SB_HO4" } } },
{ "criterias": { "$elemMatch": { "value": "COD_UZ_EIN" } } },
{ "criterias": { "$elemMatch": { "value": "COD_RP_KZH" } } },
{ "criterias": { "$elemMatch": { "value": "COD_TM_HO2" } } },
{ "criterias": { "$elemMatch": { "value": "PRT_SU_HB2_V001_2009010" } } }
]
})
查询花费了超过2秒钟的时间才能产生不令人满意的结果。当我在同一查询上运行explain
时,我可以看到MongoDB使用索引name
,但没有为此查询使用专用索引name_value
。
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "productEngine.product",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "COD_LA_G36"
}
}
}
},
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "COD_SB_HO4"
}
}
}
},
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "COD_UZ_EIN"
}
}
}
},
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "COD_RP_KZH"
}
}
}
},
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "COD_TM_HO2"
}
}
}
},
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "PRT_SU_HB2_V001_2009010"
}
}
}
},
{
"name" : {
"$eq" : "PRD_SV_HB2_SVH"
}
}
]
},
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "COD_LA_G36"
}
}
}
},
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "COD_SB_HO4"
}
}
}
},
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "COD_UZ_EIN"
}
}
}
},
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "COD_RP_KZH"
}
}
}
},
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "COD_TM_HO2"
}
}
}
},
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "PRT_SU_HB2_V001_2009010"
}
}
}
}
]
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"name" : 1
},
"indexName" : "name",
"isMultiKey" : false,
"multiKeyPaths" : {
"name" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"name" : [
"[\"PRD_SV_HB2_SVH\", \"PRD_SV_HB2_SVH\"]"
]
}
}
},
"rejectedPlans" : [
{
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "COD_LA_G36"
}
}
}
},
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "COD_SB_HO4"
}
}
}
},
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "COD_UZ_EIN"
}
}
}
},
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "COD_RP_KZH"
}
}
}
},
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "COD_TM_HO2"
}
}
}
},
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "PRT_SU_HB2_V001_2009010"
}
}
}
}
]
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"name" : 1,
"criteria.value" : 1
},
"indexName" : "name_value",
"isMultiKey" : false,
"multiKeyPaths" : {
"name" : [ ],
"criteria.value" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"name" : [
"[\"PRD_SV_HB2_SVH\", \"PRD_SV_HB2_SVH\"]"
],
"criteria.value" : [
"[MinKey, MaxKey]"
]
}
}
},
{
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "COD_LA_G36"
}
}
}
},
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "COD_SB_HO4"
}
}
}
},
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "COD_UZ_EIN"
}
}
}
},
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "COD_RP_KZH"
}
}
}
},
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "COD_TM_HO2"
}
}
}
},
{
"criterias" : {
"$elemMatch" : {
"value" : {
"$eq" : "PRT_SU_HB2_V001_2009010"
}
}
}
}
]
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"name" : 1,
"priceType" : 1,
"criteria.value" : 1
},
"indexName" : "name_priceType_value",
"isMultiKey" : false,
"multiKeyPaths" : {
"name" : [ ],
"priceType" : [ ],
"criteria.value" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"name" : [
"[\"PRD_SV_HB2_SVH\", \"PRD_SV_HB2_SVH\"]"
],
"priceType" : [
"[MinKey, MaxKey]"
],
"criteria.value" : [
"[MinKey, MaxKey]"
]
}
}
}
]
},
"serverInfo" : {
"host" : "1a63040d1b73",
"port" : 27018,
"version" : "3.4.10",
"gitVersion" : "078f28920cb24de0dd479b5ea6c66c644f6326e9"
},
"ok" : 1
}
我目前这样创建name_value
复合索引:
{"name":1, "criteria.value":1}
这是在嵌套文档字段上创建复合索引的正确方法,还是我在这里遗漏了什么?为什么不使用name_value
索引?