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": "blah@gmail.com"
    },
    "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.

CaeSea
  • 288
  • 1
  • 2
  • 11
  • you missed the underscore before id : .elemMatch("appointments", { _id: req.params.app_id }) – matthPen Sep 21 '18 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. – CaeSea Sep 21 '18 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? – matthPen Sep 21 '18 at 11:49
  • I need one result which would be the one appointment with the ID that is queried from the params – CaeSea Sep 21 '18 at 12:00
  • 1
    Possible duplicate of [Retrieve only the queried element in an object array in MongoDB collection](https://stackoverflow.com/questions/3985214/retrieve-only-the-queried-element-in-an-object-array-in-mongodb-collection) – Ashh Sep 21 '18 at 12:36

1 Answers1

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

Community
  • 1
  • 1
matthPen
  • 4,253
  • 1
  • 16
  • 16