[SERVER-5506] Enhance SERVER-1264 style $elemMatch functionality so that all mongo operators/functionality are supported Created: 04/Apr/12  Updated: 06/Dec/22

Status: Backlog
Project: Core Server
Component/s: Querying
Affects Version/s: 2.0.2, 2.6.3
Fix Version/s: None

Type: Improvement Priority: Major - P3
Reporter: Robert Stam Assignee: Backlog - Query Execution
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Depends
is depended on by CSHARP-611 Support for Enumerable.Any in LINQ qu... Closed
Related
related to SERVER-1264 $elemMatch on subArray Closed
Assigned Teams:
Query Execution
Participants:

 Description   

$elemMatch is normally used when the array values are documents. But can it be used when the array values are not documents? And what is the syntax? Experimentation shows that this seems to be possible but with limitations.

This JIRA requests:

1. That use of $elemMatch with array values that are not documents be properly supported and documented
2. That $elemMatch with array values that are not documents support the full range of query operators

Here's a simple example of a non-trivial query that is not currently supported.

Given the following collection:

> db.test.find()
{ "_id" : ObjectId("4f7caa152f320f937633aaf2"), "a" : [ 1, 2 ] }
{ "_id" : ObjectId("4f7caa172f320f937633aaf3"), "a" : [ 1, 3 ] }
{ "_id" : ObjectId("4f7caa1c2f320f937633aaf4"), "a" : [ 1, 6 ] }
>

We can find documents where a contains a multiple of 2 as follows:

> db.test.find({a:{$elemMatch:{$mod:[2,0]}}})
{ "_id" : ObjectId("4f7caa152f320f937633aaf2"), "a" : [ 1, 2 ] }
{ "_id" : ObjectId("4f7caa1c2f320f937633aaf4"), "a" : [ 1, 6 ] }
>

Or similarly, a multiple of 3:

> db.test.find({a:{$elemMatch:{$mod:[3,0]}}})
{ "_id" : ObjectId("4f7caa172f320f937633aaf3"), "a" : [ 1, 3 ] }
{ "_id" : ObjectId("4f7caa1c2f320f937633aaf4"), "a" : [ 1, 6 ] }
>

But we can't find documents where a contains a number that is a multiple of 2 and not a multiple of 3.

> db.test.find({a:{$elemMatch:{$and:[{$mod:[2,0]},{$not:{$mod:[3,0]}}]}}})
>

The syntax wouldn't have to be exactly like that, just that there needs to be a way to specify multiple conditions that must all be matched by the same array item when that item is not a document.

The motivation for this JIRA ticket is that the LINQ implementation in the C# driver needs to be able to translate C# where clauses to equivalent MongoDB queries. The above example of finding multiples 2 that are not multiples of 3 would look like this in LINQ:

// assume class C has a property "a" of type int[]
var query =
    collection.AsQueryable<C>()
    where (c.a % 2 == 0) && (c.a % 3 != 0)
    select c;

How would this be expressed in the MongoDB query language?



 Comments   
Comment by Aaron Staple [ 29/Aug/12 ]

If we want to support queries like { a:{ $elemMatch:

{ $or:[ ... ] }

} } we'd need to figure out how to do it. Right now $or, etc. aren't supported in this context.

Comment by Eliot Horowitz (Inactive) [ 04/Apr/12 ]

SERVER-1264

Generated at Thu Feb 08 03:09:06 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.