mongodb - 使用 nodejs 封顶 collections
mongodb - capped collections with nodejs
我正在尝试使用 Node.js(使用本机 MongoDB 驱动程序)在 MongoDB 中设置和更新一些上限 collection。
我的目标是,在 运行 app.js 上,将文档插入上限 collection,并更新上限 collection 中的现有文档。这两个都是 setInterval()
上的 运行,所以每隔几秒。
我的问题:
- 如果 collection 不存在,我想创建一个 collection,但如果存在,我想在其中插入一个文档。检查这个的正确方法是什么?
- 对于上限 collections,我是否应该在向其中插入任何内容之前先显式创建它们?通常我相信你可以直接将东西插入 collection 而无需先显式创建它们,但在这种情况下我需要确保它们被限制。一旦上限 collection 存在,我就知道如何向其中插入新文档,问题是我需要某种方法来处理 collection 不存在的第一次(在新服务器上)使用的应用程序' 已经存在,我想使用 node 进行创建,而不必跳入 mongo cli。
- 这里的技巧是 collection 需要封顶,所以我可以这样做:
db.createCollection("collectionName", { capped : true, size : 100000, max : 5000 } )
。这将为我创建上限 collection,但每次我调用它时它都会调用 createCollection()
而不是更新或插入 - 如果我调用 createCollection()
,一旦 collection 已经存在,它会完全覆盖现有的collection吗?
- 另一种方法是将 collection 变成带上限的:
db.runCommand({"convertToCapped": "collectionName", size: 100000, max : 5000 });
。这个问题是节点没有将 runCommand()
视为有效函数并且它出错了。是否还有其他事情需要我打电话才能让它发挥作用?它在 mongo cli 中工作,但在 node 中不工作
- 您使用什么类型的查询来查找 collection 中的第一个文档?同样,在 mongo cli 中我可以使用
db.collections.find()
进行一些查询,但在节点中它指出 find()
不是有效函数
- 如何使用
collection.update()
向现有文档添加一些新字段?假设文档是一些简单的 object,例如 {key1: "value", key2: "value"}
,但我有一个包含 {key3: "value"}
的 object。当前文档中不存在密钥 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()
在集合中查找文档,但不一定是第一个或最后一个。如果你想保证第一个或最后一个,你可以 运行 a find()
with a sort()
and limit()
of 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);
});
});
请注意,即使在更新上限集合中文档中存在的字段时,您也需要确保新值适合为文档分配的 space。因此,例如,将字符串值从 "1"
更新为 "127.0.0.1"
不一定有效。
我正在尝试使用 Node.js(使用本机 MongoDB 驱动程序)在 MongoDB 中设置和更新一些上限 collection。
我的目标是,在 运行 app.js 上,将文档插入上限 collection,并更新上限 collection 中的现有文档。这两个都是 setInterval()
上的 运行,所以每隔几秒。
我的问题:
- 如果 collection 不存在,我想创建一个 collection,但如果存在,我想在其中插入一个文档。检查这个的正确方法是什么?
- 对于上限 collections,我是否应该在向其中插入任何内容之前先显式创建它们?通常我相信你可以直接将东西插入 collection 而无需先显式创建它们,但在这种情况下我需要确保它们被限制。一旦上限 collection 存在,我就知道如何向其中插入新文档,问题是我需要某种方法来处理 collection 不存在的第一次(在新服务器上)使用的应用程序' 已经存在,我想使用 node 进行创建,而不必跳入 mongo cli。
- 这里的技巧是 collection 需要封顶,所以我可以这样做:
db.createCollection("collectionName", { capped : true, size : 100000, max : 5000 } )
。这将为我创建上限 collection,但每次我调用它时它都会调用createCollection()
而不是更新或插入 - 如果我调用createCollection()
,一旦 collection 已经存在,它会完全覆盖现有的collection吗? - 另一种方法是将 collection 变成带上限的:
db.runCommand({"convertToCapped": "collectionName", size: 100000, max : 5000 });
。这个问题是节点没有将runCommand()
视为有效函数并且它出错了。是否还有其他事情需要我打电话才能让它发挥作用?它在 mongo cli 中工作,但在 node 中不工作
- 您使用什么类型的查询来查找 collection 中的第一个文档?同样,在 mongo cli 中我可以使用
db.collections.find()
进行一些查询,但在节点中它指出find()
不是有效函数 - 如何使用
collection.update()
向现有文档添加一些新字段?假设文档是一些简单的 object,例如{key1: "value", key2: "value"}
,但我有一个包含{key3: "value"}
的 object。当前文档中不存在密钥 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()
在集合中查找文档,但不一定是第一个或最后一个。如果你想保证第一个或最后一个,你可以 运行 a find()
with a sort()
and limit()
of 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);
});
});
请注意,即使在更新上限集合中文档中存在的字段时,您也需要确保新值适合为文档分配的 space。因此,例如,将字符串值从 "1"
更新为 "127.0.0.1"
不一定有效。