Aggregate $match _id $eq $toObjectId not working

Using Compass 1.30.1, I was testing an aggregation and getting unexpected results. A $match was not working as expected. The simplified aggregation is:

db.getCollection('dlsComponents').aggregate([
  { $match: { library: 'Library1', collection: 'Collection1', media: 'Images', object: 'Image3' } }
 ])

And this gives the expected result by finding a document:

{ _id: ObjectId("61fc458b46d7874a3a97ef79"),
  library: 'Library1',
  collection: 'Collection1',
  media: 'Images',
  object: 'Image3',
  info: 'Image: 1/1/Images/Image3 Info', …

try to get the same document by _id:

db.getCollection('dlsComponents').aggregate([
  { $match: { _id: { $eq: { $toObjectId: "61fc458b46d7874a3a97ef79" } } } }
 ])

does not find a document. Why does the second $match not find a document?

I found that:

{ $match: { $expr: { $eq: [ ‘$_id’, ‘$$imageId’ ] } } }

does work ($$imageId is an ObjectId used in the non-simplified aggregate). Maybe the { $eq: ‘$value’ } format does not work in pipelines.

1 Like

Hi David,

The $eq used in find()/$match (without $expr) must specify an exact value: https://docs.mongodb.com/manual/reference/operator/query/eq/

You can use $eq: ObjectId("...")

Jess

1 Like

Your last post made me think that may be $toObjectId works only inside $expr. I tried

{ $match: { $expr : { $eq: [ '$_id' , { $toObjectId: "61fc458b46d7874a3a97ef79" } ] } } }

and it works.

3 Likes

See on a related topic

and