'Mongo NodeJS project() is not a function

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.



Solution 1:[1]

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

Solution 2:[2]

The reason you can't use .project() after findOne() – but you can use it atfer find() – is: find() return a cursor, while findOne() return the direct result, maybe an ordinary document object, which apparently don't have a .project() attribute.

So the solution is the same as previous answers: add an {projection: ...} arguement to findOne().

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 emich
Solution 2