designmynight/laravel-elasticsearch

使用 Elasticsearch 作为 Laravel 的数据库,以检索 Eloquent 模型并执行聚合操作。

v7.0.1 2022-03-31 10:03 UTC

README

使用 Elasticsearch 作为 Laravel 的数据库,以检索 Eloquent 模型并执行聚合操作。

使用 Eloquent 建立查询,就像您习惯的那样,并获取模型实例,还有一些额外的功能

  • 使用 queryfilterpostFilter 查询类型
  • 执行地理搜索
  • 构建和执行数据上的复杂聚合
  • 使用 Elasticsearch 滚动 API 获取大量结果

版本

根据您的 Elasticsearch 版本,您可以使用以下版本的此包

设置

将 Elasticsearch 连接配置添加到 database.php

'elasticsearch' => [
    'driver'   => 'elasticsearch',
    'host'     => 'localhost',
    'port'     => 9200,
    'database' => 'your_es_index',
    'username' => 'optional_es_username',
    'password' => 'optional_es_username',
    'suffix'   => 'optional_es_index_suffix',
]

创建或更新您的 base Model.php 类以覆盖 newEloquentBuilder()newBaseQueryBuilder()

/**
 * Create a new Eloquent builder for the model.
 *
 * @param  \Illuminate\Database\Query\Builder  $query
 * @return \Illuminate\Database\Eloquent\Builder|static
 */
public function newEloquentBuilder($query)
{
    switch ($this->getConnectionName()) {
        case static::getElasticsearchConnectionName():
            $builder = new ElasticsearchEloquentBuilder($query);
            break;

        default:
            $builder = new Illuminate\Database\Eloquent\Builder($query);
    }

    return $builder;
}

/**
 * Get a new query builder instance for the connection.
 *
 * @return \Illuminate\Database\Query\Builder
 */
protected function newBaseQueryBuilder()
{
    $connection = $this->getConnection();

    switch ($this->getConnectionName()) {
        case static::getElasticsearchConnectionName():
            $builder = new ElasticsearchQueryBuilder($connection, $connection->getQueryGrammar(), $connection->getPostProcessor());
            break;

        default:
            $builder = new Illuminate\Database\Query\Builder($connection, $connection->getPostProcessor());
    }

    return $builder;
}

搜索

现在您可以开始对数据进行搜索了。查询将寻找与您模型所在的数据库表同名的 Elasticsearch 索引。

$documents = MyModel::newElasticsearchQuery()
              ->where('date', '>', Carbon\Carbon::now())
              ->get();

聚合

可以通过类似于直接查询 Elasticsearch 的方法向查询中添加聚合,使用嵌套函数而不是嵌套数组。`aggregation()` 方法接受三个或四个参数

  1. 用于聚合的键
  2. 聚合类型,如 'filter' 或 'terms'
  3. (可选) 提供聚合选项的回调或数组
  4. (可选) 允许您提供进一步子聚合的函数
$myQuery = MyModel::newElasticsearchQuery()
             ->aggregation(
                 // The key of the aggregation (used in the Elasticsearch response)
                 'my_filter_aggregation',

                 // The type of the aggregation
                 'filter',

                 // A callback providing options to the aggregation, in this case adding filter criteria to a query builder
                 function ($query) {
                     $query->where('lost', '!=', true);
                     $query->where('concierge', true);
                 },

                 // A callback specifying a sub-aggregation
                 function ($builder) {
                     // A simpler aggregation, counting terms in the 'status' field
                     $builder->aggregation('my_terms_aggregation', 'terms', ['field' => 'status']);
                 }
             );

$results = $myQuery->get();
$aggregations = $myQuery->getQuery()->getAggregationResults();

地理查询

您可以通过距离地理点的距离来过滤搜索结果,或者仅包括给定边界内的结果,传递您用于直接查询 Elasticsearch 的格式相同的参数。

$withinDistance = MyModel::newElasticsearchQuery()
                    ->whereGeoDistance('geo_field', [$lat, $lon], $distance);

$withinBounds= MyModel::newElasticsearchQuery()
                 ->whereGeoBoundsIn('geo_field', $boundingBox);

滚动 API

您可以使用滚动搜索检索大量结果。而不是返回 Collection,您将得到一个 PHP 生成器 函数,您可以遍历它,其中每个值都是来自 Elasticsearch 的单个结果的模型。

$documents = MyModel::newElasticsearchQuery()
               ->limit(100000)
               ->usingScroll()
               ->get();

// $documents is a Generator
foreach ($documents as $document){
  echo $document->id;
}

控制台

此包附带以下命令,用作实用程序或作为您的部署过程的一部分。

映射和别名

在执行 migrate:mappings 期间创建新索引时,该命令将自动根据迁移名称创建一个别名(通过删除日期字符串)。例如,迁移 2018_08_03_095804_users.json 将创建别名 users

在第一次迁移中,migrate:mappings 命令还将别名切换到最新的索引映射。上述操作仅发生在别名不存在时。

未来的迁移将需要您使用 --swap 选项。