y80x86ol / elasticsearch
use elasticsearch dsl query for laravel5
Installs: 3 687
Dependents: 0
Suggesters: 0
Security: 0
Stars: 6
Watchers: 0
Forks: 1
Open Issues: 0
Requires
- php: >=7.0.0
- elasticsearch/elasticsearch: ^6.0
README
使用Elasticsearch原生的Query DSL方式进行查询。
不和laravel的model进行直接绑定,所有操作独立于laravel的model的CURD
项目目的
1、laravel的scout方式无法满足当前项目业务的快速发展需求
2、不想使用其他的ORM操作方式,太增加学习和维护成本
所以基于官方的SDK进行了一些简单封装,来满足当前项目的业务场景
当前版本
当前版本为V1.1,当前版本稳定可用,并不定期维护和更新
注意事项
1、目前暂未对ES7.0+进行测试
2、当前版本有些地方实现比较简单,将在后期做优化调整完善
3、暂时没有加入ES的路由和别名相关操作,只能手动维护,后续将加入该功能
4、当前的版本能满足大多数情况的使用,一些ES的最佳实践暂未加入,待后续加入
支持的版本
Elasticsearch
V5.0+
V6.0+
Laravel
V5.0+
安装及配置
使用composer进行安装
composer require y80x86ol\elasticsearch
在config/app.php中的providers添加
Ken\Elasticsearch\ElasticsearchserviceProvider::class,
发布配置文件
php artisan vendor:publish --provider="Ken\Elasticsearch\ElasticsearchServiceProvider"
如何使用
数据导入
- 首先我们来写一个model
我们使用laravel框架默认的Users.php模型,
在app下面建立一个example文件夹,在文件夹中建立ExampleModel.php文件,并输入如下内容
<?php
namespace Ken\Elasticsearch\Example;
use Ken\Elasticsearch\Model;
use App\Users;
/**
* 测试模型
*
* @package Ken\Elasticsearch
*/
class ExampleModel extends Model
{
/**
* 搜索的索引
*
* @var string
*/
public $searchIndexAs = 'example_test';
/**
* 搜索的类型
*
* @var string
*/
public $searchTypeAs = 'example_test';
/**
* 关联模型
*
* @var string
*/
public $relationModel = Users::class;
/**
* 定义有哪些字段需要搜索
*
* @return array
*/
public function toSearchableArray()
{
$array = [
'id' => $this->model->id, //主键ID
'username' => $this->model->username, //名称
'created_at' => $this->model->created_at, //开始时间
'updated_at' => $this->model->updated_at, //结束时间
];
return $array;
}
}
- 修改配置文件
你需要准备两个初始化文件,一个是基础的mapping模板,一个是索引创建模板,你可以参考example文件夹目录下的TemplateDsl.php和TemplateIndexDsl.php文件
/**
* 批量导入的模型列表
*/
'import_models' => [
'Ken\Elasticsearch\Example\ExampleModel'
],
/**
* 初始化的template和index
*/
'init' => [
'templates' => [
'Ken\Elasticsearch\Example\TemplateDsl' //如果没有模板可以去掉该值,模板请参考'Ken\Elasticsearch\Example\TemplateDsl'
],
'indexs' => [
'Ken\Elasticsearch\Example\TemplateIndexDsl' //如果没有模板可以去掉该值,模板请参考'Ken\Elasticsearch\Example\TemplateIndexDsl'
]
],
-
初始化es
php artisan es:init
或者导入指定的模板
php artisan es:init --template='Ken\Elasticsearch\Example\TemplateDsl'
php artisan es:init --index='Ken\Elasticsearch\Example\TemplateIndexDsl'
也可以合并在一起执行
php artisan es:init --template='Ken\Elasticsearch\Example\TemplateDsl' --index='Ken\Elasticsearch\Example\TemplateIndexDsl'
-
使用命令导入数据库指定表数据
php artisan es:import
或者导入指定的模型
php artisan es:import --modelName='Ken\Elasticsearch\Example\ExampleModel'
使用代码导入
导入全部数据
$result = (new ExampleModel())->import();
或
$result = ExampleModel::import();
导入指定数据
$result = (new ExampleModel())->index(1);
或
$result = ExampleModel::index(1);
文档操作
- 索引一篇文档
在query中填写dsl查询
return [
'id' => '500',
'body' => [
'name' => '单独索引文档'
]
];
在controller中使用
$result = ExampleModel::query(IndexDsl::class)->index();
- 更新一篇文档
在query中填写dsl查询
return [
'id' => '2',
'body' => [
'doc' => [
'name' => '我是部分更新内容'
]
]
];
在controller中使用
$result = ExampleModel::query(ExampleDsl::class)->update();
- 删除一篇文档
在query中填写dsl查询
return [
"id" => '3'
];
在controller中使用
$result = ExampleModel::query(ExampleDsl::class)->delete();
- 批量索引文档
在query中填写dsl查询
return [
[
'id' => '5000',
'body' => [
'id' => 5000,
'name' => '批量索引文档1'
]
],
[
'id' => '5001',
'body' => [
'id' => 5000,
'name' => '批量索引文档2'
]
]
];
在controller中使用
$result = ExampleModel::query(ExampleDsl::class)->bulk();
基础查询
- 获取一篇文档
在query中填写dsl查询
public function query()
{
return [
"id" => '2'
];
}
在controller中使用
$result = ExampleModel::query(ExampleDsl::class)->get();
2.获取多篇文档
在query中填写dsl查询
public function query()
{
return [
"ids" => [2, 3]
];
}
在controller中使用
$result = ExampleModel::query(ExampleDsl::class)->gets();
3.获取多篇文档(mget方法,推荐使用这种方法获取)
在query中填写dsl查询
return [
"body" => [
"ids" => [2, 3]
]
];
在controller中使用
$result = ExampleModel::query(ExampleDsl::class)->mget();
4.普通搜索
在query中填写dsl查询
return [
"body" => [
"query" => [
"match" => [
"name" => $this->params['name']
]
]
]
];
在controller中使用
$result = ExampleModel::query(ExampleDsl::class, ['name' => '测试'])->search()->get();
5.带过滤的查询
在query中填写dsl查询
return [
"body" => [
"query" => [
"bool" => [
"must" => [
"match" => [
"name" => "测试"
]
],
"filter" => [
"term" => [
"name" => "编程"
]
]
]
]
]
];
在controller中使用
$result = ExampleModel::query(ExampleDsl::class, ['name' => '测试'])->search()->get();
6.聚合查询
在query中填写dsl查询
return [
"body" => [
"size" => 0,
"aggs" => [
"order_by_course_type" => [
"terms" => [
"field" => "course_type"
]
]
]
]
];
在controller中使用
$result = ExampleModel::query(ExampleDsl::class, ['name' => '测试'])->search()->getAggregations();
简化查询
有时候我们的查询非常简单,并不想使用一个文件来存储query,那么可以使用queryArray()方法
$result = ExampleModel::queryArray(["id" => '8'])->get();
查询结果处理
当我们使用search进行搜索的时候,针对结果我们可以使用以下方法来获得更加具体的数据
-
get() 获取完整的数据结果
-
getHits() 获取命中hits结果
-
getAggregations() 获取聚合搜索结果
-
getHitsTotal() 获取命中总数
-
getHitsMaxScore() 获取命中的最大分数
以上方法并不是所有search搜索通用的,比如mget查询的时候只能使用get()方法,比如聚合搜索的时候只有getAggregations()才能获得最终处理过的结果,所以你需要知道elasticsearch的具体查询会返回什么样的结果,然后选择具体的返回结果,不然调用了其他方法可能只会给你返回空。
也比如,你使用了filter过滤器,这个使用评分就无效了,可能结果直接就是1.0,所以调用getHitsMaxScore()就不会存在什么意义了。
版本
V1.1 2019-04-11
- 增加简单的queryBuilder查询构造器
- 修复相关bug
- 优化了相关的代码和注释
- 封装了分页结果处理功能
- 将命令操作注入移入到扩展加载时期
V1.0 2019-03-11
- 基础配置
- 命令初始化与数据导入
- 单个数据导入
- 批量数据导入
- 普通DSL查询搜索
- 普通DSL查询搜索结果处理
- 直接使用原生的Elasticsearch php sdk调用
- 实例代码