2015-02-23 49 views
4

我試圖使用Node.js(使用本地MongoDB驅動程序)在MongoDB中設置和更新某些加蓋的集合。 我的目標是,在運行app.js時,將文檔插入到加蓋集合中,並更新封頂集合中的現有文檔。這兩個都在setInterval()上運行,所以每隔幾秒鐘。mongodb - 使用nodejs加蓋的集合

我的問題:

  1. 我想創建一個集合,如果集合不存在,但如果這樣做我想將文檔插入它來代替。什麼是檢查這個的正確方法?
  2. 帶上限的集合,我應該甚至在插入任何內容之前先明確地創建它們?通常我相信你可以插入一些東西到一個集合中而不用明確地創建它們,但在這種情況下,我需要確保它們被封閉。一旦封頂的集合存在,我知道如何插入新的文檔,問題是我需要某種方式來處理第一次使用的應用程序(在一個新的服務器上),集合尚不存在,我想使用節點來做這個創建,而不必跳進mongo cli。
  3. 這裏的訣竅是收藏需要封頂,所以我可以做類似於:db.createCollection("collectionName", { capped : true, size : 100000, max : 5000 })。這將爲我創建封頂集合,但每次我打電話時它都會調用createCollection()而不是更新或插入 - 如果我調用createCollection(),一旦集合已經存在,是否會完全覆蓋現有集合?
  4. 另一種方法是將集合變爲帶上限的集合:db.runCommand({"convertToCapped": "collectionName", size: 100000, max : 5000 });。問題在於節點不會將runCommand()看作是有效的函數,並且是錯誤的。有沒有其他的東西,我打算叫這個工作?它在mongo cli中工作,但不在節​​點內
  5. 您使用什麼類型的查詢來查找集合中的第一個文檔?再次,在mongo cli中,我可以使用db.collections.find()進行某些查詢,但在節點內指出find()不是有效函數
  6. 如何使用collection.update()將一些新字段添加到現有文檔?可以說文檔是一些簡單的對象,如{key1: "value", key2: "value"},但我有一個包含{key3: "value"}的對象。關鍵3在當前文檔中不存在,我如何將它添加到當前存在的?這與上面#4有些相關,因爲我不確定傳入find()似乎不能很好地與節點一起查詢參數。

回答

3

關於你的問題1 - 4關於封頂集合和自動創建它們,有幾種方法可以做到這一點。一方面,您可以運行一個腳本來初始化您的數據庫,以便它在第一次運行時爲您的客戶端提供可用的上限集合。另一方面,您可以在插入文檔之前查看給定集合中是否有任何文檔。如果存在,則只需插入文檔,如果不存在,則創建封頂集合,然後將該文檔作爲回調插入到該函數中。它的工作是這樣的:

var host = "localhost", 
port = 27017, 
dbName = "so"; 

var MongoClient = require('mongodb').MongoClient, Server = require('mongodb').Server; 
var mongoclient = new MongoClient(new Server(host, port)); 
var db = mongoclient.db(dbName); 

db.open(function(err, db) { 

    if(err) throw err; 

    // Capped collection. 
    var capped = db.collection('capped'); 

    // Document to be inserted. 
    var document = { "foo": 1, "bar": 1 } 

    capped.find().count(function(err, count) { 

     if(err) throw err; 

     if (count === 0) {   
      console.log("Creating collection..."); 
      db.createCollection("capped", 
           { "capped": true, 
            "size": 100000, 
            "max": 5000 }, 
           function(err, collection) { 
       if(err) throw err;    

       // Insert a document here. 
       console.log("Inserting document..."); 
       collection.insert(document, function(err, result) { 
        if (err) throw err;     
       }); 
      }); 

     } else { 

      // Insert your document here without creating collection. 
      console.log("Inserting document without creating collection..."); 
      capped.insert(document, function(err, result) { 
       if (err) throw err;    
      }); 
     } 

    }); 
}); 

關於第5個問題,你可以使用findOne()找到集合中的文檔,雖然這不一定是第一個或最後。如果要保證第一個或最後一個,您可以運行find(),其中sort()limit()爲1.按_id排序應該會給出第一個文檔。更多信息here

// Sort 1 for ascending, -1 for descending. 
capped.find().sort([["_id", 1]]).limit(1).nextObject(function(err, item) { 
    console.log(item); 
}); 

最後的問題6,你只需要使用$set運營商與update()方法。更多信息here

capped.update({ "foo": 1 }, { "$set": { "bar": 2 } }, {}, function(err, result) { 
    console.log(result); 
}); 

請注意,您只能更新到位證件加蓋集合,所以你不能做你所提到的額外字段的插入。列出的其他限制here您可能想知道。

[編輯:添加更新嵌套領域最後文件]

如果你想第一個或最後一個文檔中更新一個嵌套的字段(使用1或-1排序,分別),您可以獲取該文檔提取_id,然後對該文檔執行原子更新。事情是這樣的:

capped.find().sort([["_id", -1]]).limit(1).nextObject(function(err, item) {  
    if(err) throw err; 
    capped.update({ "_id": item._id }, 
       { "$set": { "timeCollected": 15, "publicIP.ip" : "127.0.0.1" }}, 
       function(err, result) { 

     if(err) throw err; 
     console.log(result);  
    }); 
}); 

注意更新存在一個上限集合中的文檔在一個領域,即使,你要確保新的價值分配給文件的空間適合。因此,例如,將字符串值從"1"更新爲"127.0.0.1"不一定有效。

+0

謝謝。我在這裏嘗試了一些想法,迄今爲止他們都一直在努力。關於文檔更新:我真的想要更新集合中的第一個文檔。因此,您對{「foo」:1}的查詢,我該如何替換,以便查詢返回第一個文檔? – Simon 2015-02-24 03:19:07

+0

我有什麼似乎是一個奇怪的問題:我有一個對象,看起來像'dataObject = {「timeCollected」:3432547,「publicIP」:{「ip」:「xx.xxx.xx.xx」} (......加上其他許多人)}'。然後我從那裏抽取一些值到一個新對象中:'systemInfo = {「timeCollected」:dataObject.timeCollected,「publicIP」:dataObject.publicIP.ip,}'。我想更新我現有文檔中的timeCollected和publicIP字段(最初,這兩個字段在文檔中都設置爲0)。 – Simon 2015-02-24 03:59:06

+0

我使用類似'collection.update(query,{「$ set」:systemInfo},function(err,result){}',但這兩個字段都沒有更新。奇怪的是,如果我只嘗試更新timeCollected,很好,但試圖更新兩者都不行,也不會自行更新publicIP – Simon 2015-02-24 03:59:36