A later $sort does not reset {$meta:"sortKey"} when the two sorts cannot be coalesced

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Unresolved
    • Priority: Minor - P4
    • None
    • Affects Version/s: None
    • Component/s: None
    • Query Optimization
    • ALL
    • Hide

       

      // code placeholder
      const c = db.getSiblingDB("sk_bug").c;
      c.drop();
      c.insertMany([
          {_id: 1, a: 3, b: "x"},
          {_id: 2, a: 1, b: "y"},
          {_id: 3, a: 2, b: "z"}]);
      
      // Two sorts on different fields, separated by a no-op $limit so they cannot coalesce.
      // Final order is by 'b' (x,y,z), so {$meta:"sortKey"} should reflect 'b'.
      const docs = c.aggregate([
          {$sort: {a: 1}},
          {$limit: 1000000000}, // Any other stage would equally surface the issue. Just added this one as is a no-op, but any other else would also reproduce it
          {$sort: {b: 1}},
          {$project: {_id: 0, b: 1, sk: {$meta: "sortKey"}}},
      ]).toArray();
      
      printjson(docs);

      Expected: the sort key reflects the last $sort (on b):

      [ {b:"x", sk:["x"]}, {b:"y", sk:["y"]}, {b:"z", sk:["z"]} ]

      Actual: the sort key is stale — it reflects the first $sort (on a):

      [ {b:"x", sk:[3]}, {b:"y", sk:[1]}, {b:"z", sk:[2]} ]  

       

      Show
        // code placeholder const c = db.getSiblingDB( "sk_bug" ).c; c.drop(); c.insertMany([ {_id: 1, a: 3, b: "x" }, {_id: 2, a: 1, b: "y" }, {_id: 3, a: 2, b: "z" }]); // Two sorts on different fields, separated by a no-op $limit so they cannot coalesce. // Final order is by 'b' (x,y,z), so {$meta: "sortKey" } should reflect 'b' . const docs = c.aggregate([ {$sort: {a: 1}}, {$limit: 1000000000}, // Any other stage would equally surface the issue. Just added this one as is a no-op, but any other else would also reproduce it {$sort: {b: 1}}, {$project: {_id: 0, b: 1, sk: {$meta: "sortKey" }}}, ]).toArray(); printjson(docs); Expected: the sort key reflects the last $sort (on b): [ {b: "x" , sk:[ "x" ]}, {b: "y" , sk:[ "y" ]}, {b: "z" , sk:[ "z" ]} ] Actual: the sort key is stale — it reflects the first $sort (on a): [ {b: "x" , sk:[3]}, {b: "y" , sk:[1]}, {b: "z" , sk:[2]} ]   
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      When an aggregation has two $sort stages on different keys that are NOT adjacent (so the optimizer cannot coalesce them), {$meta:"sortKey"} reflects the FIRST sort's key, not the effective final ordering produced by the last $sort. So it is effectively returning wrong results.

       

      A common case would be when there is a view that defines sorting and a user wants to override it with its own sorting.

       

      Note that the two sorts have to be not contiguous, which stage(s) sit in between don't matter at all

            Assignee:
            Chris Harris
            Reporter:
            Carlos Alonso Pérez
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated: