laravel-mongodb - Issue #3474: Incorrect sorting in MongoDB when using chunkById

XMLWordPrintableJSON

    • Type: Question
    • Resolution: Unresolved
    • Priority: Unknown
    • None
    • Affects Version/s: None
    • Component/s: Laravel
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      babaduk47 has created Issue #3474: Incorrect sorting in MongoDB when using chunkById in laravel-mongodb. This Jira ticket was filed by GromNaN

      Issue Text:

      • Laravel-mongodb Version: 12.47.0
      • PHP Version: 8.4
      • Database Driver & Version:

      Description:

      When using the `chunkById()` method with a model using the MongoDB driver, an incorrect sort query is generated with a duplicate `_id` key and a numeric key "0".

      Steps to reproduce

      ```php
      Item::query()
      ->orderBy('id')
      ->chunkById(100, fn() => throw new \Exception('test'));
      ```

      Expected behaviour

      The correct sort should look like this:
      ```json
      {
      "find": "items",
      "filter": {
      "$and": [
      { "_id":

      { "$ne": null }

      },

      { "deleted_at": null }

      ]
      },
      "limit":

      { "$numberInt": "100" }

      ,
      "sort": {
      "_id":

      { "$numberInt": "1" }

      }
      }
      ```

      Actual behaviour

      ```json
      {
      "find": "items",
      "filter": {
      "$and": [
      { "_id":

      { "$ne": null }

      },

      { "deleted_at": null }

      ]
      },
      "limit":

      { "$numberInt": "100" }

      ,
      "sort": {
      "0":

      { "$numberInt": "1" }

      ,
      "_id":

      { "$numberInt": "1" }

      }
      }
      ```

      Issue: The sort section contains an incorrect key `"0"` along with _id.

      Root Cause

      The problem arises from differences in the `orders` storage structure between Illuminate and MongoDB:

      Illuminate: `orders` is an array of objects with `column` and `direction` keys
      MongoDB: `orders` is an object (associative array)

      In the `removeExistingOrdersFor()` method of the `Builder` class:

      ```php
      protected function removeExistingOrdersFor($column)
      {
      return (new Collection($this->orders))
      ->reject(fn ($order) => isset($order['column']) && $order['column'] === $column)
      ->values()
      ->all();
      }
      ```

      Problems:

      • The `reject()` method doesn't filter orders correctly for MongoDB (since the data structure is different)
      • Calling `values()` reindexes the array with numeric keys, causing the loss of original object keys in orders
      • As a result, we get the key "0" instead of removing the existing sort

            Assignee:
            Pauline Vos
            Reporter:
            TPM Jira Automations Bot
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: