我在MongoDB中有一个集合,该集合包含财产清单的数据:财产地址,卧室,浴室等...最终用户可以执行财产搜索并筛选50多个不同字段(例如“我想查看500美元以上的财产” K包含3个以上的浴室”),这使得很难覆盖索引中的可过滤字段。为了解决这个问题,我从https://dzone.com/articles/mongodb-indexing-tip-3-how那里得到了建议,并将所有可过滤字段存储在子数组中,如下所示:
{
"PropertyId": 123,
"StreetAddress1": "49 Yarmouth Ln",
"City", "North East",
"Fields": [
{ "k": "Bedrooms", "v": 5 },
{ "k": "Bathrooms", "v": 3 },
{ "k": "ListPrice", "v": 450000 },
...
]
}
然后我创建了一个索引,如下所示:
db.PropertyListing.ensureIndex( { "Fields.k": 1, "Fields.v": 1 }, { name: 'PropertyListingIndex' } );
这在某种程度上起作用,但是当我尝试查询Fields数组中的多个事物时:
$match: {
Fields: {
$all: [
{ $elemMatch: { k: "CityPlaceId", v: 50636770 } },
{ $elemMatch: { k: "Bedrooms", v: 3 } },
]
}
}
...查询的执行速度比预期的慢。当我使用.explain()函数时,它显示以下内容:
"inputStage": {
"stage": "IXSCAN",
"keyPattern": {
"Fields.k": 1,
"Fields.v": 1
},
"indexName": "PropertyListingIndex",
"isMultiKey": true,
"multiKeyPaths": {
"Fields.k": ["Fields"],
"Fields.v": ["Fields"]
},
"isUnique": false,
"isSparse": false,
"isPartial": false,
"indexVersion": 2,
"direction": "forward",
"indexBounds": {
"Fields.k": ["[\"CityPlaceId\", \"CityPlaceId\"]"],
"Fields.v": ["[50636770, 50636770]"]
}
}
如果我正确地阅读了此内容,则表示它仅使用CityPlaceId进行索引扫描,而不使用其他字段(例如“卧室”)。这将解释为什么如果只在一个过滤字段上使用索引会很慢。索引是这样工作的,它们只能扫描索引数组中的一个字段吗?但是,我必须使用索引数组,因为我有很多字段需要查询,因此我不清楚如何解决这种情况。有什么想法吗?