Javascript mongodb-带nodejs的封顶集合

Javascript mongodb-带nodejs的封顶集合,javascript,node.js,mongodb,native,capped-collections,Javascript,Node.js,Mongodb,Native,Capped Collections,我正在尝试使用Node.js(使用本机MongoDB驱动程序)在MongoDB中设置和更新一些capped集合。 我的目标是,在运行app.js时,将文档插入到一个capped集合中,并更新capped集合中的现有文档。这两个都在setInterval()上运行,所以每隔几秒钟 我的问题是: 如果集合不存在,我想创建一个集合,但如果存在,我想在其中插入一个文档。正确的检查方法是什么 对于capped集合,我甚至应该在插入任何内容之前先显式地创建它们吗?通常情况下,我相信您可以直接将内容插入到集合

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

我的问题是:

  • 如果集合不存在,我想创建一个集合,但如果存在,我想在其中插入一个文档。正确的检查方法是什么
  • 对于capped集合,我甚至应该在插入任何内容之前先显式地创建它们吗?通常情况下,我相信您可以直接将内容插入到集合中,而无需先显式创建它们,但在这种情况下,我需要确保它们是有上限的。一旦封顶集合存在,我就知道如何向其中插入新文档,问题是我需要某种方法来处理第一次使用的应用程序(在新服务器上),而该应用程序并不存在集合,我希望使用节点进行创建,而不必跳入mongo cli
  • 这里的诀窍是需要对集合进行封顶,因此我可以执行如下操作:
    db.createCollection(“collectionName”,{capped:true,size:100000,max:5000})
    。这将为我创建capped集合,但每次我调用它时,它都会调用
    createCollection()
    ,而不是更新或插入-如果我调用
    createCollection()
    ,一旦集合已经存在,它会完全覆盖现有集合吗
  • 另一种方法是使用以下命令将集合转换为有上限的集合:
    db.runCommand({“convertToCapped”:“collectionName”,大小:100000,最大值:5000})。问题是节点没有将
    runCommand()
    视为有效函数,因此会出错。我还想打电话给其他人让它工作吗?它在mongo cli中工作,但不在节点中工作
  • 您使用什么类型的查询来查找集合中的第一个文档?同样,在mongo cli中,我可以对一些查询使用
    db.collections.find()
    ,但在节点中,它声明
    find()
    不是有效的函数
  • 如何使用
    collection.update()
    向现有文档添加一些新字段?假设文档是一些简单的对象,比如
    {key1:“value”,key2:“value”}
    ,但是我有一个包含
    {key3:“value”}
    的对象。当前文档中不存在键3,如何将其添加到当前存在的内容中?这在某种程度上与上面的#4有关,因为我不确定传递什么作为查询参数,因为
    find()

  • 关于你的问题1-4关于封顶集合和自动创建它们,有几种方法可以做到这一点。一方面,您可以运行一个脚本来初始化数据库,这样当您第一次运行数据库时,它就可以为您的客户机提供有上限的集合。另一方面,在插入文档之前,可以检查给定集合中是否有文档。如果有,只需插入文档,如果没有,则创建capped集合,然后将文档作为对该函数的回调插入。它的工作原理如下:

    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;             
                });
            }
    
        });
    });
    
    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);    
        });
    });  
    
    关于问题5,您可以使用
    findOne()
    在集合中查找文档,尽管这不一定是第一个或最后一个文档。如果要保证第一个或最后一个,可以运行
    find()
    ,其中
    sort()
    limit()
    的值为1。按
    \u id
    升序排序应为您提供第一个文档。更多信息

    最后,对于问题6,您只需将
    $set
    操作符与
    update()
    方法一起使用。更多信息

    请注意,您只能在适当的位置为封顶集合更新文档,因此无法插入您提到的额外字段。您可能需要注意列举的其他限制

    [编辑:在上一个文档中添加更新嵌套字段。]

    如果要更新第一个或最后一个文档中的嵌套字段(在排序中分别使用1或-1),可以获取文档,提取
    \u id
    ,然后对该文档执行原子更新。大概是这样的:

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

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

    谢谢。我在这里尝试了一些想法,到目前为止它们都很有效。关于文档更新:我真正想做的是更新集合中的第一个文档。那么您对{“foo”:1}的查询,我如何替换它以使查询返回第一个文档呢?我有一个在我看来似乎很奇怪的问题:我有一个对象,看起来像
    dataObject={“timeCollected”:3432547,“publicIP”:{“ip”:“xx.xxx.xx.xx”}(…加上许多其他的)}
    。然后我将一些值从那里拉入一个新对象:
    systemInfo={“timeCollected”:dataObject.timeCollected,“publicIP”:dataObject.publicIP.ip,}
    。我想更新现有文档中的timeCollected和publicIP字段(这两个字段最初在文档中都设置为0)。我使用类似于
    collection.update(查询,{“$set”:systemInfo},函数(err,result){}
    ,但这两个字段都不会更新。奇怪的是,如果我只尝试更新timeCollected,那么它可以正常工作,但是尝试同时更新这两个字段都不会工作,也不会单独更新publicIP,尽管如果我将对象更改为
    systemInfo={“timeCollected”:55,“publicIP”:5}
    然后这两个字段都会更新。因此这似乎与从一个nes中提取值有关