您是正确的,如果您只查询字段数组中的 a 的值,那么从某种意义上说,这两个索引都会帮助您提高查询的性能。
但是,请查看以下 3 个查询:
> db.zaid.save({field : [{a: 1}, {b: 2}, {c: 3}] });
> db.zaid.ensureIndex({field:1});
> db.zaid.ensureIndex({"field.a":1});
#Query 1
> db.zaid.find({"field.a":1})
{ "_id" : ObjectId("50b4be3403634cff61158dd0"), "field" : [ { "a" : 1 }, { "b" : 2 }, { "c" : 3 } ] }
> db.zaid.find({"field.a":1}).explain();
{
"cursor" : "BtreeCursor field.a_1",
"nscanned" : 1,
"nscannedObjects" : 1,
"n" : 1,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : true,
"indexOnly" : false,
"indexBounds" : {
"field.a" : [
[
1,
1
]
]
}
}
#Query 2
> db.zaid.find({"field.b":1}).explain();
{
"cursor" : "BasicCursor",
"nscanned" : 1,
"nscannedObjects" : 1,
"n" : 0,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
}
}
#Query 3
> db.zaid.find({"field":{b:1}}).explain();
{
"cursor" : "BtreeCursor field_1",
"nscanned" : 0,
"nscannedObjects" : 0,
"n" : 0,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : true,
"indexOnly" : false,
"indexBounds" : {
"field" : [
[
{
"b" : 1
},
{
"b" : 1
}
]
]
}
}
请注意,即使您为数组编制了索引,第二个查询也没有索引,但第三个查询却有。根据您打算如何查询数据来选择索引与考虑索引本身是否是您需要的一样重要。在 Mongo 中,如果您不小心,您的索引结构可以并且确实会对查询的性能产生非常大的影响。我认为这解释了你的第一个问题。
您的第二个问题有点开放式,但我认为答案再次在于您期望如何查询数据。如果您只对匹配“fields.a”的值感兴趣,那么您应该为将来可能需要的其他索引节省内存空间。但是,如果您同样可能查询数组中的任何这些项目,并且您有理由确定数组不会无限增长(永远不要对可能会随着时间增长到无限大小的数组进行索引。索引一旦数组在 BSON 中达到 1024 个字节,将无法索引文档。),那么您应该索引整个数组。这方面的一个例子可能是一手扑克牌的文档,其中包含描述用户手中每张牌的数组。