Issue with _id to id conversion when upgrading to laravel-mongodb v5 (Laravel 12 support)

Hi everyone,

I’m in the process of upgrading the laravel-mongodb package to version 5 in order to support Laravel 12. However, I’ve encountered a couple of issues related to the automatic conversion of _id fields to id.

Problems:

  1. rename_embedded_id_field = false has no effect
    According to the documentation, setting rename_embedded_id_field to false should prevent the package from renaming _id fields to id. Unfortunately, this configuration seems to be ignored entirely. Regardless of how it’s set, the _id fields are always renamed to id.
  2. Unexpected renaming in aggregation pipelines
    When using raw queries with aggregation (like $group), the _id field is also being automatically renamed to id. This seems unintended and problematic, especially when working with grouped results. Here’s an example:
$content = Model::raw(function ($collection) { 
    return $collection->aggregate([
        ['$group' => ['_id' => ['id' => '$brand_id', 'name' => '$brand_name'], 'count' => ['$sum' => 1]]],
        ['$sort' => ['count' => -1]]
    ], ["allowDiskUse" => true]);
})->toArray();

When accessing the result:

$content['_id']; // Throws an exception: index does not exist
$content['id'];  // This works instead

This forced me to go through all my aggregation queries and manually adjust the references to _id, which is both tedious and error-prone.

just want to make sure that you added this setting under config/database.php for the rename_embedded_id_field to take affect.
or if you did: \MongoDB\Connection::setRenameEmbeddedIdField(false);

(this was introduced in 5.3 btw)

1 Like

Yes, I actually tried setting it both outside and inside the options array — I didn’t even think of the second approach you mentioned.
In fact, even the documentation says that you can set this configuration per query, but honestly, that doesn’t seem like the correct or intended way to handle it.

'mongodb' => [
    'driver'   => 'mongodb',
    'dsn'      => env("MONGODB_DSN"),
    'database' => env("MONGODB_DATABASE"),
    'host'     => env("MONGODB_HOST"),
    'hosts'    => env("MONGODB_HOSTS"),
    'port'     => env("MONGODB_PORT"),
    'username' => env("MONGODB_USERNAME"),
    'password' => env("MONGODB_PASSWORD"),
    'options'  => [
        "sockettimeoutms" => 1200000,
        'rename_embedded_id_field' => false,
    ],
],

'mongodb' => [
    'driver'   => 'mongodb',
    'dsn'      => env("MONGODB_DSN"),
    'database' => env("MONGODB_DATABASE"),
    'host'     => env("MONGODB_HOST"),
    'hosts'    => env("MONGODB_HOSTS"),
    'port'     => env("MONGODB_PORT"),
    'username' => env("MONGODB_USERNAME"),
    'password' => env("MONGODB_PASSWORD"),
    'options'  => [
        "sockettimeoutms" => 1200000,
    ],
    'rename_embedded_id_field' => false,
],

So far, I haven’t seen any difference regardless of where I put rename_embedded_id_field.

this should work. and you are on 5.3?

Yes, I am on version 5.3

damn this sucks i went through the source and it looks like this was a mistake.

i’m very sorry for leading you in the wrong direction…my default was "oh its a public popular repo so they dont make mistakes) but looking at the code i’m a bit confused as to why this decision was made in the first place.

its confusing because the property made it seem like it was deliberate to fix this, but at the same time it doesn’t look like it was tested thoroughly.

what you could do here is:

  • create your own service class that wraps the php driver…or maybe just extend the query builder and override what they did aliasIdForResult then you can just bind that version in a service provider.

but even then i don’t recommend it as i dont really know how this impacts their future versions.

2 Likes

I am writing to inquire about a solution regarding the automatic rewrite of _id to id in laravel-mongodb. I have been using MongoDB and jessenger since 2018, and this automatic rewrite has prevented me from migrating to laravel-mongodb.

I have searched for a solution that doesn’t involve rewriting the majority of my queries, but I haven’t found a viable option. Rewriting all my queries to use raw queries would be a significant and costly undertaking.

Is there a current workaround for this issue, or are there any plans for an update that would address this?