Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-5506

Enhance SERVER-1264 style $elemMatch functionality so that all mongo operators/functionality are supported

    • Type: Icon: Improvement Improvement
    • Resolution: Unresolved
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 2.0.2, 2.6.3
    • Component/s: Querying
    • None
    • Query Execution

      $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?

            Assignee:
            backlog-query-execution [DO NOT USE] Backlog - Query Execution
            Reporter:
            robert@mongodb.com Robert Stam
            Votes:
            2 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: