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