mongodb及其索引的使用例子

1.獲取某個屬性最大的value值並自增範例
因爲mongo不支持類似select max操作,也不支持遞增int的操作,所以採用目前的方案
#找到符合table_name的記錄,find輸出時只輸出type_id,按照type_id遞減排序,取到第一個
max_obj =stmt.find({"table_name":table_name},{"type_id":1}).sort("type_id",-1).limit(1)
#max_obj此時仍是cursor
new_id = 1
if max_obj.count()>0:#如果找到max_obj
   new_id = max_obj[0]["type_id"] + 1



2.upsert型存儲
stmt = self.db[ALERT_REPORT_TAB]
stmt.update({"phone_number":phone_number},json,upsert=True)


3.mongodb取到update_time字段最大的一條
db.andriod_spider.find().sort({"update_time":-1}).limit(1)

4.mongodb建索引
db.andriod_spider.ensureIndex({"update_time": 1}) #爲andriod_spider表建單一索引
db.andriod_spider.ensureIndex({"url": 1,"year":1}) #爲andriod_spider表建url和year的聯合索引
5.查詢所建的索引:
> use spider
switched to db spider
> db.system.indexes.find()
{ "v" : 1, "key" : { "_id" : 1 }, "ns" : "spider.spider_seed", "name" : "_id_" }
{ "v" : 1, "key" : { "_id" : 1 }, "ns" : "spider.andriod_spider", "name" : "_id_" }
{ "v" : 1, "key" : { "update_time" : 1 }, "ns" : "spider.andriod_spider", "name" : "update_time_1" }
{ "v" : 1, "key" : { "url" : 1, "year" : 1 }, "ns" : "spider.andriod_spider", "name" : "url_1_year_1" }
{ "v" : 1, "key" : { "title" : 1, "type" : 1 }, "ns" : "spider.andriod_spider", "name" : "title_1_type_1" }

6.一次mongodb排查問題的過程
有臺機器的mongo的CPU佔用一直很高

wKioL1Lny7myLf8tAADdR-J7LOU323.jpg

通過db.currentOp()命令發現大量的查詢操作是這個

wKioL1Lny9OxFDLfAAGNzJtP5o8795.jpg


最後通過這一句聯合索引搞定,不能單獨索引

db.ip_speed.ensureIndex({"start_ip":-1,"end_ip":1})

再次top

wKiom1LnzA-SUKtVAADYJPFsbqM669.jpg

看到已經到25%了,成功使用上索引

7.mongo刪除數據庫
use test_db  #use 要刪除的db
db.dropDatabase()


8.爲json嵌套格式的內部數據建索引

比如數據的json格式爲{"vv_record": [{"update_time":"2013-04-06 01:51:14"}, ...] }等

wKioL1LnzBSwvnc4AAGBIurLWBM390.jpg


建立索引後的查詢,記得帶小數點,如vv_record.update_time

wKiom1LnzGXBzdxsAAoj9cI8bKU370.jpg

9.mongo查找/刪除帶指定key的數據
這裏演示刪除帶有vv_record的記錄
db.user_profile.remove({"vv_record":{$exists: true} })


[轉載]mongodb索引附錄:

  索引類型

  雖然MongoDB的索引在存儲結構上都是一樣的,但是根據不同的應用層需求,還是分成了唯一索引(unique)、稀疏索引(sparse)、多值索引(multikey)等幾種類型。

  唯一索引

  唯一索引在創建時加上unique:true 的選項即可,創建命令如下:

db.users.ensureIndex({username: 1}, {unique: true})

  上面的唯一索引創建後,如果insert一條username已經存在的數據,則會報如下的錯誤:

E11000 duplicate key error index: gardening.users.$username_1 dup key: { : "kbanker" }

  如果你在一個已有數據的collection上創建唯一索引,若唯一索引對應的字段原來就有重複的數據項,那麼創建會失敗,我們需要加上一個dropDups的選項來強制將重複的項刪除掉,命令如下例:

db.users.ensureIndex({username: 1}, {unique: true, dropDups: true})

  鬆散索引

   如果你的數據中一些行中沒有某個字段或字段值爲null,那麼如果在這個字段上建立普通索引,那麼無此字段或值null的行也會參與到索引結構中,佔用 相應的空間。如果我們不希望這些值爲空的行參與到我們的索引中,這時候可以採用鬆散索引,鬆散索引只會讓指定字段不爲空的行參與到索引創建中來。創建一個 鬆散索引可以用下面的命令:

db.reviews.ensureIndex({user_id: 1}, {sparse: true})

  多值索引

  MongoDB可以對一個array類型創建索引,比如像下面的結構,MongoDB可以在tags字段上創建索引:

  { name: "Wheelbarrow",
  tags: ["tools", "gardening", "soil"]
  }

  在生成索引時,會爲tags中的三個值分別生成三個索引元素,索引中tools,gardening,soil三個值都會指向這同一行數據。相當於分裂成了三個獨立的索引項。

  索引管理

  索引的創建和刪除

  創建和刪除索引的方法有很多種,下面兩個是比較原始的方法,通過對system.indexes這個collection進行相應的寫操作來完成索引的創建:

  spec = {ns: "green.users", key: {‘addresses.zip’: 1}, name: ‘zip’}
  db.system.indexes.insert(spec, true)

  上面命令往system.indexes中寫入一條記錄來創建索引,這條記錄包含了要在上面創建索引的collection的名字空間,索引的信息,以及索引的名稱。

  創建完成後,我們可以通過下面命令找到我們創建的索引:

  db.system.indexes.find()
  { "_id" : ObjectId("4d2205c4051f853d46447e95"), "ns" : "green.users",
  "key" : { "addresses.zip" : 1 }, "name" : "zip", "v" : 0 }

  要刪除一個已創建的索引,我們可以使用下面的命令來實現:

  use green
  db.runCommand({deleteIndexes: "users", index: "zip"})

  創建索引命令

  實際上創建索引還有更方便的命令,那就是ensureIndex,比如我們創建一個open和close兩個字段的聯合索引,就可以用下面的命令:

db.values.ensureIndex({open: 1, close: 1})

  這個命令會觸發索引創建的兩個過程,一個是將相應的字段排序,因爲索引是按B+樹來組織的,要構建樹,將數據進行排序後能夠提高插入B+樹的效率(第二個過程的效率),在日誌中,你能看到和下面類似的輸出:

Tue Jan 4 09:58:17 [conn1] building new index on { open: 1.0, close: 1.0 } for stocks.values
  1000000/4308303 23%
  2000000/4308303 46%
  3000000/4308303 69%
  4000000/4308303 92%
  Tue Jan 4 09:59:13 [conn1] external sort used : 5 files in 55 secs

  第二個過程是將排序好的數據插入到索引結構中,構成可用的索引:

  1200300/4308303 27%
  2227900/4308303 51%
  2837100/4308303 65%
  3278100/4308303 76%
  3783300/4308303 87%
  4075500/4308303 94%
  Tue Jan 4 10:00:16 [conn1] done building bottom layer, going to commit
  Tue Jan 4 10:00:16 [conn1] done for 4308303 records 118.942secs
  Tue Jan 4 10:00:16 [conn1] insert stocks.system.indexes 118942ms

  除了日誌中的輸出外,你還可以通過在終端執行currentOp命令來獲取當前操作線程的相關信息,如下例:

  > db.currentOp()
  {
  "inprog" : [
  {
  "opid" : 58,
  "active" : true,
  "lockType" : "write",
  "waitingForLock" : false,
  "secs_running" : 55,
  "op" : "insert",
  "ns" : "stocks.system.indexes",
  "query" : {
  },
  "client" : "127.0.0.1:53421",
  "desc" : "conn",
  "msg" : "index: (1/3) external sort 3999999/4308303 92%"
  }
  ]
  }

  最後一部分就是一個索引構建過程,目前正在執行排序過程,執行到92%。

  在後臺創建索引

   創建索引會對數據庫添加寫鎖,如果數據集比如大,會將線上讀寫數據庫的操作掛起,以等待索引創建結束。這影響了數據庫的正常服務,我們可以通過在創建索 引時加background:true 的選項,讓創建工作在後臺執行,這時候創建索引還是需要加寫鎖,但是這個寫鎖不會直接獨佔到索引創建完成,而是會暫停爲其它讀寫操作讓路,不至於造成嚴重 的性能影響。具體方法:

db.values.ensureIndex({open: 1, close: 1}, {background: true})

  離線創建索引

   無論如何,索引的創建都會給數據庫造成一定的壓力,從而影響線上服務。如果希望創建索引的過程完全不影響線上服務,我們可以通過將replica sets中的節點先從集羣中剝離,在這個節點上添加相應的索引,等索引添加完畢後再將其添加到replica sets中。這只需要保證一個條件,就是創建索引的時間不能長於oplog能夠保存日誌的時間,否則創建完後節點再上線發現再也無法追上primary 了,這時會進行resync操作。

  索引備份

  我們知道,無論是使用mongodump還是mongoexport命令,都只是對數據進行備份,無法備份索引。我們在恢復的時候,還是需要等待漫長的索引創建過程。所以,如果你希望備份的時候帶上索引,那麼最好採用備份數據文件的方式。

  索引壓縮

  索引在使用一段時間後,經歷增刪改等操作,會變得比較鬆散,從而戰用不必要的空間,我們可以通過reindex命令,重新組織索引,讓索引的空間佔用變得更小。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章