[ Mongodb ] mongodb基本操作 20160530


// 取得collection建立的索引
db.collection.getIndexes();

// 建立複合式索引,所為不可重複的 (a: ascending,b: ascending)
db.collection.createIndex( { a:1 , b:1 }, { unique: true });

若把{ a:1, b:1 } 改成 { a:-1,b:-1 } 則表示是用descending的方式

sort({ _id: -1 }) =====> sort by created time descending


Mongodb是設計給分散式系統用的


ObjectId
  _id 的預設值就是ObjectId
  ObjectId使用12 bytes儲存, 也就是由24個16進位的數字組成
  第0~ 3 個bytes -> timestamp
  第4~ 6 個bytes -> Machine
  第7~ 8 個bytes -> PID
  第9~11個bytes -> Increment
  由於ObjectId前面是由timestamp組成, ObjectId可以大約當成是塞入的順序

Mongoshell
  你可以將shell javascript傳給mongoshell去執行
  $ mongo script1.js script2.js script3.js

Updating
  一般Mongodb使用update時,是將整筆資料給取代
  若想只更新部分的欄位,必須使用$set來更新
  想移除某個欄位,使用$unset

  遞增
  $inc: { 欄位: 增加的數字 }
  ex:  $inc: { $pageView: 1 } // 遞增1

  $push
  ex:
  原本的資料長這樣
  {
    "_id" : ObjectId("4b2d75476cc613d5ee930164"), "title" : "A blog post",
    "content" : "...",  
    "comments" : [
      { "name" : "joe",
        "email" : "joe@example.com",
        "content" : "nice post."
      }
    ]
  } 
  如果想在comments內新
 增其他的物件,可使用$push
  {"$push" :
        {
           "comments" :
          {"name" : "bob", "email" : "bob@example.com", ... "content" : "good post."}
        }
  }
 結果如下
  {
    "_id" : ObjectId("4b2d75476cc613d5ee930164"),
    "title" : "A blog post",
    "content" : "...",
    "comments" : [
        { "name" : "joe",
          "email" : "joe@example.com",
          "content" : "nice post." },
       { "name" : "bob",
         "email" : "bob@example.com",
         "content" : "good post." }

     ]
  }
 其他的還有 $addToSet, $addToSet + $each ..
 請自行參閱:https://docs.mongodb.com/manual/reference/operator/update/push/

  Upsert
    簡單說就是更新某個條件時, 如果該條件可以找得到資料, 就更新該筆
    找不到該筆的話, 就新增進去資料庫中
    必須使用 $setOnInsert
    ex:
       db.products.update( { 
               _id: 1 
       }, {
              $set: { 
                 item: "apple" 
              }, 
             $setOnInsert: { 
                defaultQty: 100 
             } 
       }, { upsert: true } );
   
   findAndModified
     如果需要更新後並得到該筆資料, 如果使用upsert更新之後再拿_id取得該筆資料
     效能不如使用findAndModified來得好
     
     db.collection.findAndModify({
             query: <document>,         // 用來查詢想要選取的資料
             sort: <document>,             // 將取得的資料排序
             remove: <boolean>,         // *必填 決定被選取的資料是否要被刪除
             update: <document>,     // *必填 可使用這些 modifiers來更新資料
             new: <boolean>,               // true: 返回被修改後的資料, false: 原本沒被改過的資料
             fields: <document>,          // 選擇哪些欄位要出現 { field1: 1, field:2 .. }
             upsert: <boolean>,            // 與update欄位連動的欄位, 如果為true時, 當query找不到資料時, 自動新增一筆資料進去, 預設為false
             bypassDocumentValidation: <boolean>, // true: 可以在更新的時候不會遇到資料驗證的請求
             writeConcern: <document> // A document expressing the write concern. Omit to use the default write concern
         });
詳情請見: FindAndModified

Write Concern
  當新增/刪除/查詢/修改 資料的時候, 我們都會關心這次的操作是否成功. 基本上預設是都會回傳是否成功,但對於某些資料並不是那麼重要的資料: logs, bulk data loading等, 就不需要知道這些了. 
  基本的兩個write concern: 
  • acknowledged 
    • 新增/刪除/查詢/修改
  • unacknowledged
    • ex: logs, bulk data loading
  雖然unacknowledged不需要回傳database error, 但還是有需求做error checking
  假如sockert斷了或是寫入時發生錯誤, 仍然會造成例外處理
  ex: 
    > db.foo.insert({"_id" : 1})
    > db.foo.insert({"_id" : 1}) 
    E11000 duplicate key error index: test.foo.$_id_ dup key: { : 1.0 }
  已經大改版, 新版的請參考這裡 

   





留言

這個網誌中的熱門文章

[翻譯] 介紹現代網路負載平衡與代理伺服器

[MySQL] schema 與資料類型優化