Skip to content

Instantly share code, notes, and snippets.

@karakhanyans
Last active May 3, 2024 13:09
Show Gist options
  • Save karakhanyans/8c61c70794a6f80c5d5d4c35d35b0adc to your computer and use it in GitHub Desktop.
Save karakhanyans/8c61c70794a6f80c5d5d4c35d35b0adc to your computer and use it in GitHub Desktop.
Typesense

Typesense

Typesense is an open source, typo tolerant search engine that is optimized for instant sub-50ms searches, while providing an intuitive developer experience.

When using the Typesense driver you will need to install the Typesense PHP SDK via the Composer package manager:

composer require typesense/typesense-php

Then, set the SCOUT_DRIVER environment variable as well as your Typesense host and API key credentials within your application's .env file:

SCOUT_DRIVER=typesense
TYPESENSE_API_KEY=xyz
TYPESENSE_HOST=localhost

You can also modify port, path and protocol accordingly:

TYPESENSE_PORT=8108
TYPESENSE_PATH=ts
TYPESENSE_PROTOCOL=https

For more information regarding Typesense, please consult the Typesense documentation.

toSearchableArray

To make your search compatible with Typsense, cast your model id to string and created_at to int32 timestamp as shown below.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;

class Todo extends Model
{
    use Searchable;
    
     /**
     * Get the indexable data array for the model.
     *
     * @return array
     */
    public function toSearchableArray()
    {
        return array_merge(
            $this->toArray(), 
            [
                // Cast id to string and turn created_at into an int32 timestamp
                // in order to maintain compatibility with the Typesense index definition below
                'id' => (string) $this->id,
                'created_at' => $this->created_at->timestamp,
            ]
        );
    }
}

Collection Schemas and Search Parameters

To setup Typesense collection schemas, in config/scout.php find typesense driver configs and modify model-settings array as shown in example below.

To modify the model query_by attributes you have to setup seach-parameters in model-settings.

Note: query_by is required parameter.

use App\Models\User;

 /*
    |--------------------------------------------------------------------------
    | Typesense Configuration
    |--------------------------------------------------------------------------
    |
    | Here you may configure your Typesense settings. Typesense is an open
    | source search engine with minimal configuration. Below, you can state
    | the host and key information for your own Typesense installation.
    |
    | See: https://typesense.org/docs/0.25.1/api/authentication.html
    |
    */

    'typesense' => [
        'client-settings' => [
            'api_key' => env('TYPESENSE_API_KEY', 'xyz'),
            'nodes' => [
                [
                    'host' => env('TYPESENSE_HOST', 'localhost'),
                    'port' => env('TYPESENSE_PORT', '8108'),
                    'path' => env('TYPESENSE_PATH', ''),
                    'protocol' => env('TYPESENSE_PROTOCOL', 'http'),
                ],
            ],
            'nearest_node' => [
                'host' => env('TYPESENSE_HOST', 'localhost'),
                'port' => env('TYPESENSE_PORT', '8108'),
                'path' => env('TYPESENSE_PATH', ''),
                'protocol' => env('TYPESENSE_PROTOCOL', 'http'),
            ],
            'connection_timeout_seconds' => env('TYPESENSE_CONNECTION_TIMEOUT_SECONDS', 2),
            'healthcheck_interval_seconds' => env('TYPESENSE_HEALTHCHECK_INTERVAL_SECONDS', 30),
            'num_retries' => env('TYPESENSE_NUM_RETRIES', 3),
            'retry_interval_seconds' => env('TYPESENSE_RETRY_INTERVAL_SECONDS', 1),
        ],
        'model-settings' => [
            User::class => [
                'collection-schema' => [
                    'fields' => [
                        [
                            'name' => 'id',
                            'type' => 'string',
                        ],
                        [
                            'name' => 'name',
                            'type' => 'string',
                        ],
                        [
                            'name' => 'created_at',
                            'type' => 'int64',
                        ],
                    ],
                    'default_sorting_field' => 'created_at',
                ],
                'search-parameters' => [ 
                    'query_by' => 'name, title' // required
                ],
            ],
        ],
    ],

Search Parameters On The Fly

To modify search parameters on the fly you can use setSearchParameters method of Typesense Engine.

use App\Models\Todo;

Todo::search('Do grocceries')->setSearchParameters(['query_by' => 'title, description'])->get();

Available search parameters:

'highlight_start_tag' => '<mark>',
'highlight_end_tag' => '</mark>',
'snippet_threshold' => 30,
'exhaustive_search' => false,
'use_cache' => false,
'cache_ttl' => 60,
'prioritize_exact_match' => true,
'enable_overrides' => true,
'highlight_affix_num_tokens' => 4,

Full list of search parameters and descriptions can be found here.

@ianwolf99
Copy link

i have a grave issuei installed and configured everything for laravel scout and typesense but i still get {
"status": "error",
"message": "nodes is not defined."
} this is very weird

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment