当前位置:首页 > PHP教程 > php环境安装 > 列表

PHP中使用ElasticSearch最新实例讲解

发布:smiling 来源: PHP粉丝网  添加日期:2022-04-18 10:34:07 浏览: 评论:0 

这篇文章主要介绍了PHP中使用ElasticSearch最新实例讲解,这篇文章的教程是比较详细,有需要的同学可以研究下。

网上很多关于ES的例子都过时了,版本很老,这篇文章的测试环境是ES6.5

通过composer安装

composer require 'elasticsearch/elasticsearch'

在代码中引入

require 'vendor/autoload.php';

use Elasticsearch\ClientBuilder;

$client = ClientBuilder::create()->setHosts(['172.16.55.53'])->build();

下面循序渐进完成一个简单的添加和搜索的功能。

首先要新建一个index:

index对应关系型数据(以下简称MySQL)里面的数据库,而不是对应MySQL里面的索引,这点要清楚。

  1. $params = [ 
  2.   'index' => 'myindex', #index的名字不能是大写和下划线开头 
  3.   'body' => [ 
  4.     'settings' => [ 
  5.       'number_of_shards' => 2, 
  6.       'number_of_replicas' => 0 
  7.     ] 
  8.   ] 
  9. ]; 
  10. $client->indices()->create($params); 

在MySQL里面,光有了数据库还不行,还需要建立表,ES也是一样的,ES中的type对应MySQL里面的表。

注意:ES6以前,一个index有多个type,就像MySQL中一个数据库有多个表一样自然,但是ES6以后,每个index只允许一个type,在往以后的版本中很可能会取消type。

type不是单独定义的,而是和字段一起定义

  1. $params = [ 
  2.   'index' => 'myindex'
  3.   'type' => 'mytype'
  4.   'body' => [ 
  5.     'mytype' => [ 
  6.       '_source' => [ 
  7.         'enabled' => true 
  8.       ], 
  9.       'properties' => [ 
  10.         'id' => [ 
  11.           'type' => 'integer' 
  12.         ], 
  13.         'first_name' => [ 
  14.           'type' => 'text'
  15.           'analyzer' => 'ik_max_word' 
  16.         ], 
  17.         'last_name' => [ 
  18.           'type' => 'text'
  19.           'analyzer' => 'ik_max_word' 
  20.         ], 
  21.         'age' => [ 
  22.           'type' => 'integer' 
  23.         ] 
  24.       ] 
  25.     ] 
  26.   ] 
  27. ]; 
  28. $client->indices()->putMapping($params); 

在定义字段的时候,可以看出每个字段可以定义单独的类型,在first_name中还自定义了分词器 ik,

这个分词器是一个插件,需要单独安装的,参考另一篇文章:ElasticSearch基本尝试

现在数据库和表都有了,可以往里面插入数据了

概念:这里的 数据 在ES中叫文档

  1. $params = [ 
  2.   'index' => 'myindex'
  3.   'type' => 'mytype'
  4.   //'id' => 1, #可以手动指定id,也可以不指定随机生成 
  5.   'body' => [ 
  6.     'first_name' => '张'
  7.     'last_name' => '三'
  8.     'age' => 35 
  9.   ] 
  10. ]; 
  11. $client->index($params); 

多插入一点数据,然后来看看怎么把数据取出来:

通过id取出单条数据:

插曲:如果你之前添加文档的时候没有传入id,ES会随机生成一个id,这个时候怎么通过id查?id是多少都不知道啊。

所以这个插入一个简单的搜索,最简单的,一个搜索条件都不要,返回所有index下所有文档:

$data = $client->search();

现在可以去找一找id了,不过你会发现id可能长这样:zU65WWgBVD80YaV8iVMk,不要惊讶,这是ES随机生成的。

现在可以通过id查找指定文档了:

  1. $params = [ 
  2.   'index' => 'myindex'
  3.   'type' => 'mytype'
  4.   'id' =>'zU65WWgBVD80YaV8iVMk' 
  5. ]; 
  6. $data = $client->get($params); 

最后一个稍微麻烦点的功能:

注意:这个例子我不打算在此详细解释,看不懂没关系,这篇文章主要的目的是基本用法,并没有涉及到ES的精髓地方,

ES精髓的地方就在于搜索,后面的文章我会继续深入分析

  1. $query = [ 
  2.   'query' => [ 
  3.     'bool' => [ 
  4.       'must' => [ 
  5.         'match' => [ 
  6.           'first_name' => '张'
  7.         ] 
  8.       ], 
  9.       'filter' => [ 
  10.         'range' => [ 
  11.           'age' => ['gt' => 76] 
  12.         ] 
  13.       ] 
  14.     ] 
  15.  
  16.   ] 
  17. ]; 
  18. $params = [ 
  19.   'index' => 'myindex'
  20. // 'index' => 'm*', #index 和 type 是可以模糊匹配的,甚至这两个参数都是可选的 
  21.   'type' => 'mytype'
  22.   '_source' => ['first_name','age'], // 请求指定的字段 
  23.   'body' => array_merge([ 
  24.     'from' => 0, 
  25.     'size' => 5 
  26.   ],$query
  27. ]; 
  28. $data = $this->EsClient->search($params); 

上面的是一个简单的使用流程,但是不够完整,只讲了添加文档,没有说怎么删除文档,

下面我贴出完整的测试代码,基于Laravel环境,当然环境只影响运行,不影响理解,包含基本的常用操作:

  1. <?php 
  2. use Elasticsearch\ClientBuilder; 
  3. use Faker\Generator as Faker; 
  4. /** 
  5. * ES 的 php 实测代码 
  6. */ 
  7. class EsDemo { 
  8.     private $EsClient = null; 
  9.     private $faker = null; 
  10.     /** 
  11. * 为了简化测试,本测试默认只操作一个Index,一个Type, 
  12. * 所以这里固定为 megacorp和employee 
  13. */ 
  14.     private $index = 'megacorp'
  15.     private $type = 'employee'
  16.     public function __construct(Faker $faker) { 
  17.         /** 
  18. * 实例化 ES 客户端 
  19. */ 
  20.         $this->EsClient = ClientBuilder::create()->setHosts(['172.16.55.53'])->build(); 
  21.         /** 
  22. * 这是一个数据生成库,详细信息可以参考网络 
  23. */ 
  24.         $this->faker = $faker
  25.     } 
  26.     /** 
  27. * 批量生成文档 
  28. * @param $num 
  29. */ 
  30.     public function generateDoc($num = 100) { 
  31.         foreach (range(1,$numas $item) { 
  32.             $this->putDoc([ 
  33.             'first_name' => $this->faker->name, 
  34.             'last_name' => $this->faker->name, 
  35.             'age' => $this->faker->numberBetween(20,80) 
  36.             ]); 
  37.         } 
  38.     } 
  39.     /** 
  40. * 删除一个文档 
  41. * @param $id 
  42. * @return array 
  43. */ 
  44.     public function delDoc($id) { 
  45.         $params = [ 
  46.         'index' => $this->index, 
  47.         'type' => $this->type, 
  48.         'id' =>$id 
  49.         ]; 
  50.         return $this->EsClient->delete($params); 
  51.     } 
  52.     /** 
  53. * 搜索文档,query是查询条件 
  54. * @param array $query 
  55. * @param int $from 
  56. * @param int $size 
  57. * @return array 
  58. */ 
  59.     public function search($query = [], $from = 0, $size = 5) { 
  60.         // $query = [ 
  61.         // 'query' => [ 
  62.         // 'bool' => [ 
  63.         // 'must' => [ 
  64.         // 'match' => [ 
  65.         // 'first_name' => 'Cronin', 
  66.         // ] 
  67.         // ], 
  68.         // 'filter' => [ 
  69.         // 'range' => [ 
  70.         // 'age' => ['gt' => 76] 
  71.         // ] 
  72.         // ] 
  73.         // ] 
  74.         // 
  75.         // ] 
  76.         // ]; 
  77.         $params = [ 
  78.         'index' => $this->index, 
  79.         // 'index' => 'm*', #index 和 type 是可以模糊匹配的,甚至这两个参数都是可选的 
  80.         'type' => $this->type, 
  81.         '_source' => ['first_name','age'], // 请求指定的字段 
  82.         'body' => array_merge([ 
  83.         'from' => $from
  84.         'size' => $size 
  85.         ],$query
  86.         ]; 
  87.         return $this->EsClient->search($params); 
  88.     } 
  89.     /** 
  90. * 一次获取多个文档 
  91. * @param $ids 
  92. * @return array 
  93. */ 
  94.     public function getDocs($ids) { 
  95.         $params = [ 
  96.         'index' => $this->index, 
  97.         'type' => $this->type, 
  98.         'body' => ['ids' => $ids
  99.         ]; 
  100.         return $this->EsClient->mget($params); 
  101.     } 
  102.     /** 
  103. * 获取单个文档 
  104. * @param $id 
  105. * @return array 
  106. */ 
  107.     public function getDoc($id) { 
  108.         $params = [ 
  109.         'index' => $this->index, 
  110.         'type' => $this->type, 
  111.         'id' =>$id 
  112.         ]; 
  113.         return $this->EsClient->get($params); 
  114.     } 
  115.     /** 
  116. * 更新一个文档 
  117. * @param $id 
  118. * @return array 
  119. */ 
  120.     public function updateDoc($id) { 
  121.         $params = [ 
  122.         'index' => $this->index, 
  123.         'type' => $this->type, 
  124.         'id' =>$id
  125.         'body' => [ 
  126.         'doc' => [ 
  127.         'first_name' => '张'
  128.         'last_name' => '三'
  129.         'age' => 99 
  130.         ] 
  131.         ] 
  132.         ]; 
  133.         return $this->EsClient->update($params); 
  134.     } 
  135.     /** 
  136. * 添加一个文档到 Index 的Type中 
  137. * @param array $body 
  138. * @return void 
  139. */ 
  140.     public function putDoc($body = []) { 
  141.         $params = [ 
  142.         'index' => $this->index, 
  143.         'type' => $this->type, 
  144.         // 'id' => 1, #可以手动指定id,也可以不指定随机生成 
  145.         'body' => $body 
  146.         ]; 
  147.         $this->EsClient->index($params); 
  148.     } 
  149.     /** 
  150. * 删除所有的 Index 
  151. */ 
  152.     public function delAllIndex() { 
  153.         $indexList = $this->esStatus()['indices']; 
  154.         foreach ($indexList as $item => $index) { 
  155.             $this->delIndex(); 
  156.         } 
  157.     } 
  158.     /** 
  159. * 获取 ES 的状态信息,包括index 列表 
  160. * @return array 
  161. */ 
  162.     public function esStatus() { 
  163.         return $this->EsClient->indices()->stats(); 
  164.     } 
  165.     /** 
  166. * 创建一个索引 Index (非关系型数据库里面那个索引,而是关系型数据里面的数据库的意思) 
  167. * @return void 
  168. */ 
  169.     public function createIndex() { 
  170.         $this->delIndex(); 
  171.         $params = [ 
  172.         'index' => $this->index, 
  173.         'body' => [ 
  174.         'settings' => [ 
  175.         'number_of_shards' => 2, 
  176.         'number_of_replicas' => 0 
  177.         ] 
  178.         ] 
  179.         ]; 
  180.         $this->EsClient->indices()->create($params); 
  181.     } 
  182.     /** 
  183. * 检查Index 是否存在 
  184. * @return bool 
  185. */ 
  186.     public function checkIndexExists() { 
  187.         $params = [ 
  188.         'index' => $this->index 
  189.         ]; 
  190.         return $this->EsClient->indices()->exists($params); 
  191.     } 
  192.     /** 
  193. * 删除一个Index 
  194. * @return void 
  195. */ 
  196.     public function delIndex() { 
  197.         $params = [ 
  198.         'index' => $this->index 
  199.         ]; 
  200.         if ($this->checkIndexExists()) { 
  201.             $this->EsClient->indices()->delete($params); 
  202.         } 
  203.     } 
  204.     /** 
  205. * 获取Index的文档模板信息 
  206. * @return array 
  207. */ 
  208.     public function getMapping() { 
  209.         $params = [ 
  210.         'index' => $this->index 
  211.         ]; 
  212.         return $this->EsClient->indices()->getMapping($params); 
  213.     } 
  214.     /** 
  215. * 创建文档模板 
  216. * @return void 
  217. */ 
  218.     public function createMapping() { 
  219.         $this->createIndex(); 
  220.         $params = [ 
  221.         'index' => $this->index, 
  222.         'type' => $this->type, 
  223.         'body' => [ 
  224.         $this->type => [ 
  225.         '_source' => [ 
  226.         'enabled' => true 
  227.         ], 
  228.         'properties' => [ 
  229.         'id' => [ 
  230.         'type' => 'integer' 
  231.         ], 
  232.         'first_name' => [ 
  233.         'type' => 'text'
  234.         'analyzer' => 'ik_max_word' 
  235.         ], 
  236.         'last_name' => [ 
  237.         'type' => 'text'
  238.         'analyzer' => 'ik_max_word' 
  239.         ], 
  240.         'age' => [ 
  241.         'type' => 'integer' 
  242.         ] 
  243.         ] 
  244.         ] 
  245.         ] 
  246.         ]; 
  247.         $this->EsClient->indices()->putMapping($params); 
  248.         $this->generateDoc(); 
  249.     } 
  250. }

Tags: ElasticSearch

分享到: