[英]mongodb - capped collections with nodejs
I'm trying to set up and update some capped collections in MongoDB using Node.js (using the native MongoDB driver). 我正在尝试使用Node.js(使用本机MongoDB驱动程序)在MongoDB中设置和更新一些上限集合。 My goal is to, upon running app.js, insert documents into a capped collection, and also to update existing documents in a capped collection.
我的目标是,在运行app.js时,将文档插入到上限集合中,并更新上限集合中的现有文档。 Both of these are running on
setInterval()
, so every few seconds. 这两个都在
setInterval()
上运行,所以每隔几秒钟。
My questions: 我的问题:
db.createCollection("collectionName", { capped : true, size : 100000, max : 5000 } )
. db.createCollection("collectionName", { capped : true, size : 100000, max : 5000 } )
。 That will create the capped collection for me, but every time I call it it will call createCollection()
instead of updating or inserting - if I call createCollection()
, once the collection already exists, will it completely overwrite the existing collection? createCollection()
而不是更新或插入 - 如果我调用createCollection()
,一旦集合已经存在,它是否会完全覆盖现有集合? db.runCommand({"convertToCapped": "collectionName", size: 100000, max : 5000 });
db.runCommand({"convertToCapped": "collectionName", size: 100000, max : 5000 });
. runCommand()
as a valid function and it errors. runCommand()
作为有效函数而且它出错。 Is there something else that I'm meant to be calling to get this to work? db.collections.find()
with some query, but within node it states that find()
is not a valid function db.collections.find()
和一些查询,但在节点内它声明find()
不是有效的函数 collection.update()
to add some new fields to an existing document? collection.update()
向现有文档添加一些新字段? Lets say the document is some simple object like {key1: "value", key2: "value"}
but I have an object that contains {key3: "value"}
. {key1: "value", key2: "value"}
但我有一个包含{key3: "value"}
。 Key 3 does not exist in the current document, how would I add that to what currently exists? find()
doesn't seem to play well with node. find()
似乎不能很好地与节点一起使用。 Regarding your questions 1 - 4 about capped collections and creating them automatically, there are several ways to do this. 关于有关上限集合并自动创建它们的问题1 - 4,有几种方法可以做到这一点。 On the one hand, you could run a script to initialise your database so that it has the capped collections available to your client when you run it for the first time.
一方面,您可以运行一个脚本来初始化您的数据库,以便在您第一次运行它时,它可以为您的客户端提供上限集合。 On the other hand, you could have a check to see if there are any documents in the given collection before inserting a document.
另一方面,在插入文档之前,您可以检查给定集合中是否有任何文档。 If there are, you just insert your document and if there aren't, you create the capped collection and then insert the document as a callback to that function.
如果有,您只需插入文档,如果没有,则创建上限集合,然后将文档作为回调插入该函数。 It would work something like this:
它会像这样工作:
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;
});
}
});
});
Regarding question 5, you can use findOne()
to find a document in the collection, though this is not necessarily the first or last. 关于问题5,您可以使用
findOne()
在集合中查找文档,但这不一定是第一个或最后一个。 If you want to guarantee the first or last, you can run a find()
with a sort()
and limit()
of 1. Sorting by _id
ascending should give you the first document. 如果要保证第一个或最后一个,可以使用
sort()
和limit()
运行find()
1.按_id
升序排序应该为您提供第一个文档。 More information here . 更多信息在这里 。
// Sort 1 for ascending, -1 for descending.
capped.find().sort([["_id", 1]]).limit(1).nextObject(function(err, item) {
console.log(item);
});
Finally for question 6, you just use the $set
operator with the update()
method. 最后,对于问题6,您只需将
$set
运算符与update()
方法一起使用即可。 More information here . 更多信息在这里 。
capped.update({ "foo": 1 }, { "$set": { "bar": 2 } }, {}, function(err, result) {
console.log(result);
});
Note that you can only update documents in place for capped collections, so you cannot do the insert of the extra field you mention. 请注意,您只能为封顶集合更新文档,因此您无法插入您提到的额外字段。 There are other restrictions enumerated here that you might want to be aware of.
您可能希望了解此处列举的其他限制。
[EDIT: Add updating nested fields in last document.] [编辑:在上一个文档中添加更新嵌套字段。]
If you want to update a nested field in the first or last document (use 1 or -1 in the sort, respectively), you can fetch the document, extract the _id
, then perform an atomic update on that document. 如果要更新第一个或最后一个文档中的嵌套字段(分别在排序中使用1或-1),则可以获取文档,提取
_id
,然后对该文档执行原子更新。 Something like this: 像这样的东西:
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);
});
});
Note that even when updating a field that exists in a document in a capped collection, you need to ensure that the new value fits in the space allocated for the document. 请注意,即使更新加盖集合中文档中存在的字段,也需要确保新值适合为文档分配的空间。 So, for example, updating a string value from
"1"
to "127.0.0.1"
will not necessarily work. 因此,例如,将字符串值从
"1"
更新为"127.0.0.1"
不一定有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.