繁体   English   中英

mongodb - 带有nodejs的上限集合

[英]mongodb - capped collections with nodejs

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

我的问题:

  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()似乎不能很好地与节点一起使用。

关于有关上限集合并自动创建它们的问题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()在集合中查找文档,但这不一定是第一个或最后一个。 如果要保证第一个或最后一个,可以使用sort()limit()运行find() 1.按_id升序排序应该为您提供第一个文档。 更多信息在这里

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

最后,对于问题6,您只需将$set运算符与update()方法一起使用即可。 更多信息在这里

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

请注意,您只能为封顶集合更新文档,因此您无法插入您提到的额外字段。 您可能希望了解此处列举的其他限制。

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

如果要更新第一个或最后一个文档中的嵌套字段(分别在排序中使用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"不一定有效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM