uniqueway/elasticquent

将 Laravel Eloquent 模型映射到 Elasticsearch 类型。

v1.0.7 2019-06-24 04:45 UTC

README

Elasticsearch for Eloquent Laravel Models

Elasticquent 通过将 Eloquent 模型映射到 Elasticsearch 类型,使与 Elasticsearch 和 Eloquent 模型的工作变得更简单。您可以使用默认设置,也可以在模型中直接定义 Elasticsearch 如何索引和搜索您的 Eloquent 模型。

Elasticquent 使用 官方 Elasticsearch PHP API。要开始使用,您应该对 Elasticsearch 的工作原理有基本的了解(索引、类型、映射等)。

Elasticsearch 要求

您必须运行 至少 Elasticsearch 1.0。Elasticsearch 0.9 及以下版本 将不会工作 且不受支持。

内容

报告问题

如果您发现任何问题,请随时通过 GitHub 的错误追踪器 报告此项目的问题。

或者,将该项目分支出来并创建一个 pull request :)

概述

Elasticquent 允许您轻松地将 Eloquent 模型索引并搜索其内容在 Elasticsearch 中。

    $books = Book::where('id', '<', 200)->get();
    $books->addToIndex();

当您进行搜索时,您将得到一个具有特殊 Elasticsearch 功能的 Eloquent 集合,而不是一个普通的搜索结果数组。

    $books = Book::search('Moby Dick');
    echo $books->totalHits();

此外,您仍然可以使用所有 Eloquent 集合功能

    $books = $books->filter(function ($book) {
        return $book->hasISBN();
    });

查看其余的文档,了解如何开始使用 Elasticsearch 和 Elasticquent!

Elasticquent 的工作原理

当使用数据库时,Eloquent 模型是从数据库表中读取的数据填充的。使用 Elasticquent,模型是通过索引在 Elasticsearch 中的数据进行填充的。使用 Elasticsearch 进行搜索的整个想法是它快速且轻量级,因此您模型的功能将由已为您的文档索引的数据决定。

设置

在开始使用 Elasticquent 之前,请确保您已安装 Elasticsearch

要开始使用,将 Elasticquent 添加到您的 composer.json 文件

"elasticquent/elasticquent": "dev-master"

运行 composer update 后,您需要在您的 config/app.php 中注册 Laravel 服务提供者

'providers' => [
    ...
    Elasticquent\ElasticquentServiceProvider::class,
],

我们还为 elasticsearch-php 客户端(已使用我们的设置连接)提供了一个 facade,如果需要,请将以下内容添加到您的 config/app.php

'aliases' => [
    ...
    'Es' => Elasticquent\ElasticquentElasticsearchFacade::class,
],

然后,将 Elasticquent 特性添加到任何您想要在 Elasticsearch 中索引的 Eloquent 模型中

use Elasticquent\ElasticquentTrait;

class Book extends Eloquent
{
    use ElasticquentTrait;
}

现在,您的 Eloquent 模型有一些额外的功能,这使得使用 Elasticsearch 索引模型数据变得更容易。

Elasticsearch 配置

默认情况下,Elasticquent 将连接到 localhost:9200 并使用 default 作为索引名称,您可以在配置文件中更改这些以及其他设置。您可以在 Laravel 4 中将 elasticquent.php 配置文件添加到 /app/config/elasticquent.php,或者使用以下 Artisan 命令将配置文件发布到您的配置目录中(Laravel 5)

$ php artisan vendor:publish --provider="Elasticquent\ElasticquentServiceProvider"
<?php

return array(

    /*
    |--------------------------------------------------------------------------
    | Custom Elasticsearch Client Configuration
    |--------------------------------------------------------------------------
    |
    | This array will be passed to the Elasticsearch client.
    | See configuration options here:
    |
    | http://www.elasticsearch.org/guide/en/elasticsearch/client/php-api/current/_configuration.html
    */

    'config' => [
        'hosts'     => ['localhost:9200'],
        'retries'   => 1,
    ],

    /*
    |--------------------------------------------------------------------------
    | Default Index Name
    |--------------------------------------------------------------------------
    |
    | This is the index name that Elastiquent will use for all
    | Elastiquent models.
    */

    'default_index' => 'my_custom_index_name',

);

索引和映射

虽然您可以通过Elasticsearch API构建索引和映射,但您还可以使用一些辅助方法直接从模型中构建索引和类型。

如果您想简单创建索引,Elasticquent模型有一个这样的功能

Book::createIndex($shards = null, $replicas = null);

对于自定义分析器,您可以在模型中设置一个indexSettings属性并从那里定义分析器

    /**
     * The elasticsearch settings.
     *
     * @var array
     */
    protected $indexSettings = [
        'analysis' => [
            'char_filter' => [
                'replace' => [
                    'type' => 'mapping',
                    'mappings' => [
                        '&=> and '
                    ],
                ],
            ],
            'filter' => [
                'word_delimiter' => [
                    'type' => 'word_delimiter',
                    'split_on_numerics' => false,
                    'split_on_case_change' => true,
                    'generate_word_parts' => true,
                    'generate_number_parts' => true,
                    'catenate_all' => true,
                    'preserve_original' => true,
                    'catenate_numbers' => true,
                ]
            ],
            'analyzer' => [
                'default' => [
                    'type' => 'custom',
                    'char_filter' => [
                        'html_strip',
                        'replace',
                    ],
                    'tokenizer' => 'whitespace',
                    'filter' => [
                        'lowercase',
                        'word_delimiter',
                    ],
                ],
            ],
        ],
    ];

对于映射,您可以在模型中设置一个mappingProperties属性并使用一些映射函数

protected $mappingProperties = array(
   'title' => array(
        'type' => 'string',
        'analyzer' => 'standard'
    )
);

如果您想根据映射属性设置模型类型的映射,可以使用

    Book::putMapping($ignoreConflicts = true);

要删除映射

    Book::deleteMapping();

要重建(删除并重新添加,当您对映射进行重要更改时很有用)映射

    Book::rebuildMapping();

您还可以获取类型映射并检查它是否存在。

    Book::mappingExists();
    Book::getMapping();

设置自定义索引名称

默认情况下,Elasticquent将在您的配置文件(config/elasticquent.php)中查找default_index键。要设置索引的默认值,您可以编辑此文件并设置default_index

return array(

   // Other configuration keys ...
   
   /*
    |--------------------------------------------------------------------------
    | Default Index Name
    |--------------------------------------------------------------------------
    |
    | This is the index name that Elastiquent will use for all
    | Elastiquent models.
    */
    
   'default_index' => 'my_custom_index_name',
);

如果您想有一个更动态的索引,您也可以通过在Eloquent模型内部重写getIndexName方法来覆盖默认配置

function getIndexName()
{
    return 'custom_index_name';
}

注意:如果没有指定索引,Elasticquent将使用硬编码的字符串default

设置自定义类型名称

默认情况下,Elasticquent将使用模型表的名称作为索引的类型名称。如果您想覆盖它,可以使用getTypeName函数。

function getTypeName()
{
    return 'custom_type_name';
}

要检查Elasticquent模型类型的存在,使用typeExists

    $typeExists = Book::typeExists();

索引文档

要索引Eloquent模型中的所有条目,使用addAllToIndex

    Book::addAllToIndex();

您还可以索引模型集合

    $books = Book::where('id', '<', 200)->get();
    $books->addToIndex();

您也可以索引单个条目

    $book = Book::find($id);
    $book->addToIndex();

您还可以重新索引整个模型

    Book::reindex();

搜索

Elasticquent中有三种搜索方式。所有三种方法都返回一个搜索集合。

简单词项搜索

第一种方法是一个简单的词项搜索,搜索所有字段。

    $books = Book::search('Moby Dick');

基于查询的搜索

第二种是基于查询的搜索,用于更复杂的搜索需求

    public static function searchByQuery($query = null, $aggregations = null, $sourceFields = null, $limit = null, $offset = null, $sort = null)

示例

    $books = Book::searchByQuery(array('match' => array('title' => 'Moby Dick')));

以下是可用参数列表

  • query - 您的ElasticSearch查询
  • aggregations - 您希望返回的聚合。 有关聚合的详细信息,请参阅聚合
  • sourceFields - 仅限制返回集合为所选字段
  • limit - 要返回的记录数
  • offset - 设置记录偏移量(用于分页结果)
  • sort - 您的排序查询

原始查询

最后一种方法是发送到Elasticsearch的原始查询。此方法在搜索Elasticsearch中的记录时将提供最大灵活性

    $books = Book::complexSearch(array(
        'body' => array(
            'query' => array(
                'match' => array(
                    'title' => 'Moby Dick'
                )
            )
        )
    ));

这相当于

    $books = Book::searchByQuery(array('match' => array('title' => 'Moby Dick')));

搜索集合

当您在Elasticquent模型上搜索时,您会获得一个带有一些特殊功能的搜索集合。

您可以获取总命中数

    $books->totalHits();

访问分片数组

    $books->shards();

访问最大分数

    $books->maxScore();

访问超时布尔属性

    $books->timedOut();

并且访问took属性

    $books->took();

并且访问搜索聚合 - 有关聚合的详细信息,请参阅聚合

    $books->getAggregations();

搜索集合文档

搜索结果集合中的条目将具有来自Elasticsearch的一些额外数据。您始终可以使用isDocument函数检查模型是否是文档

    $book->isDocument();

您可以使用以下内容检查Elasticsearch分配给此文档的文档分数

    $book->documentScore();

从 Elastiquent 分块结果

类似于Illuminate\Support\Collectionchunk方法将Elasticquent集合拆分为多个较小、给定大小的集合

    $all_books = Book::searchByQuery(array('match' => array('title' => 'Moby Dick')));
    $books = $all_books->chunk(10);

在 Elasticquent 之外使用搜索集合

如果您正在处理来自Elasticquent之外的原始搜索数据,您可以使用Elasticquent搜索结果集合将那些数据转换为集合。

$client = new \Elasticsearch\Client();

$params = array(
    'index' => 'default',
    'type'  => 'books'
);

$params['body']['query']['match']['title'] = 'Moby Dick';

$collection = Book::hydrateElasticsearchResult($client->search($params));

更多选项

文档ID

Elasticquent 将使用您为 Eloquent 模型设置的 primaryKey 作为 Elasticsearch 文档的 id。

文档数据

默认情况下,Elasticquent 将使用整个属性数组为您的 Elasticsearch 文档。但是,如果您想自定义搜索文档的结构,您可以设置一个 getIndexDocumentData 函数,该函数返回您自己的自定义文档数组。

function getIndexDocumentData()
{
    return array(
        'id'      => $this->id,
        'title'   => $this->title,
        'custom'  => 'variable'
    );
}

请注意这一点,因为当创建搜索结果集合时,Elasticquent 会将文档源读取到 Eloquent 模型属性中,所以请确保您索引了足够的数据以支持您想要使用的模型功能。

使用自定义集合与 Elasticquent 结合

如果您正在使用自定义集合与 Eloquent 模型一起使用,您只需要将 ElasticquentCollectionTrait 添加到您的集合中,这样您就可以使用 addToIndex

class MyCollection extends \Illuminate\Database\Eloquent\Collection
{
    use ElasticquentCollectionTrait;
}

路线图

Elasticquent 当前需要

  • 模拟 ES API 调用的测试。
  • 路由支持