laravel 分词搜索匹配度_elasticsearch基础笔记9-elasticsearch 词项&全文搜索

ae59f4cd0a269c4a7a43177bbff83104.png

es的核心功能就是搜索和分析。那么我们看看搜索相关内容

1、搜索机制

7e3c4dfe6103ff6db833f875db6c3106.png

在进入搜索之前,会对查询体根据情况进行分析和处理。

82386501ba752add38dc956a2e44c68d.png

2、有哪些常用搜索类型

全文查询 词项查询 复合查询 嵌套查询 位置查询 特殊查询等。

我们常用到的就是前三种,学起来简单,用起来特别难。

3、看看这三种查询的区别。

词项查询用来查找指定字段中,包含给定的单词的文档,词项查询不会被解析,只有查询词和文档中的词精确匹配才会被搜索到,常见的应用场景为地名,人名等。我们的 准字号。

全文查询通常用于在全文进行搜索,全文查询的被查询字段是要被分析和分解的。

复合查询,就是把一些简单的查询组合在一起查询,实现更复杂的查询需求,此外,复合查询还可以控制另一个查询的行为。

我们先以term query 和matchquery 来进行对比讲解。(下面两部分第一项)

准备工作:

我们重新建一个sku索引,加入相应的数据;

3aa95762e61d684fe6bd10f471ecfa4f.png
a20a9a5d8de5deb6e1ccc7fa01e2e1cf.png

然后,我们确认下,新增的数据都已经存进来了

GET sku/_search

好,接下来我们来看看不同的查询出来的效果是怎么样的。

4、词项查旬

首先,我们查询下我们刚才录入的一个文档,

e3b4be83fafef9f8351e07d1687a2e2c.png

我们发现,并没有查到我们刚才存入的数据,这个就有点尴尬了。

那到底是什么原因呢?在想想我们对词项查询的定义,词项查询内容不会被解析,只有精确匹配到的才会被查询出来。那我们也就是说,需要我们的sku索引的相应字段要精确的匹配到"三黄片"这个词。那我们我们接下看看看索引字段是怎么存的。分词之后是什么样子的。

d5d2c897de568a5811cd660d1374cd7c.png

上面就是"三黄片"这个词在name这个字段上的分词结果。我们发现,分词结果是三、黄、片三个单独的词,而我们用"三黄片"整个词来匹配是匹配不到的。

如果我们将我们的搜索词改为"三",那么应该就会匹配到响应的数据如下:

889c506e4c45a0915211b3a82a87dba1.png

同样的情况,我们用全文查询查询一次看一下效果:参考match query内容部分

terms查询是term的升级版,用来查询文档中包含多个词项,词项间是或的关系。

比如,我们查刚才的sku 包含"三","jiaonang"的,会发现同时查到了两条记录。

dee0700c94e1b87c0ce5f159de829c12.png

prefix 查询用来查询某个字段中以给定的字段开头的文档。

da9598e3e3245cfba10cfcf72490764f.png

这个查询中我们发现,对于所查询的字段,还是用了分词的。

query

于此类似的还有 wildcard query 为通配符查询,这个查询支持单字或者多字的通配符查询。查询过程中,用'?'来匹配一个任意字符,'*'用来匹配0个或者多个字符。

7abfddc6a7921d1c9e052556f58ed9dc.png

exists 查询会查询出至少一个非空值的文档。

5、全文查询

同样的情况,我们用全文查询查询一次看一下效果:

448f7691630e88ab948ade1e8e9a3268.png

我们会发现,这个时候,无论我们怎么查,都能查到结果。这就是两种查询的区别。

match查询会对查询语句进行分词,分词之后查询语句中任何一个词项被匹配,文档就会被搜索到。

如果,想要所有词项都被搜索到才返回,则使用 and连接。 这就需要改换下写法(上面的写法是简单的写法)

完成写法如下:

577c502da33affd361fabdf9b57e0c87.png

使用了and连接,也就是对查询内容进行分词,所有的词项都被命中后才返回。我们查询"三皇片"就不会查找到任何内容。查询"三片"就会查找到相应内容。

a3e7e5813974122d560c66d36e0fcf94.png
abdc29f2083120fd0fd39d433423d066.png

对于上面的搜索结构我们可以简单的分析一下,我们可以把match{}对象中的内容表述为这次匹配查询的参数(官方:top-level parameters for match)。"field"是要查询的字段,field{}对象内容部,是对field的参数。

这个参数可以有很多。具体如下:

query: 你要查询的内容,这个字段是必须的。

analyzer: 分词器(非必须),在搜索的时候可以制定分词器,这个时候就会由指定的分词器来分析你要的关键词。比如我们把刚才的搜索加上'keyword'分词,就不会搜到结果。如果我们不指定分词器,则会默认使用索引字段设定好的分词器。

9de853ad3b74930d5cfba2952bd24106.png

fuzziness: 允许模糊搜索。 分析出来的关键词之间允许相隔最大的字符数量。

e5dfcc22537a6719ee7bfc19e434fbbc.png

max_expansions : 查询的扩展词最大数量。默认为50。

operator :对查询文本的解析操作类型,包含两个值:OR AND 。

该查询首先会把要查询的内容分词,分词器可以自行定义。同时,文档内容必须满足两个条件才能被查询到:

1、分词后的所有的词项都要被命中

2、字段中的词项和查询中的词项顺序必须一致。

这里我们用两个查询看一下差别,我们用match查询 查询 '三片黄',发现是可以查询到结果的。

08e0c09b37956cbe573031157bf44abf.png

然后,我们换 match_phrase查询,则查询不到结果,因为分词后,顺序不匹配。

3404748e740f79209a19d3d7af673da2.png

match_phrase_prefix查询

match_phrase_prefix查询和 match_phrase比较像,不同的是最后一个词支持前缀匹配。比如我们查询'hello world' 这个词。用 、'hello w'也可以查询到。

查询,

multi_match可以看做是match的升级版,用于搜索多个字段。

我们可以再sku索引上增加一个字段,然后,新增一个商品来试验一下.(为甚不新增一个字段,然后直接修改新增字段这个值?可自己试验一次),我们发现,在'name'、'fullname'这两个字段上搜国药,是可以搜索到结果的。

768a577f4b952e0563301b924dfac2bc.png

同时,multi_match在字段名称上,还支持通配符查询。如下:

e91add5156e7cdcc99c846fe1c239d91.png

另外,multi_match在查询的时候,还可以通过指数符号指定字段的权重值。如下查询,我们会发现返回的sorce值变大了。

db3e01c05ebe3e13419577fe8776ba03.png

常用词项查询,算是一种稍微高级点的查询。所以,想要用好,还是要理解比较多的内容。必须解下停止词(顺手可以把同义词看了)。这个查询比较适合于停用词在语境中有重要作用的场景。按照官方例子来说:not 是个常见的停用词。happy 和 not happy 对比下,not的意义就很重要了。

所以,提供了一种解决方案,把query分词后的词项分成了重要词项和不重要词项。查询的时候,先查询重要词项。一般来说重要词项都是低频词。然后,在进行高频词搜索,这次只计算第一次匹配的文档评分。

词项是高频还是低频,可以自行通过cutoff_frequency来设定。

更高深的用法,可参看官方文档。这个查询可以很好的适应特定领域的停用词。

字符串查询,是对查询内容按运算规则进行分析分解的查询。比如:查询 "xxxxx AND yyyy "会被分解 query xxxx and query yyyyy的形式。这个查询支持的参数非常多,具体参考官方文档。对es搜索原理非常理解估计才能用的飞起。

这个是可以直接拿来用的字符串查询,查询在解析语句的过程中,不会抛出错误。用起放心些。

为了能加深意向,大家可多来几个例子,看到底能不能搜得到:

name: 分词器: 搜索类型: 搜索:

java编程思想 ik term java 思想 编程思想

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值