mongodb 插入之后怎样获取id
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mongodb 插入之后怎样获取id相关的知识,希望对你有一定的参考价值。
我在mongodb中插入了一条记录,怎么获取这条记录的_id号,_id是自动生成的,插入的记录不是唯一的,只有自动生成的_id是唯一的。所以不能先插入之后,再去find。坐等结果。。
参考技术A 你可以自己指定_id 不用让mongo自动生成 参考技术B 两种方式提供你生成自增ID:第一种:使用IdGenerator属性,并在Bson特性上进行指定。
第二种:自增id生成器。这个需要你自己写代码来实现,原则是1个集合对应1个自增序列,并使用MongoShell自带的$inc进行原子自增操作(更新后再获取FindAndModify)。
根据你的需求,你应该当选择第二种方法。可以利用反射将每一个实体类对应的集合去让其自动生成自增集合;或者由一个集合容器来统一管理所有需要自增的集合的自增序列。本回答被提问者采纳 参考技术C 我也遇到这个问题,能否帮忙说一下怎么实现的,谢谢
Node.js | MongoDB count():在插入数据之前和之后获取计数
【中文标题】Node.js | MongoDB count():在插入数据之前和之后获取计数【英文标题】:Node.js | MongoDB count(): Getting Count Before and After Inserting Data 【发布时间】:2017-01-21 16:37:02 【问题描述】:我正在尝试获取数据库中的项目计数以确认数据插入成功。
-
插入前获取计数
插入
插入后获取计数
Console.log 总结
注意:我知道这可以使用一些简单的函数来实现:
dbName.equal(insertSize, result.insertedCount)
但是,我是 javascript 新手,我想我遇到了实现异步回调的需要,所以我想弄清楚这一点。
插入函数
var insertMany = function()
// get initial count
var count1 = getDbCount();
// Insert new 'data'
MongoClient.connect(url, function(err, db)
var col = db.collection(collectionName);
col.insert(data, w:1, function(err,result) );
db.close();
);
/** This needs to be implemented through next/callback
after the insert operation **/
var count2 = getDbCount();
/** These final console logs should be executed after all
other operations are completed **/
console.log('[Count] Start: ' + count1 + ' | End:' +count2);
console.log('[Insert] Expected: ' + data.length + ' | Actual: ' + (count2 - count1));
;
获取数据库计数函数
var getDbCount = function()
MongoClient.connect(url, function(err, db)
if (err) console.log(err);
var col = db.collection(collectionName);
col.count(, function(err, count)
if (err) console.log(err);
db.close();
console.log('docs count: ' + count);
// This log works fine
);
);
return count; // this is returning as undefined since this is
// executing before the count operation is completed
;
我收到错误,因为在所需操作完成之前发生退货。
感谢您的帮助。
[EDIT] 带有 Promise 的 getCount 函数
我已将承诺添加到 getCount 函数作为开始:
var getCount = function()
var dbCount = 0;
var promise = new Promise(function(resolve, reject)
MongoClient.connect(url, function(err, db)
if (err)
console.log('Unable to connect to server', err);
else
console.log('Database connection established:' + dbName);
// Get the collection
var col = db.collection(collectionName);
col.count(, function(err, count)
if (err) console.log(err);
db.close();
console.log('docs count: ' + count);
resolve(null);
dbCount = count;
);
);
);
promise.then(function()
return dbCount;
);
;
console.log(getCount());
输出仍然是: 不明确的 建立数据库连接:testdb 文档数:500
then(return count) 代码仍然在 promise db.count() 之前执行。在数据库操作完成之前返回 undefined。
【问题讨论】:
如果你不展示你尝试过的东西,就很难说出你做错了什么。该错误应该带有一些关于错误发生在哪一行的信息。提供发生错误的代码块以及至少调用它的部分 嗨 newBee,我已经把它拿出来了。我在通过回调实现方面没有取得太大进展,这就是我没有包含它的原因。如果我取得进展,我将更新并添加新代码。谢谢 @CarloP.LasMarias 你永远不应该选择setTimeout
。有很多文章专门在后端解释了该功能的暴行。 Promise 是为处理此类情况而开发的模块,如果它不起作用,则问题出在代码中,需要解决。 Async.js 是另一个比 setTimeout
更好的选择。
【参考方案1】:
一般来说,您遇到的问题是您希望函数返回时该值已经存在。对于异步函数,情况通常并非如此。有大量关于异步处理的信息(不要与 Java 中的并行处理相混淆)。
我创建了一个适合您情况的示例:
https://jsfiddle.net/rh3gx76x/1/
var dummyCount = 5
getCount = function()
return new Promise(function(resolve, reject)
setTimeout(function() // this would be your db call, counting your documents
resolve(dummyCount); // dummy for number of documents found
, 100 * Math.random());
);
;
insertMany = function()
return new Promise(function(resolve, reject)
setTimeout(function() // this would be your db call, writing your documents
dummyCount += 2;
resolve();
, 100 * Math.random());
);
;
runIt = function(callback)
var count1;
getCount().then(function(count)
console.log("First callback with value ", count);
count1 = count;
insertMany().then(function()
getCount().then(function(count2)
console.log("Second callback with value ", count2);
callback(null, count1, count2);
);
)
)
runIt(function(err, count1, count2)
console.log("count1: " + count1 + ", count2: " + count2);
);
最后一件事。您可能想查看“异步”包。提供大量辅助函数和控制流的东西,这对解决这些问题有很大帮助。
【讨论】:
setTimeout
是一种糟糕的做法。不建议专门在 I/O 任务中使用超时。您通过随机延迟代码来消耗时间。这会在开发复杂网站时消耗您的资源。
@Ritik Saxena 此处的超时只是替换原始海报制作的数据库调用,使示例更易于阅读。无法在您也没有提到的资源问题上关注您。将代码延迟到下一个事件循环滴答声并不少见。尽管您当然会始终使用“0”超时。
@newBee 通过使用 setTimeout 代替 db 调用以使示例更易于阅读,我希望您并不是说添加它是为了使示例更具可读性,没有任何其他目的。你是否?此外,reject
用于传递 promise 中的错误,这些错误在 catch 语句中处理。因此,您可能需要编辑注释 null = no error
,因为此处的 null 表示代码没有任何内容可传递给 then
。
@newBee 我不完全明白你为什么使用超时。实际上,超时在后端是一种不常见的做法。在这种情况下,您的代码可能会起作用,但是在程序读取/写入数据库所花费的时间取决于数据库大小的情况下,您将设置一个随机的超时时间并希望最好的发生。因此,您的代码可能在这里可以工作,但这并不是一个始终遵循的好习惯。
@RitikSaxena 写了你的第一个回复:调用 runIt 函数时我没有回传 Promise。您误解了程序的流程。一般来说,使用承诺或回调方法是一个偏好问题。这里的超时只是为了模拟任何异步操作(例如磁盘 IO 或 DB 调用),因此提供了一个更通用的示例。 w.r.t 你的第二个问题:有些用例需要那些(或类似的函数,如 setImmediate)。例如。一次调用大量回调时。这可能会导致stack overflow
错误。【参考方案2】:
在操作完成之前就发生返回的原因是nodejs的asynchronous
设计,继承自javascript。来自Mongoose.connect()
的回调将在程序向前移动并遇到return
时进行操作。
您尚未提供使您进入错误声明的解决方法,因此我无法评论您在那里做错了什么。但是,考虑到您首先要完成您开始的工作,确保Mongoose.connect()
完成然后执行return 语句的最佳方法是使用JavaScript 的promise。使用 Promise 将使您的 Mongoose.connect()
执行,然后将控制权传递给 return 语句。
您的代码将类似于:
插入函数:
var insertMany = function()
// get initial count
var count1 = getDbCount();
// Insert new 'data'
var promise = new Promise(
function(resolve,reject)
MongoClient.connect(url, function(err, db)
var col = db.collection(collectionName);
col.insert(data, w:1, function(err,result) );
db.close();
resolve(null);
);
);
promise.then(function(val)
var count2 = getDbCount();
/** These final console logs should be executed after all
other operations are completed **/
console.log('[Count] Start: ' + count1 + ' | End:' +count2);
console.log('[Insert] Expected: ' + data.length + ' | Actual: ' + (count2 - count1));
);
同样,您可以将 promise 添加到 GetDB
函数。
执行 Promise 时的关键点是:
then()
包含了 promise 执行后要同步执行的部分函数。被resolve
调用,传入的参数在catch
函数的回调中接收。
catch()
包含在 Promise 中遇到错误时调用的函数部分。由reject
调用,传入的参数在catch
函数的回调中接收。
编辑:promise 的替代品是async.js,唯一的区别在于它是一个外部模块,与promise 不同。
【讨论】:
请注意,此代码仍然会失败。 count2 将具有值“未定义” @newBee 在我写完代码之后,我提到GetDB
也必须以这种方式执行。然后,count 就会有一个值返回给 count2。
谢谢@RitikSaxena,我试过了,但仍然遇到同样的错误。即使在添加了 Promise 之后,then 语句仍然在 Promise 之前执行。我已经在修改后的 getCount 上面添加了。
@CarloP.LasMarias 您正在调用resolve
,然后为dbCount
赋值。所以你的dbCount
永远不会被分配。试试这个:将null
替换为count
在解析中。在then
函数的回调中,接收一个参数并赋值给dbCount
@RitikSaxena 我试过 resolve(count); dbCount = count;,也颠倒了顺序。结果还是一样,dbCount = undefined。以上是关于mongodb 插入之后怎样获取id的主要内容,如果未能解决你的问题,请参考以下文章
在 Mongodb 数组中,有没有办法在特定元素位置之前/之后插入新元素