reallyli / elasticquent
将 Laravel Eloquent 模型映射到 Elasticsearch 类型。
Requires
- php: >=5.4.0
- elasticsearch/elasticsearch: ~6.1
- illuminate/config: ~4.2|^5|^6
- illuminate/database: ~4.2|^5|^6
- nesbot/carbon: ~1.0|~2
Requires (Dev)
- mockery/mockery: ^0.9.4
- phpunit/phpunit: ~4.2|~5.0
README
Elasticsearch for Eloquent Laravel Models
Elasticquent 通过将它们映射到 Elasticsearch 类型,使与 Elasticsearch 和 Eloquent 模型一起工作变得简单。您可以使用默认设置,或者在模型中定义 Elasticsearch 应如何索引和搜索您的 Eloquent 模型。
Elasticquent 使用 官方 Elasticsearch PHP API。要开始,您应该对 Elasticsearch 的工作原理有基本的了解(索引、类型、映射等)。
Elasticsearch 要求
您必须运行 至少 Elasticsearch 1.0。Elasticsearch 0.9 及以下版本 将无法工作 且不受支持。
内容
报告问题
如果您发现任何问题,请随时通过 GitHub 的错误跟踪器 报告此项目的问题。
或者,复制项目并创建一个 pull request :)
概述
Elasticquent 允许您轻松地将 Eloquent 模型索引并搜索其内容。
$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,您可以在/app/config/elasticquent.php
中添加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\Collection
,chunk
方法将 Elasticquent 集合分割成多个给定大小的更小的集合
$all_books = Book::searchByQuery(array('match' => array('title' => 'Moby Dick'))); $books = $all_books->chunk(10);
在 Elastiquent 之外使用搜索集合
如果你正在处理来自 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 调用的测试。
- 对路由的支持