1

I have a saved a collection in my database and I want to filter it using companyId and cameras using ObjectId specific.

In the follow is the collection that a want to get.

  {
        "_id": ObjectID("5c3b584fa7e1b10155e6325f"),
        "companyId": "5c3b5468a7e1b10155e9995b",
        "name": "Place Test",
        "cameras": {
            "0": ObjectID("5c9149e3f054d00028cc9604"),
            "1": ObjectID("5c9149e3f054d00028cc9605")
        }
    }

I'm trying to filter like:

  const placeCollection = req.app.locals.db.collection('places')
        const place = placeCollection.findOne({
          companyId: req.body.companyId,
          cameras: { $elemMatch: { $eq: new ObjectId(req.body.cameraId) } }
        })

but not working with cameras filter, only with companyId.

Dansp
  • 1,378
  • 2
  • 14
  • 36
  • I would suggest you to change your schema. Ref: https://stackoverflow.com/questions/19802502/mongodb-query-help-query-on-values-of-any-key-in-a-sub-object $elemMatch works with array of object – Arjun Singh Mar 25 '19 at 19:48

1 Answers1

2

Since the keys in cameras are dynamically generated you need $objectToArray operator to check if any value is equal to req.body.cameraId. You can take advantage of $anyElementTrue operator here:

db.col.aggregate([
    {
        $match: {
            $expr: {
                $and: [
                    {
                        $anyElementTrue: {
                            $map: {
                                input: { $objectToArray: "$cameras" },
                                in: { $eq: [ "$$this.v", new ObjectId(req.body.cameraId) ] }
                            }
                        }
                    },
                    { $eq: [ "$companyId", req.body.companyId ] }
                ]
            }
        }
    }
])

Mongo playground

mickl
  • 48,568
  • 9
  • 60
  • 89