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