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

Support positional $ operator with aggregation pipeline for update operations

    • Type: Icon: Improvement Improvement
    • Resolution: Unresolved
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • None
    • Query Optimization

      I couldn't find a way to update a nested array matching a specific query when using the aggregation pipeline for update operations.

      Example :

      I have the following data :

      "_id" : ObjectId("5fd3ba7eb0b91523b424e612"),
      "data-block-array" : 
      [
        {
          "block-id"   : ObjectId("5fd3ba7eb0b91523b424e614")
          "metadata"   : {...},
          "data-value" : "Current value"
        },
        {
          "block-id" : ObjectId("5fd3ba7eb0b91523b424e616")
          "metadata" : {...},
          "data-value" : ""
        }
      ]

       

      I want to update the data-value of the data block with "block-id" : ObjectId("5fd3ba7eb0b91523b424e614") for the document with "_id" :  ObjectId("5fd3ba7eb0b91523b424e612").

       

      With the "classical" update (without pipeline), I can do :

      db.getCollection('myCollection').updateOne(
        { 
          "_id" : ObjectId("5fd3ba7eb0b91523b424e612"), 
          "data-block-array.block-id": ObjectId("5fd3ba7eb0b91523b424e614")
        },
        {
          $set : 
          {
            "data-block-array.$."data-value" : "New value"
          }
        }
      )

      But with the following aggregation pipeline, that fails : 

      db.getCollection('myCollection').updateOne(
       { 
         "_id" : ObjectId("5fd3ba7eb0b91523b424e612"), 
         "data-block-array.block-id": ObjectId("5fd3ba7eb0b91523b424e614")
       },
       {
         $set : 
         {
           "data-block-array.$."data-value" : "New value"
         }
       }
      )

      I get the error :

      "Invalid $set :: caused by :: FieldPath field names may not start with '$'."

      We also cannot use arrayFilters in an aggregation pipeline.

      I've seen in the issue SERVER-40397 that you will never implement arrayFilters for the update with aggregation pipeline, but could you add the support for positional $ operator ?

      I could use the other update version, but when you have in implementation (in C++ in my case) where we use polymorphism with a class method that returns a pipeline - which also supports things that we can't do with the other version - , it may be difficult to do so.

       

            Assignee:
            backlog-query-optimization [DO NOT USE] Backlog - Query Optimization
            Reporter:
            adrian.blandin@sovo-tech.com Adrian B
            Votes:
            1 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated: