MongoDB 嵌入式索引
我們有以下格式的集合:
{“_id”:{“a”:8,“b”:ObjectId(“5b23aa9e24826b82a2553ce7”)},“field1”:“value1”,“field2”:“value2”,“field3”:“value3”,“field4” " : “值4”, }
據我所知,MongoDB 在 _id 欄位上創建了一個預設索引。但在這種情況下,我想知道 MongoDB 如何在 _id 上創建索引;它是在 _id.a 和 _id.b 欄位上還是在 _id.b 欄位上?另外,如果我在 (_id.a,field1,field2) 上創建一個額外的複合索引,它會產生額外的成本嗎?或者我只需要在 (filed1,filed2) 上創建和索引,因為 _id 已經是索引欄位。
請建議。謝謝!
但在這種情況下,我想知道 MongoDB 如何在 _id 上創建索引;它是在 _id.a 和 _id.b 欄位上還是在 _id.b 欄位上?
索引會將嵌入文件作為一個整體進行索引;即全部
{ "a" : 8, "b" : ObjectId(...) }
。這是一個完全不同的索引,而不是僅在 、 或兩個欄位上的複合索引上建構_id.a
的_id.b
索引。請注意,查詢嵌套文件需要與指定文件完全匹配。為了顯示:
> db.embed.insert({ "_id" : { "a" : 1, "b" : 2 } } ) WriteResult({ "nInserted" : 1 }) > db.embed.find( { "_id" : { "b" : 2, "a" : 1 } } ) > > db.embed.find( { "_id" : { "a" : 1, "b" : 2 } } ) { "_id" : { "a" : 1, "b" : 2 } }
如果單個查詢將在
_id.a
,field1
和field2
(例如db.foo.find( { "_id.a" : 8, "field1" : "value1", "field2" : "value2" })
) 上進行過濾,那麼我建議在三個欄位上建構複合索引,即{ "_id.a" : 1, "field1" : 1, "field2" : 1 }
.更新更多資訊以供評論:
這兩個查詢在功能上並不等效;第二個查詢只會過濾
{ "_id": {$lt:{"b":5} }, "field1": "value1" }
. 例如,嘗試以下操作:db.foo.insert({ "_id" : { "a" : 1, "b" : 1 } } ) db.foo.insert({ "_id" : { "a" : 2, "b" : 2 } } ) db.foo.insert({ "_id" : { "a" : 2, "b" : 1 } } ) db.foo.insert({ "_id" : { "a" : 1, "b" : 2 } } ) db.foo.find({ "_id.a":{ "$gt" : 1 }, "_id.b":{ "$lt": 2} }) db.foo.find({ "_id": { "$gt" : { "a": 1 } }, "_id": { "$lt" : { "b": 2 } } })
請注意,過濾多個欄位的查詢具有隱式邏輯與,只要過濾的欄位不同。第二個查詢實際上只會被過濾,
"_id": { "$lt" : { "b": 2 } }
因為有兩個過濾器_id
。要在此查詢中按預期使用邏輯與,需要$and過濾器。話雖這麼說,這兩個查詢問的是不同的事情。第一個查詢過濾嵌入的值“_id.a”和“_id.b”:
> db.foo.find({ ... "_id.a" : { "$lt" : 2 } ... }) { "_id" : { "a" : 1, "b" : 1 } } { "_id" : { "a" : 1, "b" : 2 } } > > db.foo.find({ ... "_id.b" : { "$lt" : 2 } ... }) { "_id" : { "a" : 1, "b" : 1 } } { "_id" : { "a" : 2, "b" : 1 } }
而第二個查詢要求返回 _the id的整個值大於/小於指定值的文件。這可能會返回意外結果:
> db.foo.find({ ... "_id": { "$lt" : { "a": 2 } } ... }) { "_id" : { "a" : 1, "b" : 1 } } { "_id" : { "a" : 1, "b" : 2 } } > > db.foo.find({ ... "_id": { "$lt" : { "b": 2 } } ... }) { "_id" : { "a" : 1, "b" : 1 } } { "_id" : { "a" : 1, "b" : 2 } } { "_id" : { "a" : 2, "b" : 1 } } { "_id" : { "a" : 2, "b" : 2 } } > db.foo.find({ ... "_id": { "$gt" : { "b": 1 } } ... }) >