具体要求是一个关键词查询,可以查询名称或者标签或者所属的行业(通过名称模糊匹配ID)
主要是在must中嵌入 [bool][should] 进行OR的连接
然后query_string使用多字段 进行查询 name 和labels.核心代码如下
if ($keywords) {
/*获取单词的分词情况*/
$analyzer = $this->client->indices()->analyze(
[
'index' => $this->index,
'body' =>
[
'text' => $keywords,
'analyzer' => 'ik_max_word'
]
]
);
if ($analyzer) {
$tokens = $analyzer['tokens'];
$keys = array_column($tokens, 'token', NULL);
$keys_OR = implode('AND', $keys);
//分词和labels同时查询
$must_arr['bool']['should'][0]['query_string'] = ['fields' => ['name','labels'], 'query' => $keys_OR];
}else{
//没有分词就直接查询labels
$must_arr['bool']['should'][0]['query_string'] = ['default_field' => 'labels', 'query' => $keywords];
}
}
if ($pro) {
//加入获取到的profession
$must_arr['bool']['should'][1]['term']['profession'] = $pro;
}
完整方法
// 查询文档 (分页,排序,权重,过滤)
public function search_doc($keywords = "", $year_arr = '', $province_arr = [], $from = 0, $size = 10, $order = ['id' => ['order' => 'asc']], $pro = 0)
{
$must_arr = [];
$filter_arr = [];
$should_arr = [];
$keys = '';
if ($keywords) {
/*获取单词的分词情况*/
$analyzer = $this->client->indices()->analyze(
[
'index' => $this->index,
'body' =>
[
'text' => $keywords,
'analyzer' => 'ik_max_word'
]
]
);
if ($analyzer) {
$tokens = $analyzer['tokens'];
$keys = array_column($tokens, 'token', NULL);
$keys_OR = implode('AND', $keys);
//分词和labels同时查询
$must_arr['bool']['should'][0]['query_string'] = ['fields' => ['name','labels'], 'query' => $keys_OR];
}else{
//没有分词就直接查询labels
$must_arr['bool']['should'][0]['query_string'] = ['default_field' => 'labels', 'query' => $keywords];
}
}
if ($pro) {
//加入获取到的profession
$must_arr['bool']['should'][1]['term']['profession'] = $pro;
}
//查询审核通过的数据
$filter_arr[]['term']['checked'] = 1;
//按照给定年份 或者年份范围查询
if ($year_arr && $year_arr[0] > 0) {
$filter_arr[]['range'] = ['create_date' => ['gte' => $year_arr[0] . "-01-01", 'lte' => $year_arr[1] . "-12-31"]];
}
if ($province_arr) {
if (!is_array($province_arr) && $province_arr !== 0) {
$province_arr = explode(',', $province_arr);
}
//按照给定省份查询
if ($province_arr !== 0 && ($province_arr[0] ?? 0) !== 0 && count($province_arr) > 0) {
$filter_arr[]['terms']['province.keyword'] = $province_arr;
}
}
/* echo "<pre>";
print_r($filter_arr);
print_r($province_arr);
exit();*/
if ($keywords || $year_arr || ($province_arr != 0 && count($province_arr) > 0)) {
/*----------------------------------------------------------*/
/*----------------------------------------------------------*/
$params = [
'index' => $this->index,
// 'type' => $this->type,
'body' => [
'query' => [
// 'match' =>
// [
// 'name'=>$keywords
// ]
'bool' =>
[
// 'filter'=>[
'must' => $must_arr,
'filter' => $filter_arr,
'should' => $should_arr,
// ],
]
],
'sort' => [$order],
'from' => $from,
'size' => $size
]
];
/*echo "<pre>";
print_r(json_encode($params['body']['query']));
exit();*/
/*----------------------------------------------------------*/
} // ------------------------------------------------------------------------
else {
$params = [
'index' => $this->index,
'body' => [
'sort' => [$order]
, 'from' => $from, 'size' => $size
]
];
}
try {
$re = $this->client->search($params);
} catch (\Exception $e) {
echo '<pre>';
print_r($e->getMessage());
exit();
}
return ['re' => $re, 'keys' => $keys];
}
完整文件:
<?php
// +----------------------------------------------------------------------
// | EasyAdmin
// +----------------------------------------------------------------------
// | PHP交流群: 763822524
// +----------------------------------------------------------------------
// | 开源协议 https://mit-license.org
// +----------------------------------------------------------------------
// | github开源项目:https://github.com/zhongshaofa/EasyAdmin
// +----------------------------------------------------------------------
namespace app\index\controller;
use app\admin\model\Corporation;
use app\index\model\SystemUploadfile;
use app\common\controller\IndexController;
use app\common\service\MenuService;
use EasyAdmin\upload\Uploadfile;
use Elasticsearch\ClientBuilder;
use Elasticsearch\Common\Exceptions\BadRequest400Exception;
use Elasticsearch\Common\Exceptions\Missing404Exception;
use think\db\Query;
use think\facade\Cache;
use think\facade\Queue;
class Ela extends IndexController
{
private $client;
// 构造函数
public function __construct()
{
$host = ['127.0.0.1:9200'];
$this->index = 'hcc_corporation_v2';
// $this->index = 'hcc_corporation';
$this->client = ClientBuilder::create()->setHosts($host)->build();
}
// 初始化
public function index()
{
// 只能创建一次
echo '<pre>';
print_r("OVER");
exit();
$this->delete_index();
$this->create_index(); //1.创建索引
$this->create_mappings(); //2.创建文档模板
echo '<pre>';
print_r("INIT OK");
exit();
}
public function put_settings()
{
$params1 =
[
'index' => $this->index,
'body' => [
'settings' => [
'blocks' =>
[
'read_only_allow_delete' => 'false'
]
],
]
];
$this->client->indices()->putSettings($params1);
echo 'SUCCESS';
}
// 创建索引
public function create_index()
{ // 只能创建一次
$params = [
'index' => $this->index,
'body' => [
'settings' => [
'number_of_shards' => 3,
'number_of_replicas' => 2,
'blocks' =>
[
'read_only_allow_delete' => 'false'
],
],
]
];
try {
$this->client->indices()->create($params);
} catch (BadRequest400Exception $e) {
$msg = $e->getMessage();
$msg = json_decode($msg, true);
return $msg;
}
}
// 删除索引
public function delete_index()
{
/* $params = ['index' => $this->index];
$index = $this->client->indices()->get($params);
if ($index) {
return $this->client->indices()->delete($params);
}*/
//
}
// 创建文档模板
public function create_mappings()
{
/*--------------------允许type的写法--------------------------*/
/*--------------------不允许type的写法--------------------------*/
// Set the index and type
$params = [
'index' => $this->index,
'body' => [
'_source' => [
'enabled' => true
],
'properties' => [
'id' => [
'type' => 'integer',
],
'top' => [
'type' => 'integer',
],
'is_govern' => [
'type' => 'integer',
],
'name' => [
'type' => 'text',
//'analyzer' => 'ik_max_word'
'analyzer' => 'ik_max_word'
],
/*-------------------------------------*/
]
]
];
$this->client->indices()->putMapping($params);
}
// 查看映射
public function get_mapping()
{
$params = [
'index' => $this->index,
];
$re = $this->client->indices()->getMapping($params);
echo '<pre>';
print_r($re);
exit();
}
// 添加一个文档(记录)
public function add_doc($id, $doc)
{
$get = $this->get_doc($id);
if (!$get) {
$params = [
'index' => $this->index,
// 'type' => $this->type,
'id' => $id,
'body' => $doc
];
return $this->client->index($params);
}
}
// 判断文档(记录)
public function exists_doc($id = 1)
{
$params = [
'index' => $this->index,
'type' => $this->type,
'id' => $id
];
return $this->client->exists($params);
}
// 获取一条文档(记录)
public function get_doc($id = 1)
{
$params =
[
'index' => $this->index,
'id' => $id
];
try {
$re = $this->client->get($params);
} catch (Missing404Exception $e) {
return 0;
//return false;
}
return 1;
}
// 更新一条文档()
public function update_doc($id = 1)
{
// 可以灵活添加新字段,最好不要乱添加
$params = [
'index' => $this->index,
'id' => $id,
'body' => [
'doc' => [
'name' => '大王'
]
]
];
return $this->client->update($params);
}
// 删除一条文档()
public function delete_doc($id = 1)
{
$params = [
'index' => $this->index,
//'type' => $this->type,
'id' => $id
];
return $this->client->delete($params);
}
// 查询文档 (分页,排序,权重,过滤)
public function search_doc($keywords = "", $year_arr = '', $province_arr = [], $from = 0, $size = 10, $order = ['id' => ['order' => 'asc']], $pro = 0)
{
$must_arr = [];
$filter_arr = [];
$should_arr = [];
$keys = '';
if ($keywords) {
/*获取单词的分词情况*/
$analyzer = $this->client->indices()->analyze(
[
'index' => $this->index,
'body' =>
[
'text' => $keywords,
'analyzer' => 'ik_max_word'
]
]
);
if ($analyzer) {
$tokens = $analyzer['tokens'];
$keys = array_column($tokens, 'token', NULL);
$keys_OR = implode('AND', $keys);
//分词和labels同时查询
$must_arr['bool']['should'][0]['query_string'] = ['fields' => ['name','labels'], 'query' => $keys_OR];
}else{
//没有分词就直接查询labels
$must_arr['bool']['should'][0]['query_string'] = ['default_field' => 'labels', 'query' => $keywords];
}
}
if ($pro) {
//加入获取到的profession
$must_arr['bool']['should'][1]['term']['profession'] = $pro;
}
//查询审核通过的数据
$filter_arr[]['term']['checked'] = 1;
//按照给定年份 或者年份范围查询
if ($year_arr && $year_arr[0] > 0) {
$filter_arr[]['range'] = ['create_date' => ['gte' => $year_arr[0] . "-01-01", 'lte' => $year_arr[1] . "-12-31"]];
}
if ($province_arr) {
if (!is_array($province_arr) && $province_arr !== 0) {
$province_arr = explode(',', $province_arr);
}
//按照给定省份查询
if ($province_arr !== 0 && ($province_arr[0] ?? 0) !== 0 && count($province_arr) > 0) {
$filter_arr[]['terms']['province.keyword'] = $province_arr;
}
}
/* echo "<pre>";
print_r($filter_arr);
print_r($province_arr);
exit();*/
if ($keywords || $year_arr || ($province_arr != 0 && count($province_arr) > 0)) {
/*----------------------------------------------------------*/
/*----------------------------------------------------------*/
$params = [
'index' => $this->index,
// 'type' => $this->type,
'body' => [
'query' => [
// 'match' =>
// [
// 'name'=>$keywords
// ]
'bool' =>
[
// 'filter'=>[
'must' => $must_arr,
'filter' => $filter_arr,
'should' => $should_arr,
// ],
]
],
'sort' => [$order],
'from' => $from,
'size' => $size
]
];
/*echo "<pre>";
print_r(json_encode($params['body']['query']));
exit();*/
/*----------------------------------------------------------*/
} // ------------------------------------------------------------------------
else {
$params = [
'index' => $this->index,
'body' => [
'sort' => [$order]
, 'from' => $from, 'size' => $size
]
];
}
try {
$re = $this->client->search($params);
} catch (\Exception $e) {
echo '<pre>';
print_r($e->getMessage());
exit();
}
return ['re' => $re, 'keys' => $keys];
}
/**
* 批量插入数据到索引
*/
public function insertCorporation($start)
{
echo '<pre>';
print_r("OVER");
exit();
$corporations = Corporation::limit($start, 50000)->order('id ASC')->select();
foreach ($corporations as $corporation) {
$job = "index/Message2";
Queue::push($job, $corporation->toArray(), $queue = "Import2");
}
echo '<pre>';
print_r('完成了');
exit();
}
//批量更新
public function update_all_doc()
{
echo '<pre>';
print_r("OVER");
exit();
// 可以灵活添加新字段,最好不要乱添加
$params = [
'index' => $this->index,
'body' => [
'script' => 'ctx._source.recommend = 0',
],
];
$re = $this->client->updateByQuery($params);
echo '<pre>';
print_r($re);
exit();
}
}