ObjectID,也就是我們在進行insert操作時會自動生成的_id字段。我們經常會看到它,這個字段的組成及其設計思路我們可以參考NoSQLFan之前的文章《MongoDB文檔(Document)全局唯一ID的設計思路》。
今天我們想講一下對這個字段的一些優化,內容主要來源於MongoDB官方文檔。
1.使用業務中的唯一ID
_id字段在不指定時是自動生成的,也就是說,我們也可以在insert操作時自己指定它的值。如果你的業務中對每一條數據都有一個唯一ID,那麼建議使用這個ID的值作爲_id的值。比如存用戶信息的collection,那麼你可以使用用戶的uid作_id的值,這樣做有兩個好處:
- 減少原有_id對空間的佔用
- 讓你的_id值意義更明確
2.使用自增數據爲_id
由於_id字段是會自動創建索引的,所以如果你按上面的方法用業務中的唯一ID作爲_id的值,那麼它也會創建一個索引。所以如果你的ID值是一個自增長的字段,那麼在insert操作修改索引時,就不需要將_id的索引整個加載到內存中了。(實際上自動生成的_id就有這個特性)
3.使用二進制數據,而非編碼字符串
如果你打算設置的_id值是一個二進制的串,那麼你不需要將它進行16進制編碼後存在一個字符串,因爲MongoDB支持BinData類型,你可以直接將二進制串作爲_id的值進行存儲。
而你也可以通過下面一些方法將二進制串轉換爲可讀的字符串
> // mongo shell bindata info:
> help misc
b = new BinData(subtype,base64str) create a BSON BinData value
b.subtype() the BinData subtype (0..255)
b.length() length of the BinData data in bytes
b.hex() the data as a hex encoded string
b.base64() the data as a base 64 encoded string
b.toString()
4.從ObjectId中獲取insert時間
如果你使用了默認的ObjectId作爲_id值,並且你還存在一個addtime字段保存添加時間,那麼你已經在犯錯了。因爲MongoDB默認的ObjectId本身就保存了一些信息。其中就包括本條記錄生成的時間。你只需要通過下面方法就能獲取到其中的信息:
> // ObjectId支持的方法
> help misc
o = new ObjectId() create a new ObjectId
o.getTimestamp() return timestamp derived from first 32 bits of the OID
o.isObjectId()
o.toString()
o.equals(otherid)
5.使用默認_id進行排序
如果使用了默認的ObjectId作爲_id值,而你又希望通過insert的時間進行排序查詢,那麼一切就簡單了,你可以直接使用_id字段進行排序,因爲它本身是按insert的時間自增生成的。
> // 獲取最新加入的10條記錄
> db.mycollection.find().sort({id:-1}).limit(10);
參考:http://www.mongodb.org/display/DOCS/Optimizing+Object+IDs