elasticsearch-php工具类的编写,带分页&排序


 

es 5.4.0

ik 5.4.0

php 5.6

======================================

自己编写php的elasticsearch的增删改查的类:=》带有ik中文分词的功能

ik的安装文档:http://www.cnblogs.com/meiping/p/7423563.html

 

1、初始化客户端

require 'vendor/autoload.php';

use Elasticsearch\ClientBuilder;

$client = ClientBuilder::create()->build();

 

 

2、创建索引

$indexParams = [
'index' => $dbName, ## 索引:数据库
];
$client->indices()->create($indexParams);

 

 

3、设置全文检索的配置 mapping

// 准备好需要配置的字段和字段类型,用来配置mapping
$data = [  ## 尽量正确写对字段的数据类型,以及相关配置,否则后续排序,可能会报错!!!
  'title'=>'string', ## 字段title,字段类型string
  'content'=>'text',   ## 字段content,字段类型text 
  'add_time'=>'long'    ## 字段add_time,字段类型long,数字类型
]
$indexParam =[
    'index' => $dbName,   ## 索引:数据库
'type' => $tbName, ## 类型:数据表
];
$mapParam = [];
foreach ($data as $field=>$field_type){
  if($field_type == 'text' || $field_type == 'string'){   ## 需要做全文检索的ik中文分词配置
      $mapParam[$field] = [
  'type' => $field_type,
  'analyzer' => 'ik_max_word',   
  'search_analyzer' => 'ik_max_word'    
  ];
  }elseif ($field_type == 'integer' || $field_type == 'long'){ ## 数值型的字段,就不需要配置ik中文分词的全文检索了!
  $mapParam[$field] = [
  'type' => $field_type
  ];
  }else{
  $mapParam[$field] = [
  'type' => $field_type
  ];
  }
 }
$indexParam['body'][$indexParam['type']]['properties'] = $mapParam;
$client->indices()->putMapping($indexParam);

 

 

4、添加数据

// 准备好添加的数据:
$data = [
  'id'=>'1',
  'title'=>'我是标题', ## 字段title,字段值
  'content'=>'我是内容'   ## 字段content,字段值 
]
$params = [
    'index' => $dbName,   ## 索引:数据库
'type' => $tbName, ## 类型:数据表
];
if(array_key_exists('id', $data)){ ## 我把数据里的id取出来,做es的数据的唯一标识了,我觉得保持一致方便删除数据。
$params['id'] = $data['id'];
}
$params['body'] = $data;
$r = $client->index($params);

 

 

5、满足单个字段的条件查询(简单查询,不带分页&排序)

 // 准备好需要查询的条件
$data = [
  'content'=>'中国'
];
$param = [
    'index' => $dbName,   ## 索引:数据库
'type' => $tbName, ## 类型:数据表
];
$query = [
'match'=>[
$field=>[
'query'=>$data[$field],
'minimum_should_match'=>'90%'
]
]
];
// 高亮
$highlight = [
'fields'=> [
$field=>[
'pre_tags'=>'<strong>',
'post_tags'=>'</strong>'
]
]
];
$params['body']['query'] = $query;
$params['body']['highlight'] = $highlight;
$r = $client->search($params);

 =》为了业务需求,发现有下面这个“满足多字段的条件查询”的方法,即使有时候偷懒查询一个字段,也可以用下面这个方法!

 

6、满足多字段的条件查询(+“分页”,+“排序”)

// 准备好自定义的查询条件!
$data = [
  'content'=>[
    'fulltext'=>[
      'title,content'=>'中国'     ## 多个字段(title、content)同时满足某一个查询条件,多个字段用“,”隔开!
    ],
    'gt'=>[                
## 设定gt为等于条件的,用于筛选数据!
      'category_id'=>'1'      
    ] 
  ],

  'es_size'=>'15',      ## 每页显示15条
  'es_from'=>'0',        ## 从第几条开始,从0开始
  'es_sort'=>'add_time'      ## 自定义的排序字段
];
$params = [
 'index' => $dbName, ## 索引:数据库
'type' => $tbName, ## 类型:数据表
];
// 分页
if(array_key_exists('es_size', $data) && array_key_exists('es_from', $data)){
$params['size'] = $data['es_size'];
$params['from'] = $data['es_from'];
unset($data['es_size']);
unset($data['es_from']);
}
// 排序:如果使用的是best_fields,不太适合使用按照时间排序,会影响相关度靠前的排序!
 if(array_key_exists('es_sort', $data)){ ## 一开始,怎么都会报错!后来,只要给需要排序的字段设置正确的数据类型就不会在报错!我这里的排序的字段是add_time设置成long类型!
$params['body']['sort'] = [
$data['es_sort'] => 'desc'
];
unset($data['es_sort']);
}
$field = key($data);
$field_arr = explode(",", $field);
 
// 条件组合
if (array_key_exists('condition', $data)){
  $query = [];
  $condition = $data['condition'];
  if(array_key_exists('fulltext', $condition)){
    foreach ($condition['fulltext'] as $fields=>$keyword){
      $field_arr = explode(',',$fields);
      $query['bool']['must'] = [
        'multi_match'=>[
          'query' => $keyword,
          'type' => 'best_fields',   ## 希望完全匹配的结果靠前
      // 'type' => 'phrase', ## 完全匹配
          'tie_breaker' => 0.3,   ## 除了完全匹配的结果,分词的匹配结果靠后
          'fields' => $field_arr,
       // 'slop' => 10 ## slop指定每个相邻词之间允许相隔多远。如果此处设置为0,则表示实现完全匹配!与type='phrase'配合使用,很实用!
      ]
    ];
    // 高亮
    $highlight = [];
    foreach ($field_arr as $field){
      $highlight['fields'][$field] = [
        'pre_tags' => '<strong style="color:red">',
        'post_tags' => '</strong>'
      ];
    }
    $params['body']['highlight'] = $highlight;
  }
}
if (array_key_exists('gt', $condition)){
  foreach ($condition['gt'] as $field=>$value){
    $query['bool']['filter'] = [
      'term'=>[
        $field => $value
      ]
    ];
  }
}
}else{
  exit('condition不能为空!');
}
$params['body']['query'] = $query;
$client->search($params);

=》关于elasticsearch的复杂搜索的学习

 

7、根据唯一标识id删除数据

$params = [
    'index' => $dbName,   ## 索引:数据库
'type' => $tbName, ## 类型:数据表
];
$params['id'] = $id;
$r = $client->delete($params);

 

8、删除索引(删除整个数据库)

curl -XDELETE http://localhost:9200/数据库名字(即索引名字!)

 

 ====================================

注意:截图与所贴代码可能不一样,因为截图是第一次写的时候截的图,文字却是在学习es的过程中不断修改的,请以文字为主!

 

 

自我备注:

一、测试过程=》基于我自己写的es-php工具类

 

1、删除之前用于测试的索引

curl -XDELETE http://localhost:9200/test

 

2、创建索引

http://test.xx.com/ElasticsearchFulltextTool.php?db=test&tb=test&m=createIndex&d=xx

 

3、设置mapping

http://test.xx.com/ElasticsearchFulltextTool.php?db=test&tb=test&m=setMapping&d={"content":"text","title":"string","add_time":"long"}

 

4、添加数据

http://test.xx.com/ElasticsearchFulltextTool.php?db=test&tb=test&m=add&d={"title":"美食播报","content":"测试 美 食 播 报"}

http://test.xx.com/ElasticsearchFulltextTool.php?db=test&tb=test&m=add&d={"title":"美食播报","content":"测试美ccc"}

http://test.xx.com/ElasticsearchFulltextTool.php?db=test&tb=test&m=add&d={"title":"美食播报","content":"测试食xxx"}

http://test.xx.com/ElasticsearchFulltextTool.php?db=test&tb=test&m=add&d={"title":"美食播报","content":"测试,播vv报"}

http://test.xx.com/ElasticsearchFulltextTool.php?db=test&tb=test&m=add&d={"title":"美食播报","content":"测试,美食播报,相关度"}

 

5、搜索数据

http://test.xx.com/ElasticsearchFulltextTool.php?db=test&tb=test&m=searchMulti&d={"content,title":"美食播报"}

带着分页:

http://test.xx.com/ElasticsearchFulltextTool.php?db=test&tb=test&m=searchMulti&d={"content,title":"美食播报","es_from":"0","es_size":"15"}

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM