Javascript Node.js mongodb驱动程序异步/等待查询
我有一个使用mongodb本机驱动程序的node.js应用程序。 在使用NodeV8.9.1将应用程序代码迁移到async/await的过程中,我正在努力为mongodb查询找到一种优雅的方法。 mongodb驱动程序的主要问题是,所有查询都使用回调,而异步方法必须使用承诺函数 备选方案:Javascript Node.js mongodb驱动程序异步/等待查询,javascript,node.js,mongodb,mongoose,async-await,Javascript,Node.js,Mongodb,Mongoose,Async Await,我有一个使用mongodb本机驱动程序的node.js应用程序。 在使用NodeV8.9.1将应用程序代码迁移到async/await的过程中,我正在努力为mongodb查询找到一种优雅的方法。 mongodb驱动程序的主要问题是,所有查询都使用回调,而异步方法必须使用承诺函数 备选方案: mongoose-承诺不推荐使用查询,它强制使用模式模型,这对我的应用程序来说有点开销 mongoist-据说很棒,因为它在构建时考虑了异步/等待,并且完全承诺,但是与mongodb的SSL连接错误和糟糕的
- mongoose-承诺不推荐使用查询,它强制使用模式模型,这对我的应用程序来说有点开销李>
- mongoist-据说很棒,因为它在构建时考虑了异步/等待,并且完全承诺,但是与mongodb的SSL连接错误和糟糕的文档-让我远离了这个解决方案李>
对于优雅的高性能方式有什么新的想法吗 如果您没有通过回调,mongodb客户端将返回一个承诺 官方的MongoDB Node.js驱动程序提供了基于回调和承诺的与MongoDB的交互,允许应用程序充分利用ES6中的新功能 从官方
谢谢。与ES6配合得很好:
const middleWare = require('middleWare');
const MONGO = require('mongodb').MongoClient;
router.get('/', middleWare(async (req, res, next) => {
const db = await MONGO.connect(url);
const MyCollection = db.collection('MyCollection');
const result = await MyCollection.find(query).toArray();
res.send(result);
}))
如果希望在不卸载到数组的情况下使用游标,则不能将wait与find()或aggregate()函数一起使用,则必须使用以下代码: UPD由美国邮政提供: 对于一般情况,使用toArray()的答案就足够了 但是当涉及到巨大的文档集合时,使用toArray()将超过可用的RAM。因此,在这些情况下,“高性能”解决方案不得使用toArray() 对于这些情况,您可以使用MongoDB streams,它工作得很好,但比使用streams更简单的是:
const cursor = db.collection('name').aggregate(
[
{
"$match": {code: 10}
},
{
"$count": "count"
}
],
{
"allowDiskUse": false
}
)
for (let doc = await cursor.next(); doc != null; doc = await cursor.next()) {
console.log('aggregate:', doc.count);
}
const cursor = db.collection('someCollection').find({})
for (let doc = await cursor.next(); doc; doc = await cursor.next()) {
// Process the document.
}
编辑:“mongodb”v3.x 据 你可以用这种方式
让MongoClient=require('mongodb')。MongoClient;
常量连接字符串=mongodb://localhost:27017';
(异步()=>{
让客户端=等待MongoClient.connect(connectionString,
{useNewUrlParser:true});
设db=client.db('dbName');
试一试{
const res=await db.collection(“collectionName”).updateOne({
“someKey”:someValue
},{$set:someObj},{upsert:true});
log(`res=>${JSON.stringify(res)}`);
}
最后{
client.close();
}
})()
.catch(err=>console.error(err));
我将此作为答案发布,因为我无法对此发表评论。我一到50岁就会提出这个问题
不要忘记关闭数据库连接。否则,您的应用程序可能无法连接到数据库,因为打开的连接太多(一周前发生在我身上)
您的查询可能成功或失败,因此在finally
块中关闭连接是有意义的
const db = await MongoClient.connect(url);
try {
const stuff = await db.collection("Stuff").find({});
// Do something with the result of the query
} finally {
db.close();
}
更新:这似乎也没有解决我的问题。有些人说你甚至不需要手动关闭连接。如果可能的话,最好在整个应用程序中重用您的连接
使用异步/等待的mongoose查找查询
var router = require("express").Router()
var mongoose = require("mongoose")
var await = require("await")
var async = require("async")
var mongoUrl = "mongodb://localhost:27017/ekaushalnsdc"
router.get("/async/await/find",async(req, res, next) => {
try {
var db = await mongoose.createConnection(mongoUrl)
var colName = db.collection('collectionName')
var result = await colName.find({}).toArray()
res.json(result)
}catch(ex) {
res.json(ex.message)
}
})
在异步/等待的情况下,不要使用mongoose.connect
var router = require("express").Router()
var mongoose = require("mongoose")
var await = require("await")
var async = require("async")
var mongoUrl = "mongodb://localhost:27017/ekaushalnsdc"
router.get("/async/await/find",async(req, res, next) => {
try {
var db = await mongoose.createConnection(mongoUrl)
var colName = db.collection('collectionName')
var result = await colName.find({}).toArray()
res.json(result)
}catch(ex) {
res.json(ex.message)
}
})
这是我发现的与Mongo3和async/await兼容的最小代码段。 享受吧 (基于Pax Beach的答案。它被否决了,我想添加一条评论,解释为什么在某些情况下,Pat的答案是最好的。我没有足够的代表添加评论。) 对于一般情况,使用toArray()的答案就足够了 但是当涉及到庞大的文档集合时,使用toArray()将超过可用的RAM。因此,在这些情况下,“高性能”解决方案不得使用toArray() 对于这些情况,您可以使用MongoDB streams,它工作得很好,但比使用streams更简单的是:
const cursor = db.collection('name').aggregate(
[
{
"$match": {code: 10}
},
{
"$count": "count"
}
],
{
"allowDiskUse": false
}
)
for (let doc = await cursor.next(); doc != null; doc = await cursor.next()) {
console.log('aggregate:', doc.count);
}
const cursor = db.collection('someCollection').find({})
for (let doc = await cursor.next(); doc; doc = await cursor.next()) {
// Process the document.
}
由于所有答案都缺少一些位(catch块,检查客户机是否为
null
),因此我提供了自己的解决方案。使用Mongo服务器v4.0.7和节点JS驱动程序3.2.2进行测试
请注意,该示例是一个控制台程序,我们在finally
块中关闭与服务器的连接。在web应用程序中,连接被重用。
看见此外,这些错误是通过Winston或Morgan等库记录的,而不是控制台记录的
const MongoClient = require('mongodb').MongoClient;
const url = 'mongodb://localhost:27017';
async function findOne() {
const client = await MongoClient.connect(url, { useNewUrlParser: true })
.catch(err => { console.log(err); });
if (!client) {
return;
}
try {
const db = client.db("testdb");
let collection = db.collection('cars');
let query = { name: 'Volkswagen' }
let res = await collection.findOne(query);
console.log(res);
} catch (err) {
console.log(err);
} finally {
client.close();
}
}
await findOne();
我正在尝试使用mongojs从mongodb获取数据,并在graphiql服务器中显示。我用承诺,终于得到了
async resolve(parent,args){
function getdata(){
return new Promise(function(resolve,reject){
var o_id = ObjectId(args.id);
var obj = {_id:o_id}
db.book.find(obj,(err,data) => {
if(err){
console.log(err);
reject("error in sending the book data");
}
else{
if(data.length>0){
resolve(data);
}else{reject("data length is ! > 0")}
}
});
})
}
async function calldata(){
var dataNew = await getdata().then(function(returnedData){
return returnedData;
}).catch(function(errorinpassing){
console.log(errorinpassing);
})
return dataNew
}
var hello = await calldata()
if(hello.length>0){
return hello[0]
}
}
我来这里是为了
async/await
解决方案,但我并不喜欢任何答案,所以我想出了下面的代码片段
我使用的是本机驱动程序,效果很好。我发现它比for
循环更具可读性:
const cursor=await db.collection('myCollection').find({});
while(等待cursor.hasNext()){
const doc=wait cursor.next();
//做什么都行。
控制台日志(doc);
};
toArray()
方法也可以,但正如前面指出的那样,您必须确保永远不会得到占用RAM的大型结果集。@MikaS is似乎需要一个“co”包。我基本上是在寻找一个充满希望的本土图书馆这是一个很好的答案。对于任何试图找出require('middleware')
步骤的人来说,这里有一个很好的指南:这也不起作用了。有更新的机会吗?我忽略了mongodb,现在正在使用mongoose。这是强烈推荐,因为很多更新和承诺支持。这是美丽的,正是我所寻找的。非常感谢。从版本3开始,MongoClient返回的是客户机,而不是db对象!这不管用了。我们可以获得mongodb最新版本的更新吗?假设我们在调用的函数中调用了3个以上的函数