OpenSearch to MySQL Model Relationships
In many applications, OpenSearch is used in conjunction with a relational database like MySQL. The Laravel-OpenSearch integration allows you to define hybrid relationships between OpenSearch and MySQL models seamlessly. This enables a flexible and powerful architecture for applications that need the speed and scalability of OpenSearch along with the reliability and consistency of a relational database.
Implementing Hybrid Relationships
To establish a relationship between an OpenSearch model and a MySQL (or any native Laravel datasource) model, you will need to use the HybridRelations
trait provided by the Laravel-OpenSearch package in your non-OpenSearch model to bind the two models together.
use PDPhilip\OpenSearch\Eloquent\HybridRelations;
Full example
Relationship Diagram
The models will define the following relationships:
User model (MySQL)
use Illuminate\Foundation\Auth\User as Authenticatable;
use PDPhilip\OpenSearch\Eloquent\HybridRelations;
/**
* App\Models\User
*
* *****Relationships*******
* @property-read UserLog $userLogs
* @property-read UserProfile $userProfile
* @property-read Company $company
* @property-read Avatar $avatar
* @property-read Photo $photos
*/
class User extends Authenticatable
{
use HybridRelations;
protected $connection = 'mysql';
//Relationships =====================================
// With OpenSearch models
public function userLogs()
{
return $this->hasMany(UserLog::class);
}
public function userProfile()
{
return $this->hasOne(UserProfile::class);
}
public function company()
{
return $this->belongsTo(Company::class);
}
public function avatar()
{
return $this->morphOne(Avatar::class, 'imageable');
}
public function photos()
{
return $this->morphMany(Photo::class, 'photoable');
}
}
UserLog model (OpenSearch)
/**
* App\Models\UserLog
*
******Fields*******
* @property string $_id
* @property string $company_id
* @property string $title
* @property integer $code
* @property mixed $meta
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
*
******Relationships*******
* @property-read User $user
*
* @mixin \Eloquent
*/
class UserLog extends Model
{
protected $connection = 'opensearch';
public function user()
{
return $this->belongsTo(User::class);
}
}
UserProfile model (OpenSearch)
/**
* App\Models\UserProfile
*
******Fields*******
* @property string $_id
* @property string $user_id
* @property string $twitter
* @property string $facebook
* @property string $address
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
*
******Relationships*******
* @property-read User $user
*
* @mixin \Eloquent
*
*/
class UserProfile extends Model
{
protected $connection = 'opensearch';
//Relationships =====================================
public function user()
{
return $this->belongsTo(User::class);
}
}
Company Model (OpenSearch)
/**
* App\Models\CompanyLog
*
******Fields*******
* @property string $_id
* @property string $name
* @property integer $status
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
*
******Relationships*******
* @property-read User $user
*
* @mixin \Eloquent
*
*/
class CompanyLog extends Model
{
protected $connection = 'opensearch';
//Relationships =====================================
public function company()
{
return $this->hasMany(User::class);
}
}
Avatar Model (OpenSearch)
/**
* App\Models\Avatar
*
******Fields*******
* @property string $_id
* @property string $url
* @property string $imageable_id
* @property string $imageable_type
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
*
******Relationships*******
* @property-read Company $company
*
* @mixin \Eloquent
*
*/
class Avatar extends Model
{
protected $connection = 'opensearch';
//Relationships =====================================
public function imageable()
{
return $this->morphTo();
}
}
Photo Model (OpenSearch)
/**
* App\Models\Photo
*
******Fields*******
* @property string $_id
* @property string $url
* @property string $photoable_id
* @property string $photoable_type
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
*
******Relationships*******
* @property-read Company $company
*
* @mixin \Eloquent
*
*/
class Photo extends Model
{
protected $connection = 'opensearch';
//Relationships =====================================
public function photoable()
{
return $this->morphTo();
}
}
Example Usage
// Retrieve User and related OpenSearch models
$user = User::first();
$userCompanyName = $user->company->name; //Company name for the user
$userTwitter = $user->userProfile->twitter;
$userAvatar = $user->avatar->url; //Link to Avatar
$userPhotos = $user->photos->toArray(); //Array of photos
// Retrieve UserLog and related MySQL User
$userLog = UserLog::first();
$userName = $userLog->user->name;
// Retrieve Company and related MySQL Users
$company = Company::first();
$companyUsers = $company->users->toArray(); //Array of users