it-source

Node.jsmongodb 드라이버 비동기/대기 쿼리

criticalcode 2023. 5. 31. 16:02
반응형

Node.jsmongodb 드라이버 비동기/대기 쿼리

mongodb 네이티브 드라이버를 사용하는 node.js 애플리케이션이 있습니다.노드 v8.9.1을 사용하여 애플리케이션 코드를 비동기/대기로 마이그레이션하는 과정에서 mongodb 쿼리를 위한 우아한 방법을 찾는 데 어려움을 겪고 있습니다.mongodb 드라이버의 주요 문제는 모든 쿼리가 비동기 메서드에 대해 약속 함수가 필수인 콜백을 사용한다는 것입니다.

대안:

  • mongoose - 약속 쿼리는 더 이상 사용되지 않으며 내 앱에 약간 오버헤드인 스키마 모델을 사용합니다.
  • mongoist - async/wait를 염두에 두고 완전히 약속을 지키며 구축되었기 때문에 훌륭하다고 주장하지만 mongodb에 대한 SSL 연결 오류와 빈약한 문서가 저를 이 솔루션에서 멀어지게 했습니다.

우아한 방식으로 구현하는 데 성공한 유일한 해결 방법은 콜백 약속 enpm 패키지를 사용하여 mongodb 드라이버 API를 완전히 약속으로 변환하는 것입니다.

우아한 고성능 방법을 위한 새로운 아이디어가 있습니까?

모든 답변에 일부 비트(캐치 블록, 클라이언트 확인)가 누락되어 있지 않습니다.null) 저는 제 나름의 해결책을 가지고 왔습니다.Mongo 서버 v4.0.7 및 Node JS 드라이버 3.2.2를 사용하여 테스트했습니다.

예제는 콘솔 프로그램이며 여기서 서버에 대한 연결을 닫습니다.finally웹 응용 프로그램에서 연결은 재사용됩니다.Node Mongo 문서를 참조하십시오.또한 오류는 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();

편집: 'mongodb' v3.x

mongoDB ES6 future에 따르면 당신은 이 방법을 사용할 수 있습니다;

let MongoClient = require('mongodb').MongoClient;
const connectionString = 'mongodb://localhost:27017';

    (async () => {
        let client = await MongoClient.connect(connectionString,
            { useNewUrlParser: true });

        let db = client.db('dbName');
        try {
           const res = await db.collection("collectionName").updateOne({ 
               "someKey": someValue
           }, { $set: someObj }, { upsert: true });

           console.log(`res => ${JSON.stringify(res)}`);
        }
        finally {
            client.close();
        }
    })()
        .catch(err => console.error(err));

감사합니다. 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);
}))

이것은 Mongo3 및 비동기/대기와 호환되는 가장 작은 코드 조각입니다.맛있게 드세요!

module.exports = {
  myFunction: async (query) => {
    let db, client;
    try {
      client = await MongoClient.connect(process.env.MONGODB_CONNECTION_STRING, { useNewUrlParser: true });
      db = client.db(dbName);
      return await db.collection(collectionName).find(query).toArray();
    } finally {
      client.close();
    }
  }
}

콜백을 통과하지 못하면 mongodb 클라이언트가 약속을 반환합니다.

공식 MongoDB Node.js 드라이버는 애플리케이션이 ES6의 새로운 기능을 최대한 활용할 수 있도록 MongoDB와의 콜백 기반 및 약속 기반 상호 작용을 모두 제공합니다.

공식 문서에서

Array에 언로드하지 않고 커서로 작업하려면 find() 또는 aggregate() 함수를 사용하여 wait를 사용할 수 없습니다. 그러면 코드를 사용해야 합니다.

Usas에 의한 UPD:일반적인 경우 Array()를 사용한 답변으로 충분합니다.

그러나 방대한 문서 수집이 필요한 경우, toArray()를 사용하면 사용 가능한 RAM을 초과하게 됩니다.따라서 이러한 상황에서 "고성능" 솔루션을 어레이()에 사용해서는 안 됩니다.

이러한 경우 MongoDB 스트림을 사용할 수 있습니다. MongoDB 스트림은 잘 작동하지만 스트림을 사용하는 것보다 훨씬 간단합니다.

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);
}

Ido Lev님의 답변에 댓글을 달 수 없어서 답변으로 올립니다.저는 제가 50명의 명성에 도달하는 대로 이것을 옮길 것입니다.

DB 연결을 닫는 것을 잊지 마십시오.그렇지 않으면 응용프로그램이 너무 많은 열린 연결로 인해 DB에 연결할 수 없습니다(1주일 전에 저에게 발생).

수도 실패할 수도 있기 이 의미가 .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();
}

업데이트: 이것도 제 문제를 해결하지 못한 것 같습니다.어떤 사람들은 수동으로 연결을 닫을 필요가 없다고 말합니다.가능하면 응용프로그램 전체에서 연결을 재사용하는 것이 가장 좋습니다.

(팍스 비치의 답변을 토대로 함.그것은 부결되었고, 저는 왜 어떤 상황에서는 팻의 대답이 최고인지 설명하는 논평을 추가하고 싶었습니다.담당자가 부족하여 의견을 추가할 수 없습니다.)

일반적인 경우 Array()를 사용한 답변으로 충분합니다.

그러나 방대한 문서 수집이 필요한 경우, toArray()를 사용하면 사용 가능한 RAM을 초과하게 됩니다.따라서 이러한 상황에서 "고성능" 솔루션을 어레이()에 사용해서는 안 됩니다.

이러한 경우 MongoDB 스트림을 사용할 수 있습니다. MongoDB 스트림은 잘 작동하지만 스트림을 사용하는 것보다 훨씬 간단합니다.

const cursor = db.collection('someCollection').find({})
for (let doc = await cursor.next(); doc; doc = await cursor.next()) {
    // Process the document.
}

비동기/대기를 사용하여 mongoose 쿼리 찾기

하지 않음 용 안 함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)
    }
    })

는 여에온이는 에 여기에 왔습니다.async/await해결책이지만 어떤 답도 마음에 들어할 수 없어서 아래의 토막글을 생각해냈습니다.

저는 네이티브 드라이버를 사용하고 있고 이것은 꽤 잘 작동합니다.나는 그것이 그것보다 더 읽기 쉽다고 생각합니다.for슬롯:슬라이드:

const cursor = await db.collection('myCollection').find({});

while (await cursor.hasNext()) {
  const doc = await cursor.next();
  // do whatever, ex.
  console.log(doc);
};

toArray()방법도 괜찮지만, 앞에서 지적했듯이 RAM을 다 써버리는 큰 결과 집합을 얻을 수 없는지 확인해야 합니다.

나는 mongojs를 사용하여 mongodb에서 데이터를 얻고 graphiql server에 표시하려고 합니다.나는 약속을 사용했고 마침내 그것을 얻었습니다.

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]
                }
            }

언급URL : https://stackoverflow.com/questions/47370487/node-js-mongodb-driver-async-await-queries

반응형