Search

Search engine on Bookshelves use laravel/scout which can use Algolia or Meilisearch to use powerful search engine. If you want to use only embeded search engine, you can just set SCOUT_DRIVER into .env to collection, less efficient than meilisearch but useful for search.

.env
SCOUT_DRIVER=collection

Options available: meilisearch, algolia, collection

When you use Bookshelves for development, you can set it to collection, you won't need to have engine.

Option: Meilisearch

If you want to use a more powerful engine, you can use Meilisearch, if you configure laravel/scout with meilisearch each new model will be register into Meilisearch database.

.env
SCOUT_DRIVER=meilisearch

You have to execute meilisearch server available on same machine with right configuration.

.env
# default configuration for meilisearch
MEILISEARCH_HOST=http://127.0.0.1:7700
MEILISEARCH_KEY=

Install Meilisearch

These commands have to be used as root user.

These options are available for Linux or MacOS, for Windows, you can use WSL to install meilisearch like on Linux but you can also download latest binary to execute server.

curl -L https://install.meilisearch.com | sh
mv ./meilisearch /usr/bin/
brew update
brew install meilisearch
echo "deb [trusted=yes] https://apt.fury.io/meilisearch/ /" > /etc/apt/sources.list.d/fury.list
apt update
apt install meilisearch-http

Execute server

meilisearch

On production

On production you have to setup a service.

sudo vim /etc/systemd/system/meilisearch.service

You can change Y0urVery-S3cureAp1K3y with your master key (you will add it to .env into MEILISEARCH_KEY).

/etc/systemd/system/meilisearch.service
[Unit]
Description=MeiliSearch
After=systemd-user-sessions.service

[Service]
Type=simple
ExecStart=/usr/bin/meilisearch --http-addr 127.0.0.1:7700 --env production --master-key Y0urVery-S3cureAp1K3y

[Install]
WantedBy=default.target

Now you can enable service.

sudo systemctl enable meilisearch
sudo systemctl start meilisearch

Check if it works

sudo systemctl status meilisearch

Add NGINX domain

You can have more information on Meilisearch documentation.

/etc/nginx/sites-available/meilisearch.example.com.conf
server {
  listen 80;
  listen [::]:80;
  server_name meilisearch.example.com;

  location / {
    proxy_pass  http://127.0.0.1:7700;
  }

  access_log /var/log/nginx/meilisearch.access.log;
  error_log /var/log/nginx/meilisearch.error.log;
}

Now Meilisearch is available on http://meilisearch.example.com. You will have to update .env on MEILISEARCH_HOST with new URL.

Import models

You can import Book, Author and Serie with Bookshelves command.

php artisan bookshelves:scout

If you want to reset all models of Bookshelves, you can flush existing indexes with -f option.

php artisan bookshelves:scout -f

Test search: Meilisearch

If you have an meilisearch instance, you can check it to http://127.0.0.1:7700 (default configuration). If importation works, you will see three indexes for Book, Author and Serie and you can search into each index.

All fields you can see on each index is available for search.

Example: on Book, if title is available, Meilisearch will allow you to search on it, if you want to add description you can add into Book model toSearchableArray method, check Laravel documentation.

Usage

Into a controller, you can search with search method

Book::search('any search')->get();

Customize fields

Meilisearch check all fields but you can limit it with toSearchableArray

public function toSearchableArray()
{
  return [
    'id' => $this->id,
    'title' => $this->title,
    'date' => $this->date,
    'author' => $this->authors_names,
    'created_at' => $this->created_at,
    'updated_at' => $this->updated_at,
  ];
}

And execute again scout command with php artisan booksheves:scout -f

With API v1

You can search any entity on http://localhost:8000/api/v1/search like http://localhost:8000/api/v1/search?q=any%20title

routes/api-v1.php
Route::prefix('search')->group(function () {
  Route::get('/', [SearchController::class, 'index'])->name('api.v1.search.index');
});

You can check SearchController.php to know how search engine works, under the hood you can check SearchEngineService.php.

app/Http/Controllers/Api/SearchController.php
public function index(Request $request)
{
  $q = $request->input('q');
  $types = $request->input('types');
  if ($types) {
    $types = explode(',', $types);
  }

  if ($q) {
    $engine = SearchEngineService::create($q, $types);

    return response()->json([
      'data' => [
        'count' => $engine->results_count,
        'type' => $engine->search_type,
        'relevant' => [
          'authors' => $engine->authors_relevant,
          'series' => $engine->series_relevant,
          'books' => $engine->books_relevant,
        ],
        'other' => [
          'authors' => $engine->authors_other,
          'series' => $engine->series_other,
          'books' => $engine->books_other,
        ],
      ],
    ]);
  }
}

Troubles

No indexes on Meilisearch

If you don't see indexes on http://127.0.0.1:7700, it may be cause by cache.

php artisan cache:clear
php artisan bookshelves:scout -f

Version file is missing

Version file is missing or the previous MeiliSearch engine version was below 0.24.0. Use a dump to update MeiliSearch

When you update Meilisearch, you can have this error, you have to remove data.ms

If you delete data.ms, all indexes will be deleted.

sudo rm -rf /data.ms

Now you have to restart meilisearch.

sudo service meilisearch restart

Check if service works.

sudo service meilisearch status
Edit this page on GitHub Updated at Tue, Apr 12, 2022