J'ai une application node.js utilisant le pilote natif mongodb. Lors de la migration de mon code d'application en mode asynchrone/wait en utilisant le noeud v8.9.1, je peine à trouver un moyen élégant pour les requêtes mongodb. Le problème majeur avec le pilote mongodb est que toutes les requêtes utilisent des callbacks où les fonctions de promesses sont obligatoires pour les méthodes asynchrones.
Alternatives:
La seule solution de rechange que j'ai réussi à mettre en œuvre de manière élégante consiste à utiliser le package callback-promise npm pour convertir l'API du pilote mongodb en promesse totale.
Des idées fraîches pour un moyen élégant et performant?
C'est le plus petit morceau de code que j'ai trouvé qui soit compatible avec Mongo3 et asynchrone/wait .
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();
}
}
}
Edit: 'mongodb' v3.x
selon mongoDB ES6 future vous pouvez utiliser cette façon;
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));
Merci. Travailler très bien avec 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);
}))
Je poste ceci comme une réponse parce que je ne peux pas commenter la réponse d'Ido Lev . Je proposerai cela dès que j'aurai atteint 50 points de réputation.
N'oubliez pas de fermer la connexion à la base de données. Sinon, il est possible que votre application ne puisse pas se connecter à la base de données à cause d’un trop grand nombre de connexions ouvertes (m’est arrivé il ya une semaine).
Votre requête peut réussir ou échouer, il est donc logique de fermer la connexion dans un bloc 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();
}
Update: Il semble que cela ne résolve pas non plus mon problème. Certaines personnes disent qu'il n'est même pas nécessaire de fermer la connexion manuellement. Il semble préférable de réutiliser votre connexion avec votre application, si possible.
Si vous ne passez pas de rappel, le client mongodb renvoie une promesse.
Le pilote officiel MongoDB Node.js fournit une interaction basée sur le rappel ainsi que sur la promesse avec MongoDB, permettant aux applications de tirer pleinement parti des nouvelles fonctionnalités de l'ES6.
Du fonctionnaire docs
mangouste trouver Query Using async/wait
ne pas utiliser mongoose.connect
en cas d'async/wait
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)
}
})
Si vous voulez utiliser le curseur sans décharger dans Array, vous ne pouvez pas utiliser les fonctions wait avec find () ou aggreg (), vous devez alors utiliser le code
UPD par Usas: Pour le cas général, les réponses utilisant toArray () sont suffisantes.
Mais lorsque d'énormes collections de documents sont impliquées, l'utilisation de toArray () dépasserait la RAM disponible. Ainsi, une solution "hautes performances" dans ces situations ne doit pas utiliser toArray ().
Pour ces cas, vous pouvez utiliser les flux MongoDB, ce qui fonctionne bien, mais l'utilisation de flux est encore plus simple:
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);
}
(Basé sur la réponse de Pax Beach. Il avait été voté à la baisse et je voulais ajouter un commentaire expliquant pourquoi, dans certaines situations, la réponse de Pat est la meilleure. Je n'ai pas assez de représentant pour ajouter des commentaires.)
Pour le cas général, les réponses utilisant toArray () sont suffisantes.
Mais lorsque énorme collections de documents sont impliquées, utiliser toArray () dépasserait la RAM disponible. Ainsi, une solution "hautes performances" dans ces situations ne doit pas utiliser toArray ().
Pour ces cas, vous pouvez utiliser les flux MongoDB, ce qui fonctionne bien, mais l'utilisation de flux est encore plus simple:
const cursor = db.collection('someCollection').find({})
for (let doc = await cursor.next(); doc; doc = await cursor.next()) {
// Process the document.
}