mongodb / laravel-mongodb

A MongoDB based Eloquent model and Query builder for Laravel (Moloquent)
https://www.mongodb.com/compatibility/mongodb-laravel-integration
MIT License
6.99k stars 1.42k forks source link

Eager loading latest item of relation does not return expected results #2437

Open stefanschindler opened 2 years ago

stefanschindler commented 2 years ago

Description:

I have a hybrid setup with MySQL and MongoDB. Eager Loading latest item of relation is not working correctly. I want to load a list of customers with their latest metrics (by date) eager loaded. Instead of loading the latest metric for every customer, it just loads the latest metric in total.

Steps to reproduce

The Customer Class (Mysql):

class Customer extends Model
{
    use HybridRelations;

    public function metrics()
    {
        return $this->hasMany(Metrics::class);
    }
}

The Metrics Class (Mongodb):

class Metrics extends Moloquent
{
    protected $connection = 'mongodb';
   ...
}

The code that loads the data:

$customers = Customer::orderBy('last_accessed_at', 'desc')
                                                  ->with([
                                                      'metrics' => function (HasMany $query)
                                                      {
                                                          $query->orderBy('date', 'desc')
                                                                ->limit(1)
                                                                ->get([
                                                                    '_id',
                                                                    'date',
                                                                    'metric1',
                                                                    'metric2',
                                                                ]);
                                                      },
                                                  ])
                                                  ->get([
                                                      'id',
                                                      'name'
                                                  ]);

I also tried to use first() instead of limit(1)->get(), but that led to the same result.

Expected behaviour

It should return all customers with their latest metrics, similar to this:

"customers": [
        {
            "id": 1,
            "name": "customer 1",
            "metrics":[
                {
                    "_id": "6304a45314e6ad8aff662a13",
                    "date": "2022-08-23T00:00:00.000000Z",
                    "metric1": 81,
                    "metric2": 21
                }
            ]
        },
        {
            "id": 2,
            "name": "customer 3",
            "url": "https://stevie.url.com",
            "metrics": [
                {
                    "_id": "6304a45314e6ad8aff662a12",
                    "date": "2022-08-23T00:00:00.000000Z",
                    "metric1": 33,
                    "metric2": 7
                }
            ]
        },
        ...
    ]

Actual behaviour

Only the newest metric of all customers is returned, which results, that most customers have empty metrics:

"customers": [
        {
            "id": 1,
            "name": "customer 1",
            "metrics": []
        },
        {
            "id": 2,
            "name": "customer 3",
             "url": "https://stevie.url.com",
            "metrics": [
                {
                    "_id": "6304a45314e6ad8aff662a12",
                    "date": "2022-08-23T00:00:00.000000Z",
                    "metric1": 33,
                    "metric2": 7
                }
            ]
        },
        ...
    ]

@jenssegers seems to be the same problem as this issue: https://github.com/jenssegers/laravel-mongodb/issues/1042#issue-191570133

divine commented 2 years ago

Instead of necroposting next time create a new issue.

stefanschindler commented 2 years ago

@divine didn't I open a new issue? Maybe the problem is already known, but the other issue was closed in 2018 without any reason and it still doesn't seem to work.

JeRabix commented 1 year ago

+1

Iscrimou commented 1 year ago

Same problem here, Message::with('user') works well, but User::with('messages') came a empty array, and I didn't find any solution in others posts

eslamismail commented 1 year ago

I have the same issue with laravel 8 and jenssegers/mongodb 3.8.x
it works only with belongsTo relation hasone or has many return empty response cause the foreign key and primary id is objectID while package search in collection with string type