$projection vs $elemMatch

paulkon

What is the functional difference between:

db.docs.find({ 'a.b': 'c' }, { 'a.$': 1 })

and

db.docs.find({ 'a.b': 'c' }, { 'a': { $elemMatch: { b: 'c' } } })

Is $elemMatch redundant? How would indexes change?

Stennie

The difference in projection usage is somewhat subtle. In your example usage, these should be equivalent queries (in terms of index usage) but the $elemMatch example unnecessarily repeats the query criteria. The $ projection would be a more sensible choice for this example.

An essential difference noted in the documentation is the array field limitation for $ projections:

Since only one array field can appear in the query document, if the array contains documents, to specify criteria on multiple fields of these documents, use the $elemMatch operator.

Some further notes on the differences in the projection operators below ...

The positional ($) projection operator:

  • limits the contents of an array field that is included in the query results to contain the first element that matches the query document.

  • requires that the matching array field is included in the query criteria

  • can only be used if a single array field appears in the query criteria

  • can only be used once in a projection

The $elemMatch projection operator

  • limits the contents of an array field that is included in the query results to contain only the first array element that matches the $elemMatch condition.

  • does not require the matching array to be in the query criteria

  • can be used to match multiple conditions for array elements that are embedded documents

The $elemMatch query operator

Note that there is also an $elemMatch query operator which performs similar matching, but in the query rather than the results projection. It's not uncommon to see this used in combination with a $ projection.

Borrowing an example from the docs where you might use both:

db.students.find(
    // use $elemMatch query operator to match multiple criteria in the grades array
    { grades: {
        $elemMatch: {
            mean:  { $gt: 70 },
            grade: { $gt: 90 }
        }
    }},

    // use $ projection to get the first matching item in the "grades" array
    { "grades.$": 1 }
)

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Combining $elemMatch and $ in mongodb projection

From Dev

Using $elemMatch in projection field - not filtering as desired

From Dev

How to use $elemMatch on aggregate's projection?

From Dev

MongoDB: Embedded Array $elemMatch(projection) error issue

From Dev

Is It possible to use query projection on the same collection that has a $elemMatch projection?

From Dev

Make $elemMatch (projection) return all objects that match criteria

From Dev

Projection of arrays using $ vs using $slice

From Dev

Projection Queries vs. Regular Queries

From Dev

Why the difference in scale values in projection vs. tile?

From Dev

Java Wildcard-types vs Kotlin Star-projection

From Dev

GeoJSON projection of external file vs. internal object

From Dev

ArgumentNullException with ElemMatch

From Dev

$elemMatch and update

From Dev

$or statement in $elemMatch

From Dev

MongoDB $elemMatch $in

From Dev

ArgumentNullException with ElemMatch

From Dev

$or statement in $elemMatch

From Dev

$elemMatch and update

From Dev

Index for query with "field": {$not: {$elemmatch: {...}}?

From Dev

MongoDB: multiple $elemMatch

From Dev

$and inside $elemMatch not working in Meteor

From Dev

MongoDB $elemMatch in Meteor

From Dev

mongodb find with opposite of $elemMatch

From Dev

$and inside $elemMatch not working in Meteor

From Dev

$elemMatch on embedded documents

From Dev

MongoDB: $elemMatch issue

From Dev

$elemMatch on nested Embedded Document

From Dev

MongoDb $elemMatch is not working as expected

From Dev

mongodb $elemMatch with multiple values