-
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":
},
{ "deleted_at": null } ]
},
"limit":
,
"sort": {
"_id":
}
}
```
Actual behaviour
```json
{
"find": "items",
"filter": {
"$and": [
{ "_id":
},
{ "deleted_at": null } ]
},
"limit":
,
"sort": {
"0":
,
"_id":
}
}
```
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