quietplace
quietplace

Reputation: 539

MongoDB projection parameter not working in findOne()

I'm trying to use a projection parameter on findOne() to extract a single field from a document (stats) but it just seems to return the whole document. I'm using version "mongodb": "^3.4.1" in Node.js

This is the document structure

{ _id: 5e563015fa9a1a0134cac3cb,
  username: 'user1',
  password: '1234',
  email: '[email protected]',
  stats: 
   { totalViewed: 122,
     totalUnique: 4,
     tknow: 80,
     tdknow: 42,
     setCnt: 78 },
  progress: 
   [ { cardId: 1001, knowCnt: 3, dknowCnt: 4 },
     { cardId: 1016, knowCnt: 0, dknowCnt: 0 } ] }

This is the code:

 var findOneDoc = function() {
        db.collection("testusers").findOne(
          { username: "user1" },
          { stats: 1 }, //field to return
          function(err, result) {
            if (err) {
              console.log("Error: ", err);
            }
            console.log("Success: ", result);
          }
        );
      };
     findOneDoc();

I also tried:{$project: {stats: 1}}, to no avail

Thanks

Upvotes: 23

Views: 16211

Answers (4)

zvijude
zvijude

Reputation: 359

you can do it like mick said, with findOne

await db.collection("testusers").findOne(
    { username: "user1" },
    { projection: { stats: 1 } },
    function(err, result) { ... }
);

or you can do it with find, like that

await db.collection("testusers")
.find({ username: "user1" })
.limit(1)
.project(["stats"])
.toArray()

you can add fields to the array project for more fields

Upvotes: 2

Bryant
Bryant

Reputation: 41

with findOne operations, the second parameter passed is an options parameter, so you should pass in your projects within the options parameter, like this:

query = { username: "user1" };
options = { projection: { stats: 1 }};

db.collection("testusers").findOne(query, options)

Upvotes: 4

Cahaba Data
Cahaba Data

Reputation: 622

findOne returns a document. use find() …..

Upvotes: -1

mickl
mickl

Reputation: 49945

Based on the documentation the .findOne() method takes options as a second parameter and it is recommended to use projection to define fields:

db.collection("testusers").findOne(
    { username: "user1" },
    { projection: { stats: 1 } },
    function(err, result) { ... }
);

Upvotes: 56

Related Questions