whereHas issue
neilmarsland opened this issue · comments
- Laravel-mongodb Version: 4.1
- PHP Version: 8.3.0
- Database Driver & Version: mongodb
Description:
I have a leagues collection.
{
"_id": {
"$oid": "658e9c7d9ce7b199fa555269"
},
"type": "CUPMATCH",
"api_id": 75,
"name": "World Cup",
"country_id": {
"$oid": "658e9c7d9ce7b199fa555268"
}
}
And Countries Collection
{
"_id": {
"$oid": "658e9c7d9ce7b199fa555268"
},
"name": "International",
"main_area": {
"$oid": "658e9c7d9ce7b199fa555267"
},
"flag": "https://football.bongdalu4.com/Image/info/images/164454845888.png"
}
League
Model is has relationship with Country
public function country()
{
return $this->belongsTo(Country::class, 'country_id');
}
When I query with whereHas country name is China:
$query = League::with("country")->whereHas('country', function($query){
$query->where('name', 'LIKE', "%China%");
});
If return empty collection.
Expected behaviour
It should return all of league in China Country
Actual behaviour
Logs:
Insert log.txt here (if necessary)Hello, this kind of filter requires a $lookup
that is not implemented in this library. You can use a raw aggregation pipeline, but the performance will not be optimal:
use MongoDB\BSON\Regex;
use MongoDB\Collection;
League::raw(function (Collection $collection) {
return $collection->aggregate([
[
'$lookup' => [
'from' => 'countries',
'localField' => 'country_id',
'foreignField' => '_id',
'as' => 'country_info'
]
],
[
'$match' => [
'country_info.name' => new Regex('China', 'i')
]
],
[
'$project' => [
'country_info' => 0,
],
]);
});
The League
model should be populated.
Also, the MongoDB modeling strategy is different from tabular databases, you can denormalize the country name in the leagues documents when they are saved. Learn about Map Schema Relationships