写点什么

ElasticSearch 中文分词和模糊查询

作者:北桥苏
  • 2023-05-13
    广东
  • 本文字数:1839 字

    阅读完需:约 6 分钟

前言:

​ ElasticSearch 是一个一个分布式的实时文档存储,每一个字段都可以被索引与搜索,并且能支持 PB 级别的结构化或者非结构化数据。早期我们应用的全局搜索是简单的 SQL 模糊查询,为了分担数据库压力所以用了 ES,选择他的原因除了以上几点外,还有其提供的 API 方式简单,于任何对接的编程语言都适用。以下将以 PHP 的业务场景完善搜索功能。



环境:


ThinkPHP5.1


ElasticSearch7.8


PHP7.3


功能迭代简介:

​ 最开始的 ES 取代方法解决了搜索速度问题,后来新增的 ik 分词器,解决了搜索词条单一问题。单也正是中文分词原因,对每句话都是拆解成指定粒度的词。当遇到单词时,一般只会对一句话里的单词进行拆解,而搜索时需要输入某个字母,希望输出的是带字母后面的词条,也就是模糊查询。经过翻阅文档,发现了即时搜索。


​ 即时搜索或输入即搜索(search-as-you-type),就是当用户习惯在输完查询内容之前,就能为他们展现搜索结果,不仅能在更短的时间内得到搜索结果,也能引导用户搜索索引中真实存在的结果。例如,输入 dvd r ,即时搜索会得到:dvd r9s 和 dvd r9sk 等 , 以下将通过完整示例演示效果。


配置索引的映射:

​ 关于 ElasticSearch 环境搭建和基本操作在前面文章有说明,这里就假装已经创建了索引,以下是索引的映射。还有文档的添加也是根据你自己的需求定义了,不管是定时任务还是业务节点触发,亦或是采集工具同步等。

{  "mappings": {    "_doc": {      "properties": {        "class_id": {          "type": "long"        },        "goods_name": {          "type": "text",          "analyzer": "ik_smart"        },        "goods_sort": {          "type": "keyword"        },        "id": {          "type": "keyword"        },        "price": {          "type": "long"        },        "single_goods_name": {          "type": "text",          "analyzer": "ik_max_word"        },        "state": {          "type": "keyword"        },        "v": {          "type": "long"        }      }    }  }}
复制代码


前台搜索:

1. 即搜索示例

{    "match_phrase_prefix" : {        "brand" : {            "query": "walker johnnie bl",             "slop":  10        }    }}
复制代码


2. 业务代码

public function queryData($key, $sort, $from = 0, $size = 10){    $from = $from * $size;    $indexName = Env::get('elasticsearch.goods_index') ?? 'products';
$params = [ 'index' => $indexName, 'client' => [ 'timeout' => 10, 'connect_timeout' => 10 ], 'body' => [ 'from' => $from, 'size' => $size, 'query' => [ 'bool' => [ 'should' => [ [ 'multi_match' => [ 'query' => $key, 'fields' => [ 'goods_name^2', 'single_goods_name' ], ], ], [ 'wildcard' => [ 'single_goods_name' => "$key*" ] ], [ 'fuzzy' => [ 'single_goods_name' => [ 'value' => $key ] ] ], [ 'match_phrase_prefix' => [ 'single_goods_name' => "$key" ] ], ], ], ], 'sort' => [ ['_score' => "desc"], ['goods_sort' => 'desc'] ], ] ];
return $this->es->search($params);}
复制代码


3. 效果演示



用户头像

北桥苏

关注

公众号:ZERO开发 2023-05-08 加入

专注后端实战技术分享,不限于PHP,Python,JavaScript, Java等语言,致力于给猿友们提供有价值,有干货的内容。

评论

发布
暂无评论
ElasticSearch中文分词和模糊查询_php_北桥苏_InfoQ写作社区