我在 windows server 2008 R2 上使用 MongoDB,版本 2.4.8,我有奇怪的索引行为,我无法解释。这是我收藏中的结构示例:
{
"_id" : NUUID("67070100-4627-4aa5-8ab9-45624e5b82ad"),
"PropertyType" : "Cooperative",
"Address" : {
"Street" : "aaaaaaaaa",
"HouseNo" : "165",
"PostalCode" : 2860,
"City" : "bbbbb",
"Floor" : "1",
"DoorNumber" : ""
},
"Sales" : {
"Price" : 425000,
"Payout" : 0,
"AreaPrice" : 9042,
"GrossPrice" : 2340,
"NetPrice" : 800,
},
"WithdrawnFromSale" : true,
"UnitData" : {
"UnitType" : "aaaaa",
"Area" : 400,
"LivingArea" : 50,
"UnitArea" : 50,
"Rooms" : 2,
"BuildYear" : 1948,
"GroundArea" : 203,
"NoiseLevel" : 5
}
}
另外,我为该集合创建了索引:
db["UnitModel"].ensureIndex({ "Sales": 1, "PropertyType": 1, "UnitData.Rooms": 1, "UnitData.NoiseLevel": 1 })
该索引的问题是我在使用该索引时得到了错误的项目计数。
当我发出这个请求时:
db.UnitModel.find({Sales: {$ne: null}, WithdrawnFromSale: false}).explain({verbose: true})
我得到以下结果:
{
"cursor" : "BtreeCursor Sales_1_PropertyType_1_UnitData.Rooms_1_UnitData.NoiseLevel_1 multi",
"isMultiKey" : false,
"n" : 19368,
"nscannedObjects" : 42875,
"nscanned" : 42876,
"nscannedObjectsAllPlans" : 43274,
"nscannedAllPlans" : 43276,
"scanAndOrder" : false,
"indexOnly" : false,
....
}
在这里我们可以看到已经使用了索引,但是返回的项目数是“n”:19368。。这是错误的。它应该是 70986项符合该标准的集合。
为什么我确定应该是更多记录?好吧,这里的代码:
var totalCount = 0;
db.UnitModel.find({WithdrawnFromSale: false}).forEach(
function (e) {
if(e.hasOwnProperty('Sales') && e.Sales != null)
totalCount++;
}
)
totalCount;
总数 = 70986
为了确保上面的查询不使用任何索引,让我们检查一下:
db.UnitModel.find({WithdrawnFromSale: false}).explain({verbose: true})
结果:
{
"cursor" : "BasicCursor",
"isMultiKey" : false,
"n" : 70986,
"nscannedObjects" : 3204212,
"nscanned" : 3204212,
"nscannedObjectsAllPlans" : 3204212,
"nscannedAllPlans" : 3204212,
"scanAndOrder" : false,
"indexOnly" : false,
....
}
因此,对于我正在使用的 UnitModel 集合,标准:Sales: {$ne: null}, WithdrawnFromSale: false它应该是 mongo 返回的 70986 条记录。但正如你所看到的,我弄错了。
有人可以解释我为什么吗?可能是什么原因?
顺便提一句。当我删除该索引并使用以下索引时: db["UnitModel"].ensureIndex({ "WithdrawnFromSale": 1}) 它按预期工作。但是我不需要那个索引,这对我的情况来说不是最优的。