简体   繁体   中英

Using NodeJS promise to query MongoDB

I am building a chatbot using WATSON API which sends artist data give users' input. I am trying to use nodejs promise in order to query my DB and print out the data, since DB accessing is asynchronous.

So the artpromise function is a function which takes in the artist's name and query the db to save the result in the 'result' variable. Then I am trying to print out the result (in chatbot i actually print out the result to the user).

However I am not getting the result I want and keep getting a syntax error. Any help would be appreciated.

let arttistinfo;

function artpromise (artist) {
  return new Promise(function(resolve, reject) {
    const MongoClient = require("mongodb").MongoClient;
    const url = 'mongodb://majac.co.kr:27017/artbot';
    MongoClient.connect(url, function(err, db) {
      if (err) throw err;
      var dbo = db.db("artbot");
      var query = {name: artist};
      artistinfo = dbo.collection("artistdb").find(query)
        .toArray(function(err, result) {
          if (err) throw reject(err);
          resolve(result);
      });
      db.close();
    }
  });
)};


let artist = "Jan Tarasin";
artpormise.then(function(artist) {
  console.log(result);
});

I'd rewrite like so, I can see there were a small number of issues with your code, but this works for me now:

function artpromise (artist) {
  return new Promise(function(resolve, reject) {
    const MongoClient = require("mongodb").MongoClient;
    const url = 'mongodb://majac.co.kr:27017/artbot';
    MongoClient.connect(url, function(err, db) {
      if (err) throw err;
      var dbo = db.db("artbot");
      var query = {name: artist};
      artistinfo = dbo.collection("artistdb").find(query)
        .toArray(function(err, result) {
          if (err) throw reject(err);
          resolve(result);
      });
      db.close();
    });
  });
};

let artist = "Jan Tarasin";
artpromise(artist).then(function(result) {
  console.log(result);
});

I get the result below:

[{
    _id: 5abdbc18423795deaaff0d8e,
    nationality: 'Polish',
    art_link: 'https: //media.mutualart.com/Images/2016_06/29/20/203606422/0532d043-71f6-47bc-945e-aeededd2d483_570.Jpeg',
    years: '1926',
    name: 'JanTarasin',
    art_title: '"Falujace watki I",
    2003r.'
}]

MongoDB Node driver is natively supporting promises from v3 on. So you may greatly simplify your code by using them.

Here is how i would approach to your problem;

function artpromise (artist) {
  const MongoClient = require("mongodb").MongoClient;

  return MongoClient.connect('mongodb://majac.co.kr:27017')       // connect to mongo server
                    .then(mc => mc.db('artbot')                   // get mongoClient object and connect to artbot db
                                  .collection('artistdb')         // connect to the artistdb collection
                                  .find({name: artist})           // perform your query
                                  .toArray()                      // convert the results into an array
                                  .then(as => (mc.close(), as)))  // close db and return array from query result
                    .catch(e => console.log(e));                  // catch errors
}


let artist = "Jan Tarasin";
artpromise(artist).then(as => as.forEach(a => console.log(a)));

[nodemon] starting `node maeror.js`
{ _id: 5abdbc18423795deaaff0d8e,
  nationality: 'Polish',
  art_link: 'https://media.mutualart.com/Images/2016_06/29/20/203606422/0532d043-71f6-47bc-945e-aeededd2d483_570.Jpeg',
  years: '1926',
  name: 'Jan Tarasin',
  art_title: ' "Falujące wątki I", 2003 r. ' }
[nodemon] clean exit - waiting for changes before restart

It might be useful to remind that cursor.toArray() returns a promise as it has to iterate all the query results at once before consturcting the results array. Sometimes this operation might be time consuming yielding delayed server response. So you may instead use the cursor.forEach() method to process the documents returned from the query one by one like a stream. Which means processing the first document and then iterating to the next one. Here is another example to show how it might be implemented.

function artpromise (artist) {
  const MongoClient = require("mongodb").MongoClient;

  return MongoClient.connect('mongodb://majac.co.kr:27017')         // connect to mongo server
                    .then(function(mc){
                            var cursor = mc.db('artbot')            // get mongoClient object and connect to artbot db
                                           .collection('artistdb')  // connect to the artistdb collection
                                           .find({name: artist});   // get the cursor
                            return [mc, cursor];                    // return mongoClient and cursor objects
                          });
}

let artist = "Italian";
artpromise(artist).then(function([mc,docs]){
                          docs.forEach(doc => console.log(doc),     // process a document and then iterate to the next
                                       ()  => mc.close());          // close db session when all documents are processed
                        })
                  .catch(e => console.log(e));                      // catch errors

[nodemon] starting `node maeror_v2.js`
{ _id: 5abdbc18423795deaafeff13,
  nationality: 'Dutch',
  art_link: 'https://media.mutualart.com/Images/2012_04/15/13/132154856/ddf14e9d-85b1-4b5a-b621-00583e013879_570.Jpeg',
  years: '1839 - 1902',
  name: 'Frederick Hendrik Kaemmerer',
  art_title: ' A Beach Stroll ' }
[nodemon] clean exit - waiting for changes before restart

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM