当前位置:首页 > PHP教程 > php应用 > 列表

php操作ElasticSearch搜索引擎流程详解

发布:smiling 来源: PHP粉丝网  添加日期:2022-05-18 08:55:34 浏览: 评论:0 

ElasticSearch是一个基于Lucene的搜索引擎,是用Java语言开发的,能够达到实时搜索,稳定,可靠,快速,安装使用方便,作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎,是最受欢迎的企业搜索引擎。

〝 古人学问遗无力,少壮功夫老始成 〞

如果这篇文章能给你带来一点帮助,希望给飞兔小哥哥一键三连,表示支持,谢谢各位小伙伴们。

一、安装

通过composer安装

composer require 'elasticsearch/elasticsearch'

二、使用

创建ES类

  1. <?php 
  2.    
  3. require 'vendor/autoload.php'
  4.    
  5. //如果未设置密码 
  6. $es = \Elasticsearch\ClientBuilder::create()->setHosts(['xxx.xxx.xxx.xxx'])->build(); 
  7.    
  8. //如果es设置了密码 
  9. $es = \Elasticsearch\ClientBuilder::create()->setHosts(['http://username:password@xxx.xxx.xxx.xxx:9200'])->build() 

三、新建ES数据库

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

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

四、创建表

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

ES中的type对应MySQL里面的表

ES6以前,一个index有多个type,就像MySQL中一个数据库有多个表一样

但是ES6以后,每个index只允许一个type

在定义字段的时候,可以看出每个字段可以定义单独的类型

在first_name中还自定义了 分词器 ik,这是个插件,是需要单独安装的

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

五、插入数据

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

在ES里面的数据叫文档

可以多插入一些数据,等会可以模拟搜索功能

  1. <?php 
  2. $params = [ 
  3.     'index' => 'autofelix_db'
  4.     'type' => 'autofelix_table'
  5.     //'id' => 1, #可以手动指定id,也可以不指定随机生成 
  6.     'body' => [ 
  7.         'first_name' => '飞'
  8.         'last_name' => '兔'
  9.         'age' => 26 
  10.     ] 
  11. ]; 
  12. $es->index($params); 

六、 查询所有数据

  1. <?php 
  2. $data = $es->search(); 
  3.    
  4. var_dump($data); 

七、查询单条数据

如果你在插入数据的时候指定了id,就可以查询的时候加上id

如果你在插入的时候未指定id,系统将会自动生成id,你可以通过查询所有数据后查看其id

  1. <?php 
  2. $params = [ 
  3.     'index' => 'autofelix_db'
  4.     'type' => 'autofelix_table'
  5.     'id' =>  //你插入数据时候的id 
  6. ]; 
  7. $data = $es->get($params); 

八、搜索

ES精髓的地方就在于搜索

  1. <?php 
  2. $params = [ 
  3.     'index' => 'autofelix_db'
  4.     'type' => 'autofelix_table'
  5.     'body' => [ 
  6.         'query' => [ 
  7.             'constant_score' => [ //非评分模式执行 
  8.                 'filter' => [ //过滤器,不会计算相关度,速度快 
  9.                     'term' => [ //精确查找,不支持多个条件 
  10.                         'first_name' => '飞' 
  11.                     ] 
  12.                 ] 
  13.             ] 
  14.         ] 
  15.     ] 
  16. ]; 
  17.    
  18. $data = $es->search($params); 
  19. var_dump($data); 

九、测试代码

基于Laravel环境,包含删除数据库,删除文档等操作

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

Tags: ElasticSearch

分享到: