MongoDB主键是您的朋友
MongoDB集合中的所有文檔都有一個主鍵,稱為_id 。 該字段在插入后自動分配給文檔,因此幾乎不需要提供它。 _id字段的有趣之處在于它是基于時間的 。 也就是說,基礎(chǔ)類型的_id ,這是ObjectId ,是一個12字節(jié)的BSON型 ,和那些字節(jié)的4代表秒自Unix紀(jì)元。
_id字段的特殊之處還在于,它會通過在任何集合上調(diào)用getIndexes自動索引,如下所示。
所有MongoDB集合都有一個_id字段作為索引:
就像每個人都記得傳統(tǒng)RDBMS一樣, 索引很重要,因?yàn)樗鼈兛梢允刮臋n檢索更快。 但是,索引確實(shí)會占用內(nèi)存,并且在插入文檔時會稍微降低性能,因?yàn)楸仨毟滤邢鄳?yīng)的索引。 因此,盡管您應(yīng)該認(rèn)真考慮使用索引,但是在使用索引時需要經(jīng)濟(jì)。
自然地,僅當(dāng)您知道文檔的_id時才方便搜索。 通常會通過其他字段來搜索文檔,如果您發(fā)現(xiàn)自己是通過時間序列 (例如created_at進(jìn)行搜索的,那么您就來了。
想象一下名為logs的集合,其中包含捕獲各種日志消息的簡單文檔。 示例文檔如下所示:
日志收集中的一個簡單文檔:
{"_id" : ObjectId("51c4ab6d4d6906d494460728"),"message" : "crashed, no such method exception","type" : "crash","created_at" : ISODate("2013-06-21T19:37:17.992Z") }如果我想查找某個日期(例如今天)的所有日志消息怎么辦? 我可以這樣寫查詢:
查找自2013年6月20日以來創(chuàng)建的所有日志:
db.logs.find({created_at:{'$gt': new Date(2013, 5, 20)}})如果我對該查詢進(jìn)行解釋,則可以看到,因?yàn)槲以赾reated_at上沒有索引,因此可以利用基本游標(biāo),并且掃描了集合中的所有文檔以檢索結(jié)果。
我的發(fā)現(xiàn)所附的解釋計(jì)劃:
> db.logs.find({created_at:{'$gt': new Date(2013, 5, 20)}}).explain() {"cursor" : "BasicCursor","isMultiKey" : false,"n" : 2,"nscannedObjects" : 4,"nscanned" : 4,"nscannedObjectsAllPlans" : 4,"nscannedAllPlans" : 4,"scanAndOrder" : false,"indexOnly" : false,"nYields" : 0,"nChunkSkips" : 0,"millis" : 0,"indexBounds" : {},"server" : "ghome-computer.home:27017" }如您所見,通過created_at字段進(jìn)行搜索可能效率不高; 因此,您可能很想在該字段上添加索引。 這自然會使該特定查詢效率更高,但是,您將招致新索引的開銷,這將消耗更多的內(nèi)存,并且由于對該新創(chuàng)建的索引進(jìn)行了更新,因此插入操作會稍微慢一些。
事實(shí)證明,由于_id字段在其中嵌入了Unix紀(jì)元,因此無需添加 created_at字段,您就可以輕松地編寫find表達(dá)式。 例如, MongoDB Ruby驅(qū)動程序允許您從Time來創(chuàng)建ObjectId ,如下所示:
通過from_time工廠方法創(chuàng)建一個新的ObjectId:
yesterday = Time.now - (60*60*(24*1)) custom_id = BSON::ObjectId.from_time(yesterday) => BSON::ObjectId('51c397800000000000000000')如您所見,我通過from_time工廠方法創(chuàng)建了一個新的ObjectId 。 51c397800000000000000000是十六進(jìn)制表示形式,前8位數(shù)字表示時間,其他所有內(nèi)容均清零。
現(xiàn)在,我可以在任何find表達(dá)式中使用我的custom_id了。 通過Ruby驅(qū)動程序,我還可以將一個explain ,which'll展示自由的使用_id索引。
使用派生日期的ObjectId強(qiáng)制查找使用_id索引:
mongodb[:logs].find({_id: {'$gt' => custom_id}}).explain=> {"cursor"=>"BtreeCursor _id_", "isMultiKey"=>false, "n"=>1, "nscannedObjects"=>1, "nscanned"=>1, ....}如果看到BtreeCusor ,則表明您正在使用索引; 如果看到BasicCursor ,那么您知道不是。
因此,如果你發(fā)現(xiàn)自己在執(zhí)行查詢和創(chuàng)建了一段時間或日期字段比如索引created_at ,你可能會更好只使用蒙戈的_id領(lǐng)域,因?yàn)樗呀?jīng)嵌入在創(chuàng)建默認(rèn)情況下,索引的概念。 數(shù)字?
翻譯自: https://www.javacodegeeks.com/2013/06/mongodb-primary-keys-are-your-friend.html
總結(jié)
以上是生活随笔為你收集整理的MongoDB主键是您的朋友的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: gvim linux安装(gvim li
- 下一篇: 嗨,那里有回调!