MongoDB, Node.js'de vaatlerle nasıl kullanılır?


83

MongoDB'yi Node.js ile nasıl kullanacağımı keşfetmeye çalışıyorum ve belgelerde önerilen yol geri aramaları kullanmak gibi görünüyor. Şimdi, bunun sadece bir tercih meselesi olduğunu biliyorum ama gerçekten vaatleri kullanmayı tercih ediyorum.

Sorun şu ki, onları MongoDB ile nasıl kullanacağımı bulamadım. Doğrusu şunu denedim:

var MongoClient = require('mongodb').MongoClient;

var url = 'mongodb://localhost:27017/example';

MongoClient.connect(url).then(function (err, db) {
    console.log(db);
});

Ve sonuç şudur undefined. Bu durumda, bunu yapmanın yolu bu değil gibi görünüyor.

Geri arama yerine vaatlerle Düğüm içinde mongo db kullanmanın bir yolu var mı?


Yanıtlar:


119

Yaklaşımınız neredeyse doğru, sadece argümanınızda küçük bir hata

var MongoClient = require('mongodb').MongoClient
var url = 'mongodb://localhost:27017/example'
MongoClient.connect(url)
  .then(function (db) { // <- db as first argument
    console.log(db)
  })
  .catch(function (err) {})

11
Kesinlikle! MongoDB Node.js sürücüsü 2.x "Geri döner : Geri arama geçilmezse söz ver " ia MongoClient.connect. Dahili ES6 vaatleri olmadan node.js <4 varsa, o zaman ES6 uyumlu vaat dolgusu kullanabilir veya promiseLibraryseçeneği ile ES6 uyumlu vaat uygulaması sağlayabilirsiniz MongoClient.connect.
VolkerM

5
Bazı testlere dayanarak, URL'ye bağlanırsanız mongodb//localhost:27017(bir veritabanı belirtmeden) bir mongoclient alırsınız, bu yüzden aramanız gerekir mongoclient.db('example'). Bkz. Mongodb.github.io/node-mongodb-native/api-generated/…
PatS

23

Ayrıca async / await de yapabilirsiniz

async function main(){
 let client, db;
 try{
    client = await MongoClient.connect(mongoUrl, {useNewUrlParser: true});
    db = client.db(dbName);
    let dCollection = db.collection('collectionName');
    let result = await dCollection.find();   
    // let result = await dCollection.countDocuments();
    // your other codes ....
    return result.toArray();
 }
 catch(err){ console.error(err); } // catch any mongo error here
 finally{ client.close(); } // make sure to close your connection after
}


Şu anda yüzünü öpebilirim. Bu saatler içinde bulduğum en basit, en iyi cevaptı.
Rob E.

Bu, mümkün olan en basit, en taze ve en eksiksiz ve en güncel cevaptır. Çok teşekkür ederim.
keuluu

19

Yukarıdaki cevapların hiçbiri bunun bluebird veya q veya başka bir fantezi kütüphane olmadan nasıl yapılacağından bahsetmediğinden, buna 2 sentimi de eklememe izin verin.

Yerel ES6 vaatleriyle bir insert nasıl yapacağınız aşağıda açıklanmıştır

    'use strict';

const
    constants = require('../core/constants'),
    mongoClient = require('mongodb').MongoClient;



function open(){

    // Connection URL. This is where your mongodb server is running.
    let url = constants.MONGODB_URI;
    return new Promise((resolve, reject)=>{
        // Use connect method to connect to the Server
        mongoClient.connect(url, (err, db) => {
            if (err) {
                reject(err);
            } else {
                resolve(db);
            }
        });
    });
}

function close(db){
    //Close connection
    if(db){
        db.close();
    }
}

let db = {
    open : open,
    close: close
}

module.exports = db;

Open () yöntemimi bir sözü geri veren yöntem olarak tanımladım. Bir ekleme gerçekleştirmek için, işte aşağıdaki kod parçacığım

function insert(object){
    let database = null;
    zenodb.open()
    .then((db)=>{
        database = db;
        return db.collection('users')    
    })
    .then((users)=>{
        return users.insert(object)
    })
    .then((result)=>{
        console.log(result);
        database.close();
    })
    .catch((err)=>{
        console.error(err)
    })
}



insert({name: 'Gary Oblanka', age: 22});

Umarım yardımcı olur. Bunu daha iyi hale getirmek için herhangi bir öneriniz varsa, kendimi geliştirmek istediğim için bana bildirin :)


13
Bir sözümü başka bir sözle sarıyorsun. MongoClient yöntemleri şimdiden bir söz veriyor ve bunu tekrar sarmaya gerek yok. Bu, tipik bir söz karşıtı kalıptır.
westor

4
Aylar sonra geliyor, ancak @ Green'in orijinal gönderiden 20 dakika sonraki yanıtı mongodb.MongoClient'in yerel vaat desteğini kullanıyor ve gereksiz vaat kitaplıkları kullanmıyor.
Owen

2
Üçüncü şahısların vaat ettiği kitaplıklara dayanmadığından bu doğru cevap olmalıdır.
GlGuru

@westor open () yönteminden bir sözü, yeni Promise'a bağlamadan nasıl iade edeceksiniz? Sanırım tek yol bu.
Abhishek Nalin

1
@AbhishekNalin MongoDB bağlantı yöntemi (en azından daha yeni sürümlerde) bir söz verir. Bu nedenle, basitçe 'mongoClient.connect (url). Sonra (...)' yazabilirsiniz veya bu açık yöntemde mongoClient.connect (url) döndürürsünüz. Geri aramadan kurtulabilirsiniz. Hata durumu, buradaki son yakalama tarafından yakalanır.
westor

11

Bu, MongoDB'nin Node.js'deki vaatlerle nasıl kullanılacağına ilişkin Genel bir cevaptır.

mongodb, geri arama parametresi atlanırsa bir söz döndürür

Promise'a dönüştürmeden önce

var MongoClient = require('mongodb').MongoClient,
dbUrl = 'mongodb://db1.example.net:27017';

MongoClient.connect(dbUrl,function (err, db) {
    if (err) throw err
    else{
        db.collection("users").findOne({},function(err, data) {
            console.log(data)
        });
    }
})

Promise'a dönüştürdükten sonra

//converted
MongoClient.connect(dbUrl).then(function (db) {
    //converted
    db.collection("users").findOne({}).then(function(data) {
         console.log(data)
    }).catch(function (err) {//failure callback
         console.log(err)
    });
}).catch(function (err) {})

Birden fazla isteği yerine getirmeniz gerektiğinde

MongoClient.connect(dbUrl).then(function (db) {

   /*---------------------------------------------------------------*/

    var allDbRequest = [];
    allDbRequest.push(db.collection("users").findOne({}));
    allDbRequest.push(db.collection("location").findOne({}));
    Promise.all(allDbRequest).then(function (results) {
        console.log(results);//result will be array which contains each promise response
    }).catch(function (err) {
         console.log(err)//failure callback(if any one request got rejected)
    });

   /*---------------------------------------------------------------*/

}).catch(function (err) {})

1
Bağlantıdan sonra operasyon için neden iç içe geçmiş taahhüt zinciri oluşturuyorsunuz? Neden olmasın:MongoClient.connect(uri).then(client => client.db("db").collection("users").find()).then(data => console.log(data)).catch(err => console.log(err));
SerG

Bu, belgelere bağlantılarla daha iyi olurdu
mikemaccana

Yakalama için daha kısa gösterim: .catch (console.log)
Benjam

2

UYARI Düzenleme:

John Culviner'in belirttiği gibi, bu cevap kabul edilmiyor. Sürücüyü kullanın, OOTB sözleriyle birlikte gelir.


Bluebird'ü bir söz kitaplığı olarak kullanmayı seçerseniz promisifyAll(), MongoClient'te bluebirds işlevini kullanabilirsiniz :

var Promise = require('bluebird');
var MongoClient = Promise.promisifyAll(require('mongodb').MongoClient);

var url = 'mongodb://localhost:27017/example';

MongoClient.connectAsync(url).then(function (db) {
    console.log(db);
}).catch(function(err){
    //handle error
    console.log(err);
});

6
MongoDB sürücüsünün zaten vaatleri var (eğer bluebird istiyorsanız, seçeneklerde belirtebilirsiniz veya ben global. Promise ekledim) BUNU YAPMAYIN!
John Culviner

2

Partiye biraz geç kaldığımı biliyorum ama ES6 kullanarak bir örnek paylaşmak istiyorum

const config = require('config');
const MongoClient = require('mongodb').MongoClient;

var _connection;
var _db;

const closeConnection = () => {
  _connection.close();
}

/**
 * Connects to mongodb using config/config.js
 * @returns Promise<Db> mongo Db instance
 */
const getDbConnection = async () => {
  if (_db) {
    return _db;
  }
  console.log('trying to connect');
  const mongoClient = new MongoClient(config.mongodb.url, { useNewUrlParser: true });
  _connection = await mongoClient.connect();
  _db = _connection.db(config.mongodb.databaseName);
  return _db;
}

module.exports = { getDbConnection, closeConnection };

Bir göz atmak isterseniz, burada biraz daha ayrıntıya giriyorum:

https://medium.com/swlh/how-to-connect-to-mongodb-using-a-promise-on-node-js-59dd6c4d44a7


çok hoş. Sadece getDbConnection işlevini yeniden adlandırırdım çünkü bağlantıyı döndürmez. _Db döndürür. :)
kroiz

1

Ya gibi alternatif bir paket kullanabilir mongodb-promiseya da mongodbpaket API'sini, etrafında kendi sözlerinizi oluşturarak ya da vaat edilen bir yardımcı program paketi aracılığıyla manuel olarak vaat edebilirsiniz.bluebird.promisify


MongoDB sürücüsünün zaten vaatleri var (eğer bluebird istiyorsanız, seçeneklerde belirtebilirsiniz veya ben global. Promise ekledim) BUNU YAPMAYIN!
John Culviner

1

MongoDB sürümü> 3.0 ile çalışma çözümü

var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";


open = (url) => {
    return new Promise((resolve,reject) => {
        MongoClient.connect(url, (err,client) => { //Use "client" insted of "db" in the new MongoDB version
            if (err) {
                reject(err)
            } else {
                resolve({
                    client
                });
            };
        });
    });
};

create = (client) => {
    return new Promise((resolve,reject) => {
        db = client.db("myFirstCollection"); //Get the "db" variable from "client"
        db.collection("myFirstCollection").insertOne({
            name: 'firstObjectName',
            location: 'London'
            }, (err,result)=> {
                if(err){reject(err)}
                else {
                    resolve({
                        id: result.ops[0]._id, //Add more variables if you want
                        client
                    });
                }

            });
    });
};

close = (client) => {
    return new Promise((resolve,reject) => {
        resolve(client.close());
    })

};

open(url)
    .then((c) => {
        clientvar = c.client;
        return create(clientvar)
    }).then((i) => {
        idvar= i.id;
        console.log('New Object ID:',idvar) // Print the ID of the newly created object
        cvar = i.client
        return close(cvar)
    }).catch((err) => {
        console.log(err)
    })

0

Mongo'ya bağlanan bir söz oluşturmanız gerekiyor.

Sonra bu sözünü kullandığı işlevi tanımlayın: myPromise.then(...).

Örneğin:

function getFromMongo(cb) {
    connectingDb.then(function(db) {

       db.collection(coll).find().toArray(function (err,result){
           cb(result);
       });

    });
}

işte tam kod:

http://jsfiddle.net/t5hdjejg/


MongoDB sürücüsünün zaten vaatleri var (eğer bluebird istiyorsanız, seçeneklerde belirtebilirsiniz veya ben global. Promise ekledim) BUNU YAPMAYIN!
John Culviner

@JohnCulviner anlayabildiğim kadarıyla, .find bir söz vermiyor mu? Örneğin, bazı yöntemler bir imleç üzerinde - .count () işlevini yapar, ancak db.mycoll.find ({}). O zaman tanımsız?
sil

@sil db.get ("koleksiyon"). find ({bir şey: "a"}). sonra (). catch (); benim için çalışıyor
Rafique Mohammed

0

İşte bağlantıyı açmak için bir yol

export const openConnection = async ()  =>
     await MongoClient.connect('mongodb://localhost:27017/staticback')

ve böyle çağır

const login = async () => 
const client = await openConnection()

-1

Bağlantı yönteminin tanımlanmış bir vaat arayüzü varmış gibi görünmüyor

http://mongodb.github.io/node-mongodb-native/2.1/tutorials/connect/

Mongodb bağlayıcı kitaplığında her zaman kendiniz uygulayabilirsiniz, ancak bu muhtemelen aradığınızdan daha karmaşıktır.

Gerçekten sözlerle çalışmanız gerekiyorsa, ES6 sözlü polyfill'i her zaman kullanabilirsiniz:

https://github.com/stefanpenner/es6-promise

ve bağlantı kodunuzu bununla sarın. Gibi bir şey

var MongoClient = require('mongodb').MongoClient;
var Promise = require('es6-promise').Promise;

var url = 'mongodb://localhost:27017/example';

var promise = new Promise(function(resolve, reject){
    MongoClient.connect(url, function (err, db) {
        if(err) reject(err);
        resolve(db);
    });        
});

promise.then(<resolution code>);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.