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"}