laravel-mongodb icon indicating copy to clipboard operation
laravel-mongodb copied to clipboard

Eager loading latest item of relation does not return expected results

Open stefanschindler opened this issue 1 year ago • 5 comments

  • Laravel-mongodb Version: 3.8.5
  • PHP Version: 8.0.15
  • Database Driver & Version: unix 3.4.24

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

stefanschindler avatar Aug 23 '22 13:08 stefanschindler

Instead of necroposting next time create a new issue.

divine avatar Aug 23 '22 13:08 divine

@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.

stefanschindler avatar Aug 29 '22 05:08 stefanschindler

+1

JeRabix avatar Sep 13 '22 13:09 JeRabix