es的核心功能就是搜索和分析。那么我们看看搜索相关内容
1、搜索机制
在进入搜索之前,会对查询体根据情况进行分析和处理。
2、有哪些常用搜索类型
全文查询 词项查询 复合查询 嵌套查询 位置查询 特殊查询等。
我们常用到的就是前三种,学起来简单,用起来特别难。
3、看看这三种查询的区别。
词项查询用来查找指定字段中,包含给定的单词的文档,词项查询不会被解析,只有查询词和文档中的词精确匹配才会被搜索到,常见的应用场景为地名,人名等。我们的 准字号。
全文查询通常用于在全文进行搜索,全文查询的被查询字段是要被分析和分解的。
复合查询,就是把一些简单的查询组合在一起查询,实现更复杂的查询需求,此外,复合查询还可以控制另一个查询的行为。
我们先以term query 和matchquery 来进行对比讲解。(下面两部分第一项)
准备工作:
我们重新建一个sku索引,加入相应的数据;
然后,我们确认下,新增的数据都已经存进来了
GET sku/_search
好,接下来我们来看看不同的查询出来的效果是怎么样的。
4、词项查旬
首先,我们查询下我们刚才录入的一个文档,
我们发现,并没有查到我们刚才存入的数据,这个就有点尴尬了。
那到底是什么原因呢?在想想我们对词项查询的定义,词项查询内容不会被解析,只有精确匹配到的才会被查询出来。那我们也就是说,需要我们的sku索引的相应字段要精确的匹配到"三黄片"这个词。那我们我们接下看看看索引字段是怎么存的。分词之后是什么样子的。
上面就是"三黄片"这个词在name这个字段上的分词结果。我们发现,分词结果是三、黄、片三个单独的词,而我们用"三黄片"整个词来匹配是匹配不到的。
如果我们将我们的搜索词改为"三",那么应该就会匹配到响应的数据如下:
:
同样的情况,我们用全文查询查询一次看一下效果:参考match query内容部分
terms查询是term的升级版,用来查询文档中包含多个词项,词项间是或的关系。
比如,我们查刚才的sku 包含"三","jiaonang"的,会发现同时查到了两条记录。
prefix 查询用来查询某个字段中以给定的字段开头的文档。
这个查询中我们发现,对于所查询的字段,还是用了分词的。
query
于此类似的还有 wildcard query 为通配符查询,这个查询支持单字或者多字的通配符查询。查询过程中,用'?'来匹配一个任意字符,'*'用来匹配0个或者多个字符。
exists 查询会查询出至少一个非空值的文档。
5、全文查询
:
同样的情况,我们用全文查询查询一次看一下效果:
我们会发现,这个时候,无论我们怎么查,都能查到结果。这就是两种查询的区别。
match查询会对查询语句进行分词,分词之后查询语句中任何一个词项被匹配,文档就会被搜索到。
如果,想要所有词项都被搜索到才返回,则使用 and连接。 这就需要改换下写法(上面的写法是简单的写法)
完成写法如下:
使用了and连接,也就是对查询内容进行分词,所有的词项都被命中后才返回。我们查询"三皇片"就不会查找到任何内容。查询"三片"就会查找到相应内容。
对于上面的搜索结构我们可以简单的分析一下,我们可以把match{}对象中的内容表述为这次匹配查询的参数(官方:top-level parameters for match)。"field"是要查询的字段,field{}对象内容部,是对field的参数。
这个参数可以有很多。具体如下:
query: 你要查询的内容,这个字段是必须的。
analyzer: 分词器(非必须),在搜索的时候可以制定分词器,这个时候就会由指定的分词器来分析你要的关键词。比如我们把刚才的搜索加上'keyword'分词,就不会搜到结果。如果我们不指定分词器,则会默认使用索引字段设定好的分词器。
fuzziness: 允许模糊搜索。 分析出来的关键词之间允许相隔最大的字符数量。
max_expansions : 查询的扩展词最大数量。默认为50。
operator :对查询文本的解析操作类型,包含两个值:OR AND 。
,
该查询首先会把要查询的内容分词,分词器可以自行定义。同时,文档内容必须满足两个条件才能被查询到:
1、分词后的所有的词项都要被命中
2、字段中的词项和查询中的词项顺序必须一致。
这里我们用两个查询看一下差别,我们用match查询 查询 '三片黄',发现是可以查询到结果的。
然后,我们换 match_phrase查询,则查询不到结果,因为分词后,顺序不匹配。
match_phrase_prefix查询
match_phrase_prefix查询和 match_phrase比较像,不同的是最后一个词支持前缀匹配。比如我们查询'hello world' 这个词。用 、'hello w'也可以查询到。
查询,
multi_match可以看做是match的升级版,用于搜索多个字段。
我们可以再sku索引上增加一个字段,然后,新增一个商品来试验一下.(为甚不新增一个字段,然后直接修改新增字段这个值?可自己试验一次),我们发现,在'name'、'fullname'这两个字段上搜国药,是可以搜索到结果的。
同时,multi_match在字段名称上,还支持通配符查询。如下:
另外,multi_match在查询的时候,还可以通过指数符号指定字段的权重值。如下查询,我们会发现返回的sorce值变大了。
,
常用词项查询,算是一种稍微高级点的查询。所以,想要用好,还是要理解比较多的内容。必须解下停止词(顺手可以把同义词看了)。这个查询比较适合于停用词在语境中有重要作用的场景。按照官方例子来说:not 是个常见的停用词。happy 和 not happy 对比下,not的意义就很重要了。
所以,提供了一种解决方案,把query分词后的词项分成了重要词项和不重要词项。查询的时候,先查询重要词项。一般来说重要词项都是低频词。然后,在进行高频词搜索,这次只计算第一次匹配的文档评分。
词项是高频还是低频,可以自行通过cutoff_frequency来设定。
更高深的用法,可参看官方文档。这个查询可以很好的适应特定领域的停用词。
,
字符串查询,是对查询内容按运算规则进行分析分解的查询。比如:查询 "xxxxx AND yyyy "会被分解 query xxxx and query yyyyy的形式。这个查询支持的参数非常多,具体参考官方文档。对es搜索原理非常理解估计才能用的飞起。
这个是可以直接拿来用的字符串查询,查询在解析语句的过程中,不会抛出错误。用起放心些。
为了能加深意向,大家可多来几个例子,看到底能不能搜得到:
name: 分词器: 搜索类型: 搜索:
java编程思想 ik term java 思想 编程思想