喵星之旅-狂奔的兔子-使用kibana对es进行查询
match系列
match关键字,相当于mysql数据库中的like查询,match查询的字段如果是text类型,那么text会被分词,match就会匹配分词,查询所有包含分词的doc文档,如果不是text类型的,那就是精确查询。
match:查询指定条件的数据,match会将查询的条件进行分词操作,然后doc文档中包含分词,就都会查询出来。
match_all:查询所有数据。
match_phrase:匹配短语,match是会查询所有包含分词的doc文档,而match_phrase则是匹配整个短语,才会返回对应的doc文档。但是这个与“ik_max_word”分词器有冲突,很可能失败,不排除有的版本可以。由于我选择的分词器就是“ik_max_word”,所以相关验证跳过。
match_phrase_prefix:匹配短语的前缀部分,这个只能使用在text类型字段。
# 查询bunny索引中title包含"提高效率"的数据,前提是该字段已经分词,并且会对查询条件进行分词。实际查询结果是包含“提高效率”,“提高”,“高效率”,“高效”,“效率”的数据。
GET /bunny/_search
{
"query": {
"match": {
"title": "提高效率"
}
}
}
# 查询bunny索引中所有数据
get /bunny/_search
{
"query": {
"match_all": {}
}
}
排序查询
elasticsearch支持对搜索结果排序,默认是根据相关度算分(_score)来排序。
不是所有字段都可以排序,只能是数字字段。
get /bunny/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"createTime": {
"order": "desc"
}
}
]
}
分页查询
elasticsearch 默认情况下只返回top10的数据。而如果要查询更多数据就需要修改分页参数了。 elasticsearch中通过修改from、size参数来控制要返回的分页结果:
# 跳过80条数据,从第81条开始显示最多10条。如果是默认的应该是0,10.
GET /ky_technical_product/_search
{
"query": {
"match": {
"title": "提高 效率"
}
} ,
"from": 80,
"size": 10
}
bool查询
es bool 查询是把任意多个简单查询组合在一起,使用 must、should、must_not、filter 选项来表示简单查询之间的逻辑,每个选项都可以出现 0 次到多次。它是为了满足现实中比较复杂的查询需求,如需要在多个字段上查询多种多样的文本,并且根据一系列的标准来过滤。
bool query 主要通过下列 4 个选项来构建用户想要的布尔查询,每个选项的含义如下:
must:文档必须匹配,该选项下的查询条件,相当于逻辑运算的 AND,且参与文档相关度的评分。
should:文档可以匹配 should 选项下的查询条件也可以不匹配,相当于逻辑运算的 OR,且参与文档相关度的评分。
must_not:与 must 相反,匹配该选项下的查询条件的文档不会被返回;需要注意的是,must_not 语句不会影响评分,它的作用只是将不相关的文档排除。
filter:和 must 一样,匹配 filter 选项下的查询条件的文档才会被返回,但是 filter 不评分,只起到过滤功能,与 must_not 相反。
这里需要说明的是,每一个子查询都独自地计算文档的相关性得分。一旦他们的得分被计算出来, bool 查询就将这些得分进行合并并且返回一个代表整个布尔操作的得分。具体的得分规则在下面的评分计算章节中介绍。
must 语句必须匹配,但有多少 should 语句应该匹配呢?默认情况下,没有 should 语句是必须匹配的,但只有一个例外,那就是当没有 must 语句的时候,至少有一个 should 语句必须匹配。
计算规则
bool 查询采用“匹配越多越好(more_matches_is_better)”的机制,因此满足 must 和 should 子句的文档将会合并起来计算分值。
在 filter 子句查询中,分值将会都返回 0。
must_not 子句并不影响得分,它们存在的意义是排除已经被包含的文档。
如上所述,bool 查询的计算得分主要是 must 和 should 子句,它们的计算规则是,把所有符合 must 和 should 的子句得分加起来,然后乘以匹配子句的数量,再除以子句的总数。
# groundingState="已上架" and "category"<>"暂无" and "title"包含 "钻井" and ("createByName"包含"管理" or "content"包含"石油")。其中groundingState没有分词。
GET /bunny/_search
{
"query": {
"bool": {
"filter": {
"term": { "groundingState.keyword": "已上架" }
},
"must_not": {
"term": { "category": "暂无" }
},
"must": {
"match": { "title": "钻井" }
},
"should": [
{
"match": { "createByName": "管理" }
},
{
"match": { "content": "石油" }
}
]
}
}
}
高亮显示
GET /bunny/_search
{
"query": {
"match": {
"title": "钻井"
}
},
"highlight": {
"fields": {
"title": {
}
}
}
}
elasticsearch 提供了如下高亮参数:
boundary_chars 包含每个边界字符的字符串。默认为,! ?\ \ n。
boundary_max_scan 扫描边界字符的距离。默认为20。
boundary_scanner 指定如何分割突出显示的片段,支持chars、sentence、word三种方式。
boundary_scanner_locale 用来设置搜索和确定单词边界的本地化设置,此参数使用语言标记的形式(“en-US”, “fr-FR”, “ja-JP”)
encoder 表示代码段应该是HTML编码的:默认(无编码)还是HTML (HTML-转义代码段文本,然后插入高亮标记)
fields 指定检索高亮显示的字段。可以使用通配符来指定字段。例如,可以指定comment_*来获取以comment_开头的所有文本和关键字字段的高亮显示。
force_source 根据源高亮显示。默认值为false。
fragmenter 指定文本应如何在突出显示片段中拆分:支持参数simple或者span。
fragment_offset 控制要开始突出显示的空白。仅在使用fvh highlighter时有效。
fragment_size 字符中突出显示的片段的大小。默认为100。
highlight_query 突出显示搜索查询之外的其他查询的匹配项。这在使用重打分查询时特别有用,因为默认情况下高亮显示不会考虑这些问题。
matched_fields 组合多个匹配结果以突出显示单个字段,对于使用不同方式分析同一字符串的多字段。所有的matched_fields必须将term_vector设置为with_positions_offsets,但是只有将匹配项组合到的字段才会被加载,因此只有将store设置为yes才能使该字段受益。只适用于fvh highlighter。
no_match_size 如果没有要突出显示的匹配片段,则希望从字段开头返回的文本量。默认为0(不返回任何内容)。
number_of_fragments 返回的片段的最大数量。如果片段的数量设置为0,则不会返回任何片段。相反,突出显示并返回整个字段内容。当需要突出显示短文本(如标题或地址),但不需要分段时,使用此配置非常方便。如果number_of_fragments为0,则忽略fragment_size。默认为5。
order 设置为score时,按分数对突出显示的片段进行排序。默认情况下,片段将按照它们在字段中出现的顺序输出(order:none)。将此选项设置为score将首先输出最相关的片段。每个高亮应用自己的逻辑来计算相关性得分。
phrase_limit 控制文档中所考虑的匹配短语的数量。防止fvh highlighter分析太多的短语和消耗太多的内存。提高限制会增加查询时间并消耗更多内存。默认为256。
pre_tags 与post_tags一起使用,定义用于突出显示文本的HTML标记。默认情况下,突出显示的文本被包装在和标记中。指定为字符串数组。
post_tags 与pre_tags一起使用,定义用于突出显示文本的HTML标记。默认情况下,突出显示的文本被包装在和标记中。指定为字符串数组。
require_field_match 默认情况下,只突出显示包含查询匹配的字段。将require_field_match设置为false以突出显示所有字段。默认值为true。
tags_schema 设置为使用内置标记模式的样式。
type 使用的高亮模式,可选项为unified、plain或fvh。默认为unified。
如果我们想使用自定义标签,在高亮属性中给需要高亮的字段加上 pre_tags 和 post_tags 即可。例如:
GET /bunny/_search
{
"query": {
"match": {
"title": "钻井"
}
},
"highlight": {
"fields": {
"title": {
"pre_tags": ["<strong>"],
"post_tags": ["</strong>"]
}
}
}
}
关于搜索高亮,还需要掌握如何设置多字段搜索高亮。比如,搜索 title 字段的时候,我们期望 description 字段中的关键字也可以高亮,这时候就需要把 require_field_match 属性的取值设置为 fasle。require_field_match 的默认值为 true,只会高亮匹配的字段。多字段高亮的查询语句如下
GET /bunny/_search
{
"query": {
"match": {
"title": "暂无 钻井"
}
},
"highlight": {
"require_field_match": "false",
"fields": {
"title": {
},
"category": {
}
}
}
}
高亮返回结果只有匹配上的才会显示,高亮的字段要支持分词,可能是下面两种可能:
"highlight" : {
"title" : [
"<em>钻井</em>优化新技术如何提高<em>钻井</em>效率"
],
"category" : [
"<em>暂无</em>"
]
}
"highlight" : {
"title" : [
"<em>钻井</em>"
]
}
term查询
term query会去倒排索引中寻找确切的term,它并不知道分词器的存在,这种查询适合keyword、numeric、date等明确值的,分词的字段也可以使用。下面的title就是分词字段。
# 查询包含“提高效率”的,不分词。
GET /bunny/_search
{
"query": {
"term": {
"title": "提高效率"
}
}
}
# title= "提高效率",严格相等的条件
GET /bunny/_search
{
"query": {
"term": {
"title.keyword": "提高效率"
}
}
}
# 包含多个值的用terms
GET /bunny/_search
{
"query": {
"terms": {
"title": ["效率" ,"提高"]
}
}
}
权重设置
需要根据用户输入的查询关键字同时去匹配多个字段,并且希望对匹配字段的权重做不同的设置,比如同时去匹配公司名称和公司简介,这里一般需要提升公司名称匹配的权重,这样得出的相关性评分才会更准确。
在ES中,我们可以通过boost参数来控制多字段查询的权重。
boost是一个用来修改文档的相关性的参数,默认值是1。可以通过设置不同的值,提升该字段在相关性评分的权重。
boost有两种类型:索引期间boost、查询期间boost。
创建索引时指定的boost参数是存储在索引中的,修改boost值唯一的方法是重新索引这篇文档。
索引期间boost
PUT bunny
{
"mappings": {
"properties": {
"company": {
"type": "text", "analyzer": "ik_smart", "boost":"3"
},
"desc": {
"type": "text", "analyzer": "ik_smart"
}
}
}
}
GET bunny/_search
{
"query": {
"multi_match": {
"query": "喵星",
"fields": ["company","desc"]
}
}
}
查询期间boost
通过字段名称后面添加“^”符号和boost的值,提升指定字段的评分权重。
GET bunny/_search
{
"query": {
"multi_match": {
"query": "喵星",
"fields": ["company^3","desc"]
}
}
}
java API中权重控制
Map<String,Float> fields = new HashMap(2);
fields.put("company", 3.0f);
fields.put("desc", 1.0f);
queryBuilder.must(QueryBuilders.multiMatchQuery(paramsDto.getKeyword()).fields(fields).analyzer("ik_smart"));
作者:喵星兔
出处:https://www.cnblogs.com/kittybunny/
喵星之旅:https://www.cnblogs.com/kittybunny/p/12148641.html
我的视频:https://space.bilibili.com/518581788
更多内容:不咬人的小兔子
本博客所有文章仅用于学习、研究和交流目的,欢迎非商业性质转载。
我是兔子,我会喵,我叫喵星兔~~