Tengo una colección de user_batch. Contiene los siguientes documentos:
[{ _id: ObjectId("594baf96256597ec035df23c"), name: "Batch 1", batchSize: 30, users:[] }, { _id: ObjectId("594baf96256597ec035df234"), name: "Batch 2", batchSize: 50, users:[] }]
En la consulta de búsqueda quiero proyectar solo nombre y tamaño de lote . Pero cuando ejecuto la consulta de búsqueda de nodejs, obtengo un documento completo en el resultado de la consulta. Consulta:
db.collection('user_batch').find({}, {name: 1, batchSize: 1}).toArray((err, result) => { if(err) console.log(err) else console.log(result) })
Si simplemente paso {nombre: 1} , se proyectará _id y nombre. Pero si paso batchSize entonces devolverá el documento completo.
Nota: No estoy enfrentando este problema al ejecutar esta consulta en Mongo Shell
Tiene razón en que el controlador interpreta incorrectamente esto como la opción batchSize
e ignora la statement de proyección.
La forma correcta de hacer esto, sin embargo, en las versiones modernas de controladores es utilizar el método de cursor .project()
lugar. Esto es más consistente con otras implementaciones de controladores de lenguaje.
db.collection('collection').find() .project({ name: 1, batchSize: 1}) .toArray();
Como una demostración completa:
const mongodb = require('mongodb'), MongoClient = mongodb.MongoClient; (async function() { let db; try { db = await MongoClient.connect('mongodb://localhost/test'); // New form uses .project() as a cursor method let result = await db.collection('collection').find() .project({ name: 1, batchSize: 1}) .toArray(); console.log(JSON.stringify(result,undefined,2)); // Legacy form confuses this as being a legacy "cursor option" let other = await db.collection('collection') .find({},{ name: 1, batchSize: 1 }) .toArray(); console.log(JSON.stringify(other,undefined,2)); } catch(e) { console.error(e) } finally { db.close() } })()
Produce la salida:
[ { "_id": "594baf96256597ec035df23c", "name": "Batch 1", "batchSize": 30 }, { "_id": "594baf96256597ec035df234", "name": "Batch 2", "batchSize": 50 } ] [ { "_id": "594baf96256597ec035df23c", "name": "Batch 1", "batchSize": 30, "users": [] }, { "_id": "594baf96256597ec035df234", "name": "Batch 2", "batchSize": 50, "users": [] } ]
Donde la primera forma de salida es la corregida, usando .project()
La syntax de Find
ha cambiado. A continuación se muestra lo que necesitaba saber para resolver este problema. Esto está extraído de https://github.com/mongodb/node-mongodb-native/blob/master/CHANGES_3.0.0.md#find
find
y findOne
ya no admite el parámetro fields
. Puede obtener los mismos resultados que el parámetro de fields
utilizando Cursor.prototype.project
o pasando la propiedad de projection
en el objeto de opciones. Además, find
no admite opciones individuales como skip
y limit
como parámetros posicionales. Debe pasar estos parámetros en el objeto de options
o agregarlos a través de métodos de Cursor
como Cursor.prototype.skip
.
2.x syntax:
const cursor = coll.find({ a: 42 }, { someField: 1 });
Sintaxis 3.x:
const cursor = coll.find({ a: 42 }).project({ someField: 1 }); /* OR */ const cursor = coll.find({ a: 42 }, { projection: { someField: 1 } });