torann / elasticquent
将Laravel Eloquent模型映射到Elasticsearch类型。
Requires
- php: >=5.5.0
- elasticsearch/elasticsearch: >2.0 <2.2
- illuminate/config: ~5.2
- illuminate/database: ~5.2
- illuminate/support: ~5.2
Requires (Dev)
- mockery/mockery: ^0.9.4
- phpunit/phpunit: ~4.2|~5.0
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的bug tracker为此项目报告。
或者,分支项目并提交一个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。
从命令行运行
$ composer require torann/elasticquent
安装完成后,您需要将服务提供程序注册到应用程序中。打开config/app.php
并找到providers
键。
'providers' => [ ... Elasticquent\ElasticquentServiceProvider::class, ],
然后,将Elasticquent trait添加到任何您希望能够在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 [ /* |-------------------------------------------------------------------------- | 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', /* |-------------------------------------------------------------------------- | Default Index Settings |-------------------------------------------------------------------------- | | This is the settings used when creating an Elasticsearch index. | | 'default_settings' => [ | 'number_of_shards' => 1, | 'analysis' => [ | 'filter' => [ | 'autocomplete_filter' => [ | 'type' => 'edge_ngram', | 'min_gram' => 1, | 'max_gram' => 20, | ], | ], | 'analyzer' => [ | 'autocomplete' => [ | 'type' => 'custom', | 'tokenizer' => 'standard', | 'filter' => [ | 'lowercase', | 'autocomplete_filter', | ], | ], | ], | ], | ], */ 'default_settings' => null, ];
索引和映射
虽然您当然可以通过Elasticsearch API构建索引和映射,但您也可以使用一些辅助方法直接从模型中构建索引和类型。
对于自定义分析器,您可以在config/elasticquent.php
文件中设置一个default_settings
属性。
[ 'default_settings' => [ 'number_of_shards' => 1, 'analysis' => [ 'filter' => [ 'autocomplete_filter' => [ 'type' => 'edge_ngram', 'min_gram' => 1, 'max_gram' => 20, ], ], 'analyzer' => [ 'autocomplete' => [ 'type' => 'custom', 'tokenizer' => 'standard', 'filter' => [ 'lowercase', 'autocomplete_filter', ], ], ], ], ], ]
对于映射,您可以在模型中设置一个mappingProperties
属性,并从中使用一些映射函数。
protected $mappingProperties = [ 'title' => [ '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 [ // 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();
Artisan命令
es:install
创建Elasticsearch索引。
es:uninstall
删除Elasticsearch索引。
es:map <action> <model>
初始化Eloquent模型。
参数
action Mapping action to perform (add or remove)
model Name or comma separated names of the model(s) to initialize
es:index [options] [--] <model>
索引或重新索引Eloquent模型中的所有条目。
参数
model Name or comma separated names of the model(s) to index
搜索
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([ 'match' => ['title' => 'Moby Dick'] ]);
以下是可用的参数列表
query
- 您的ElasticSearch查询aggregations
- 您希望返回的聚合。有关聚合的详细信息,请参阅聚合。sourceFields
- 限制返回集仅为所选字段limit
- 返回的记录数offset
- 设置记录偏移量(用于分页结果)sort
- 您的排序查询
原始查询
最后一种方法是发送到Elasticsearch的原始查询。此方法在搜索Elasticsearch中的记录时提供了最大的灵活性。
$books = Book::complexSearch([ 'body' => [ 'query' => [ 'match' => [ 'title' => 'Moby Dick' ] ] ] ]);
这相当于
$books = Book::searchByQuery(['match' => ['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(['match' => ['title' => 'Moby Dick']]); $books = $all_books->chunk(10);
在Elastiquent外部使用搜索集合
如果您正在处理来自Elasticquent之外的原始搜索数据,您可以使用Elasticquent搜索结果集合将该数据转换为集合。
$client = new \Elasticsearch\Client(); $params = [ '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 [ '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 调用的测试。