I wanted to exclude some attributes from the result. I read the specification: https://docs.mongodb.com/manual/tutorial/project-fields-from-query-results/ - I need to use project
function. So I chained this call but the code starts failing. The code worked fine without .project({ auth: 0, prefs: 0, consent: 0 })
. Where is the issue? I found this answer which looks similar: https://stackoverflow.com/a/51732851/1639556.
package.json
"mongodb": "^3.4.1",
Lambda
exports.handler = (payload, context, callback) => {
const userId = payload.pathParameters.userId;
context.callbackWaitsForEmptyEventLoop = false;
mongo.connectToDatabase()
.then(db => {
return findUser(db, userId);
})
.then(user => {
console.log("User fetched");
})
};
function findUser(dbClient, userId) {
return dbClient.db()
.collection("users")
.findOne({ "_id": userId })
.project({ auth: 0, prefs: 0, consent: 0 })
.then(doc => { return doc; });
}
Error
2020-01-28T11:52:34.555Z 0701f485-3770-1f43-f838-4baec8377293 INFO Request failed TypeError: dbClient.db(...).collection(...).findOne(...).project is not a function
at findUser (/var/task/src/handlers/users/getUser.js:41:10)
at mongo.connectToDatabase.then.db (/var/task/src/handlers/users/getUser.js:19:20)
PS I am curious if the projection is done at client side or server side. It is confusing to me that the project
function is AFTER the find
call.
.project()
is a cursor function, so while you can use it on cursor methods, findOne
does not return a cursor. What you can do is use the project
as a query option.
In the documentation you linked theres an example of how to use it, in the follow case:
db.inventory.find( { status: "A" }, { item: 1, status: 1, instock: { $slice: -1 } } )
The projection option is { item: 1, status: 1, instock: { $slice: -1 } }
.
So in your case you'll need to change your code to:
return dbClient.db()
.collection("users")
.findOne({ "_id": userId }, { auth: 0, prefs: 0, consent: 0 })
.then(doc => { return doc; });
Or in case your using version 3+ of the Mongod nodejs driver change into:
return dbClient.db()
.collection("users")
.findOne({ "_id": userId }, {projection: { auth: 0, prefs: 0, consent: 0 }})
.then(doc => { return doc; });
project()
is only a function of the find()
operation. It doesn't work with findOne()
(as of mongoDB Node.js driver 3.6.0) and has to be passed in the options for that call. That's why the accepted answer works, but you've seen the project()
function elsewhere.
The mongo documentation here only shows the .project()
function after a find()
call: https://docs.mongodb.com/drivers/node/fundamentals/crud/read-operations/project
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With