elasticsearch-eloquent

⚡️ Models like Eloquent for Elasticsearch.

Downloads
12.8K
Stars
112
Committers
3

Elasticsearch Eloquent 2.x

This package allows you to interact with Elasticsearch as you interact with Eloquent models in Laravel.

Requirements

  • PHP >= 8.0
  • Elasticsearch >= 7.0

Install

Via Composer

$ composer require isswp101/elasticsearch-eloquent

Usage

Create a new model

You should override index and type properties to determine the document path.

use Isswp101\Persimmon\Models\BaseElasticsearchModel;
use Isswp101\Persimmon\Persistence\Persistence;
use Isswp101\Persimmon\Contracts\PersistenceContract;

class Product extends BaseElasticsearchModel
{
    protected string $index = 'index';
    protected string|null $type = 'type'; // optional

    // If you have a pre-configured Elasticsearch client you can pass it here (optional)
    public function createPersistence(): PersistenceContract
    {
        return new Persistence($client);
    }
}

Use the static create() method to create the document in Elasticsearch:

$product = Product::create([
    'id' => 1, 
    'name' => 'Product',
    'price' => 10
]);

Save the model

$product = new Product();
$product->id = 1;
$product->name = 'Product';
$product->price = 10;
$product->save();

Use save() method to store model data in Elasticsearch. Let's see how this looks in Elasticsearch:

{
   "_index": "index",
   "_type": "type",
   "_id": "1",
   "_version": 1,
   "_source": {
      "id": 1,
      "name": "Product",
      "price": 10,
      "created_at": "2021-03-27T11:24:15+00:00",
      "updated_at": "2021-03-27T11:24:15+00:00"
   }
}

Fields created_at and updated_at were created automatically.

Find existing model

$product = Product::find(1);

If you have big data in Elasticsearch you can specify certain fields to retrieve:

$product = Product::find(1, ['name']);

There are the following methods:

  • findOrFail() returns ModelNotFoundException exception if no result found.

Cache

There is a smart model cache when you use methods like find(), findOrFail() and so on.

$product = Product::find(1, ['name']);  // from elasticsearch
$product = Product::find(1, ['name']);  // from cache
$product = Product::find(1, ['price']); // from elasticsearch
$product = Product::find(1, ['price']); // from cache
$product = Product::find(1, ['name']);  // from cache
$product = Product::find(1);            // from elasticsearch
$product = Product::find(1);            // from cache
$product = Product::find(1, ['name']);  // from cache
$product = Product::find(1, ['price']); // from cache

Partial update

You can use the partial update to update specific fields quickly.

$product = Product::find(1, ['name']);
$product->name = 'Name';
$product->save(['name']);

Delete models

$product = Product::find(1);
$product->delete();

You can use the static method:

Product::destroy(1);

Model events

Out of the box you are provided with a simple implementation of events. You can override the following methods to define events:

  • saving() is called before saving, updating, creating the model
  • saved() is called after saving, updating, creating the model
  • deleting() is called before deleting the model
  • deleted() is called after deleting the model
  • searching() is called after searching models
  • searched() is called after searching models

For example:

use Isswp101\Persimmon\Models\BaseElasticsearchModel;

class Product extends BaseElasticsearchModel
{
    protected function saving(): bool
    {
        // Disable update if it's free
        return $this->price <= 0;
    }

    protected function deleting(): bool
    {
        if ($this->user_id != 1) {
            throw new DomainException('No permissions to delete this model');
        }

        return true;
    }
}

Basic search

There are helpers to search documents:

The first($query) method returns the first document according to the query or null.

$product = Product::first($query);

The firstOrFail($query) method returns ModelNotFoundException exception if first($query) returns null.

$product = Product::firstOrFail($query);

The search($query) method returns documents according to the query.

$products = Product::search($query);

The all($query) method returns all documents (default 50 items per request) according to the query.

$products = Product::all($query);

If $query is not passed the query will be as match_all query.

Query Builder

Consider using these packages:

Testing

$ composer test

License

The MIT License (MIT).