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

Ability to see if arrayFilters matched anything

    • Type: Icon: Improvement Improvement
    • Resolution: Unresolved
    • Priority: Icon: Minor - P4 Minor - P4
    • None
    • Affects Version/s: 4.0.12
    • Component/s: Usability
    • Labels:
      None
    • Query Execution

      when using arrayFilters, it is not possible to determine if the full query (including arrayFilters) matched anything.

       

      For example, given the document:

      use test;
      db.test.drop();
      db.test.insert({
        name: 'A',
        parents: [
          {
            name: 'AA',
            children: [
              {
                name: 'AAA',
                count: 2
              }, {
                name: 'AAB',
                count: 2
              }
            ]
          }
        ]
      });
      

      Now run an update:

      db.test.update({name: 'A'}, {
        $set: {
          'parents.$[parentMatch].children.$[childMatch].count': 1
        },
      }, {
        arrayFilters: [
          {'parentMatch.name': {$eq: 'AA'}},
          {'childMatch.name': {$eq: 'AAA'}}
        ]
      });
      

      So far so good, now let's run another update:

      db.test.update({name: 'A'}, {
        $set: {
          'parents.$[parentMatch].children.$[childMatch].count': 1
        },
      }, {
        arrayFilters: [
          {'parentMatch.name': {$eq: 'AA'}},
          {'childMatch.name': {$eq: 'AAC'}}
        ],
        upsert: true
      });
      

      Has no effect. The upsert: true has no effect because it only applies to the match predicate in the first parameter. My request is not to change the behavior here, I'm just noting for discussion.

       

      Running this query in production, it would be impossible to know if the update just simply didn't have nModified > 0 because the arrayFilter didn't match anything, or because the count value was already 1 and so no data modification occurred.

       

       

      I can see that the value for nMatched needs to be 1 because it is applied to the document level, not the subdocument level (as arrayFilters can be used across multiple sub documents within a single document, it would be difficult to assert the meaning of this value if it took that into consideration).

       

      I'm not sure what the best solution is, but I believe it is a shortcoming.

      Perhaps there is additional information returned in writeResult.

      Perhaps the update positional operator needs to be expanded so that the arrays deeper than 1 level can be updated. (I think this is a bad idea for other reasons).

       

      I like arrayFilters, and it is very useful and extendible, but it is hard to work with when "upsert" functionality is desired.

       

      Thank you for your consideration.

       

       

       

       

            Assignee:
            backlog-query-execution [DO NOT USE] Backlog - Query Execution
            Reporter:
            ben@ethika.com Ben Rotz
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: