daltcore / elasticquent
将 Laravel Eloquent 模型映射到 Elasticsearch 类型。
Requires
- php: >=5.4.0
- elasticsearch/elasticsearch: ~7.0
- illuminate/config: ~4.2|^5|^6|^7|^8
- illuminate/database: ~4.2|^5|^6|^7|^8
- nesbot/carbon: ~1.0|~2
Requires (Dev)
- mockery/mockery: ^0.9.4|^1.0
- phpunit/phpunit: ~4.2|~5.0|~8.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 错误跟踪器 报告。
或者,您可以分叉该项目并提交一个拉取请求 :)
概述
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 客户端的 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
方法将Elastiquent集合拆分为多个大小给定的较小集合
$all_books = Book::searchByQuery(array('match' => array('title' => 'Moby Dick'))); $books = $all_books->chunk(10);
在Elastiquent之外使用搜索集合
如果您正在处理Elastiquent之外的原始搜索数据,您可以使用Elastiquent搜索结果集合将数据转换为集合。
$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' ); }
请注意这一点,因为Elastiquent在创建搜索结果集合时将文档源读入Eloquent模型属性,所以请确保您正在索引足够的数据,以便使用您想要使用的模型功能。
使用自定义集合与Elastiquent一起使用
如果您正在使用自定义集合与Eloquent模型一起使用,您只需将 ElasticquentCollectionTrait
添加到您的集合中,然后您就可以使用 addToIndex
。
class MyCollection extends \Illuminate\Database\Eloquent\Collection { use ElasticquentCollectionTrait; }
路线图
Elasticquent 目前需要
- 模拟 ES API 调用的测试
- 对路由的支持