mongodb – 用nodejs加盖的集合

我正在尝试使用Node.js(使用本地MongoDB驱动程序)设置和更新MongoDB中的某些封顶集合。 我的目标是,在运行app.js时,将文档插入到加盖的集合中,还要更新封顶集合中的现有文档。 这两个都在setInterval()上运行,所以每隔几秒钟。

我的问题:

  1. 我想创build一个集合,如果集合尚不存在,但如果它我想要插入一个文档,而不是。 什么是正确的方法来检查这个?
  2. 有了capped集合,我甚至应该在插入任何内容之前先明确地创build它们? 通常情况下,我相信你可以直接插入一个集合而不需要明确地创build它们,但是在这种情况下,我需要确保它们是封闭的。 一旦封顶的集合存在,我知道如何插入新的文档,问题是我需要一些方法来处理应用程序正在使用的应用程序(在一个新的服务器上)集合尚不存在,我想使用节点来做这个创build,而不必跳进mongo cli。
  3. 这里的技巧是集合需要被封顶,所以我可以做一些事情: db.createCollection("collectionName", { capped : true, size : 100000, max : 5000 } ) 。 这将为我创build封顶的集合,但每次我调用它都会调用createCollection()而不是更新或插入 – 如果我调用createCollection() ,一旦集合已经存在,它会完全覆盖现有的集合吗?
  4. 另一种方法是将一个集合转换为一个封闭的集合: db.runCommand({"convertToCapped": "collectionName", size: 100000, max : 5000 }); 。 这个问题是节点没有看到runCommand()作为一个有效的function,它的错误。 还有什么别的,我打算叫这个工作? 它在mongo cli中工作,但不在节​​点内
  5. 您使用什么types的查询来查找集合中的第一个文档? 再次,在mongo cli中,我可以使用db.collections.find()和一些查询,但是在节点中它声明find()不是一个有效的函数
  6. 我将如何使用collection.update()将一些新的字段添加到现有的文档? 比方说,文档是一些简单的对象,如{key1: "value", key2: "value"}但是我有一个包含{key3: "value"} 。 关键3在当前文件中不存在,我将如何添加到目前存在的? 这与上面#4有些相关,因为find()似乎不能很好地与节点一起使用,所以我不确定要传入什么查询参数。

关于你的问题1 – 4关于封顶收集和自动创build它们,有几种方法可以做到这一点。 一方面,您可以运行一个脚本来初始化您的数据库,以便在第一次运行时为您的客户端提供可用的上限集合。 另一方面,可以在插入文档之前检查给定集合中是否有任何文档。 如果存在,则只需插入文档,如果没有,则创build封顶的集合,然后将该文档作为callback插入到该函数中。 它会这样工作:

 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()在集合中查找文档,但这不一定是第一个或最后一个。 如果要保证第一个或最后一个,可以使用sort()limit()运行find() 。按_id升序sorting应该为您提供第一个文档。 更多信息在这里 。

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

最后,对于问题6,您只需使用带有update()方法的$set操作符。 更多信息在这里 。

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

请注意,您只能更新用于加盖集合的文档,因此您无法插入您提到的额外字段。 这里列举的其他限制,您可能想知道。

[编辑:添加更新最后一个文档中的嵌套字段。]

如果要更新第一个或最后一个文档中的嵌套字段(分别在sorting中使用1或-1),则可以提取文档,提取_id ,然后对该文档执行primefaces更新。 像这样的东西:

 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); }); }); 

请注意,即使在更新封顶集合中文档中存在的字段时,也需要确保新值适合分配给文档的空间。 因此,例如,将string值从"1"更新为"127.0.0.1"不一定有效。