0

I am trying to query a data collection to return just one object from an array of objects using elemMatch. I have this data:

[
{
    "_id": "5ba10e24e1e9f4062801ddeb",
    "user": {
        "_id": "5b9b9097650c3414ac96bacc",
        "firstName": "blah",
        "lastName": "blah blah",
        "email": "[email protected]"
    },
    "appointments": [
        {
            "date": "2018-09-18T14:39:36.949Z",
            "_id": "5ba10e28e1e9f4062801dded",
            "treatment": "LVL",
            "cost": 30
        },
        {
            "date": "2018-09-18T14:39:32.314Z",
            "_id": "5ba10e24e1e9f4062801ddec",
            "treatment": "LVL",
            "cost": 30
        }
    ],
    "__v": 1
}
]

I need to query the DB and pull out just one appointment depending on the id passed to params. I am using the code below based on the docs here.

router.get(
 "/booked/:app_id",
 passport.authenticate("jwt", { session: false }),
 (req, res) => {
  Appointment.find()
  .elemMatch("appointments", { id: req.params.app_id })
  .then(app => res.json(app));
 }
);

This is returning an empty array though when I test with postman. This is the first time I have used node.js and mongoDB so any help would be appreciated. Thanks.

5
  • you missed the underscore before id : .elemMatch("appointments", { _id: req.params.app_id }) Commented Sep 21, 2018 at 11:11
  • Thank you @matthPen for pointing that out, silly mistake! Only thing is, after changing that, it now returns the entire data collection and not just the one appointment I need. Commented Sep 21, 2018 at 11:27
  • ok, you need only the first array value that matches, that's it? Multiple results are desired/possible, or the first/unique per array is suffisant? Commented Sep 21, 2018 at 11:49
  • I need one result which would be the one appointment with the ID that is queried from the params Commented Sep 21, 2018 at 12:00
  • 1
    Possible duplicate of Retrieve only the queried element in an object array in MongoDB collection Commented Sep 21, 2018 at 12:36

1 Answer 1

2

You are using elemmatch as query operator, but you need to use it as projection operator

Change your function to this :

Appointment.find(
  {"appointments": {$elemMatch: {_id: req.params.app_id }}},
  {"appointments": {$elemMatch: {_id: req.params.app_id }}}
)

Why twice??

First object in find query param is $elemmatch query operator. It will return all documents, that have at least one entry matching _id in there appointments array. (but will return whole documents)

Second object (the same) is elemmatch projection oprator, which 'filters' appointments array and returns only the first matching element in array.

PS : cannot test this command. Try on your side

Sign up to request clarification or add additional context in comments.

3 Comments

Brilliant, this worked, thank you for the answer and the explanation!
why removing accepted? 'cause of duplicate, really?
It was an accident!

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.