23

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

2
  • As a double check, did you try db.collection["testusers'].findOne({"username":"user1"},{stats:1}) directly from the shell? Commented Mar 5, 2020 at 2:10
  • Sorry I'm not familiar with using the shell directly. Thanks Commented Mar 5, 2020 at 3:14

4 Answers 4

56

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) { ... }
);
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks. When I tried this nothing returned from the database - so success or error messages or fields returned. var findOneDoc4 = function() { db.collection("testusers").findOne( { username: "user1" }, { projection: { stats: 1 } }, function(err, result) { if (err) { console.log("Error: ", err); } console.log("Success: ", result); } );
The document is shown at the top in the original question. Thanks
what if you remove second parameter, are you still getting no result?
If I remove the second parameter the whole document returns as expected.
Can you try { fields: { stats: 1 } } instead of { projection: { stats: 1 } }?
|
4

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)

1 Comment

Don't forget to await
3

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

Comments

-1

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

1 Comment

I tried .find() but it still didn't return anything. I'm only targeting one document so my understanding is that findOne() should work and is compatible with projection parameters. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.