MongoDB ObjectId詳解及使用

MongoDB ObjectId詳解及使用

2017年09月13日 14:25:18 universsky2015 閱讀數:11802mongodb

 版權聲明:本文爲博主原創文章,未經博主容許不得轉載。 https://blog.csdn.net/universsky2015/article/details/77965374shell

MongoDB中咱們常常會接觸到一個自動生成的字段:」_id」,類型爲ObjectId。
本文詳解ObjectId的構成和使用。數據庫

ObjectId構成

以前咱們使用MySQL等關係型數據庫時,主鍵都是設置成自增的。但在分佈式環境下,這種方法就不可行了,會產生衝突。爲此,MongoDB採用了一個稱之爲ObjectId的類型來作主鍵。ObjectId是一個12字節的 BSON 類型字符串。按照字節順序,一次表明:segmentfault

4字節:UNIX時間戳
3字節:表示運行MongoDB的機器
2字節:表示生成此_id的進程
3字節:由一個隨機數開始的計數器生成的值數組

ObjectId獲取時間

從ObjectId的構造上來看,內部就嵌入了時間類型。咱們確定能夠從中獲取時間信息:即插入此文檔時的時間。MongoDB對ObjectId對象提供了getTimestamp()方法來獲取ObjectId的時間。分佈式

> a = new ObjectId()ObjectId("53102b43bf1044ed8b0ba36b")> a.getTimestamp()ISODate("2014-02-28T06:22:59Z")
  • 1

根據時間構造ObjectId

上例是直接使用MongoDB提供的新建方法來構造ObjectId的,咱們本身可不能夠經過字符串來構造呢?看下例:spa

 
  1. // 使用Date的字符串構造方法生成日期,而後使用Date對象的getTime獲取毫秒數,再除以1000獲得標準時間戳.net

  2.  
  3. > a = new Date("2012-12-12 00:00:00").getTime()/1000code

  4.  
  5. 1355241600對象

  6.  
  7. // 獲取時間戳的標準十六進制表示

  8. > a = a.toString(16)

  9.  
  10. 50c75880

  11.  
  12.  
  13. // 在後面填補16個0

  14. > a = a + new Array(17).join("0") 50c758800000000000000000// 使用24個字符串構造ObjectId

  15.  
  16. > b = new ObjectId(a) ObjectId("50c758800000000000000000")// 獲取時間以驗證

  17.  
  18. > b.getTimestamp() ISODate("2012-12-11T16:00:00Z")

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

上述過程當中 new Array(17).join(「0″)目的是生成16個0拼接的字符串。

這裏使用了點小技巧。new Array(17)構造了一個17個元素的數組,可是數組裏面沒有元素,join(atr)方法的做用是鏈接數組元素而且以其參數分割。17個元素正好有16個間隔,因此最終拼接起來的字符串爲16個。
根據ObjectId按照插入時間排序

MongoDB默認在ObjectId上創建索引,是按照插入時間排序的。咱們可使用此索引進行查詢和排序。

 
  1. // 按序插入三個文檔

  2.  
  3. > db.col.insert({"num":1})

  4. > db.col.insert({"num":2})

  5. > db.col.insert({"num":3})

  6.  
  7. > db.col.find().pretty()

  8. { "_id" : ObjectId("53102fb4bf1044ed8b0ba36c"), "num" : 1 }

  9. { "_id" : ObjectId("53102fb9bf1044ed8b0ba36d"), "num" : 2 }

  10. { "_id" : ObjectId("53102fbabf1044ed8b0ba36e"), "num" : 3 }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Q&A

爲何選擇ObjectId
而不是遞增ID?
參考segmentfault上面的問題:mongoDB修改」_id」的objectID到普通遞增id爲何很差
如何取到ObjectId裏面的時間?

shell下可直接oid.getTimestamp()。各類驅動也都有對應的方法。

如何使用日期範圍來查詢ObjectId?

既然ObjectId是能夠排序的,它固然也能夠比較大小。在有日期範圍的狀況下,實際上能夠從_id中利用IXSCAN找到相應的記錄,而不須要根據另一個時間字段來查詢。若是時間字段正好沒有索引的話,_id的優點就體現出來了。stackoverflow上詳細講了該怎麼作。

使用本身生成的UUID字符串和ObjectId比較哪一個作_id更好?

中籤王言:抓住新股申購黃金時間點,10打新10次中,屢試不爽

相關文章
相關標籤/搜索