欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

thinkphp结合elasticsearch实现全文搜索,搜索推荐,高亮显示

程序员文章站 2022-07-05 14:43:24
...
<?php
namespace app\controller;

use Elasticsearch\ClientBuilder;

class Es{
    private $client;
    // 构造函数
    public function __construct()
    {
        $params = array(
            '127.0.0.1:9200'
        );
        $this->client = ClientBuilder::create()->setHosts($params)->build();
    }

    // 创建索引
    public function create_index($index_name = 'gk') { // 只能创建一次
        $params = [
            'index' => $index_name,
            'body' => [
                'settings' => [
                    'number_of_shards' => 5,
                    'number_of_replicas' => 0
                ]
            ]
        ];

        return $this->client->indices()->create($params);
    }

    // 检查索引是否存在
    public function check_index_exists($index_name = 'gk') {
        $params = [
            'index' => $$index_name
        ];

        return $this->client->indices()->exists($params);
    }

    // 删除索引
    public function delete_index($index_name = 'gk') {
        $params = [
            'index' => $index_name
        ];

        return $this->client->indices()->delete($params);
    }

    // 创建文档模板
    public function create_mappings($type_name = 'users',$index_name = 'gk') {
        $params = [
            'index' => $index_name,//这里是索引名,相当于数据库名
            'type' => $type_name,//这里是类型名,相当于表名
            'include_type_name' => true,//7.0以上版本必须有
            'body' => [
                //下面是数据类型定义,相当于数据库字段
                'properties' => [
                    'id' => [
                        'type' => 'integer', // 整型 integer short long byte
                        'index' => 'false', // 非全文搜索,即不创建id字段的搜索 默认是true
                    ],
                    'name' => [
                        'type' => 'completion', // 字符串型 text模糊查找 keyword精准查找  completion 搜索推荐
                        //'index' => 'true', // 全文搜索
                        //'analyzer' => 'ik_max_word'
                    ],
                    'profile' => [
                        'type' => 'text',// 字符串型
                        //'index' => 'true', // 全文搜索
                        'analyzer' => 'ik_max_word'
                    ],
                    'age' => [
                        'type' => 'short',
                        //'index' => 'false', //非全文搜索
                    ],
                ]
            ]
        ];

        return $this->client->indices()->putMapping($params);
    }

    // 查看映射,相当于数据库的数据结构
    public function get_mapping($index_name = 'gk',$type_name = 'users') {
        $params = [
            'index' => $index_name,
            'type' => $type_name,
            'include_type_name' => true,//7.0以上版本必须有
        ];

        return $this->client->indices()->getMapping($params);
    }

    // 添加文档 $id相当于数据库id $doc相当于数据库一条数据
    public function add_doc($id,$doc,$index_name = 'gk',$type_name = 'users') {
        $params = [
            'index' => $index_name,
            'type' => $type_name,
            'id' => $id,
            'body' => $doc
        ];

        return $this->client->index($params);
    }

    // 判断文档存在
    public function exists_doc($id,$index_name = 'gk',$type_name = 'users') {
        $params = [
            'index' => $index_name,
            'type' => $type_name,
            'id' => $id
        ];

        return $this->client->exists($params);
    }

    // 获取文档
    public function get_doc($id,$index_name = 'gk',$type_name = 'users') {
        $params = [
            'index' => $index_name,
            'type' => $type_name,
            'id' => $id
        ];

        return $this->client->get($params);
    }

    // 更新文档
    public function update_doc($id,$index_name = 'gk',$type_name = 'users') {
        $params = [
            'index' => $index_name,
            'type' => $type_name,
            'id' => $id,
            'body' => [
                'doc' => [
                    'name' => '小强',
                    'profile' => 'php是最好的语言。',
                    'age' => '18',
                ]
            ]
        ];

        return $this->client->update($params);
    }

    // 删除文档
    public function delete_doc($id,$index_name = 'gk',$type_name = 'users') {
        $params = [
            'index' => $index_name,
            'type' => $type_name,
            'id' => $id
        ];

        return $this->client->delete($params);
    }

    /**
     * 查询文档 (分页,排序,权重,过滤)
     * @param string $keywords  搜索的词
     * @param string $index_name 相当于数据库名
     * @param string $type_name  相当于表名
     * @param int $from  开始的位置
     * @param int $size  每页显示的个数
     * @return array|callable
     */
    public function search_doc($keywords = "删库",$index_name = "gk",$type_name = "users",$from = 0,$size = 10) {
        $params = [
            'index' => $index_name,
            'type' => $type_name,
            'body' => [
                'suggest' => [
                    'my-suggester'=>[
                        'text' => $keywords,
                        'completion' => [ 'field' => 'name' ]
                    ],
                ],
//                'query' => [
//                    'bool' => [//bool查询,可以把很多小的查询组成一个更为复杂的查询,
//                        //必须匹配  必须满足 关键词=界面
//                        // must_not排除包含
                        "must"=>[
                            "match"=>[
                                "profile"=>'界面',
                            ]
                        ],
//                        //应该匹配 满足其中一个即可
//                        'should' => [
                            [ 'match' => [ 'profile' => [
                                'query' => $keywords,
                                'boost' => 3, // 权重大
                            ]]],
//                            [ 'match' => [ 'name' => [
//                                'query' => $keywords,
//                                'boost' => 2,
//                            ]]],
                            [ 'match' => [ 'age' => [
                                'query' => $keywords,
                            ]]],
                            [ 'range' => [ 'age' => [
                                "gte"=>25,
                                "lte"=>26,
                            ]]],
//                        ],
//                        //限制年龄小于24
                        'filter'=>[
                            "range"=>[
                                "age"=>["lt"=>24]
                            ]
                        ]
//                    ],
//                ],
                //高亮搜索
//                'highlight'=>[
//                    "fields"=>[
//                        //必须加object,要不然转json时,这里依然是数组,而不是对象
//                        "profile"=>(object)[]
//                    ]
//                ],
                //统计
//                'aggs'=>[
//                    "result"=>[
//                        //terms 桶 统计文档数量
//                        "terms"=>[
//                            "field"=>"age"
//                        ]
//                    ],
//                    "avg"=>[
//                        //avg 平均值
//                        "avg"=>[
//                            "field"=>"age"
//                        ]
//                    ],
//                    "max"=>[
//                        //max 最大值
//                        "max"=>[
//                            "field"=>"age"
//                        ]
//                    ],
//                    "min"=>[
//                        //avg 最小值
//                        "min"=>[
//                            "field"=>"age"
//                        ]
//                    ],
//                ],
                //按照age倒叙排列
                'sort' => ['age'=>['order'=>'desc']],
                'from' => $from,
                'size' => $size
            ]
        ];

        return $this->client->search($params);
    }

}

 

相关标签: PHP es