Index

MongoDB 嵌入式索引

  • July 18, 2018

我們有以下格式的集合:

{“_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,field1field2(例如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 } }
... })
>

引用自:https://dba.stackexchange.com/questions/212459