Elasticsearch: 高级搜索
这里写目录标题
- 一、match_all匹配所有文档
- 1、介绍:
- 二、精确匹配
- 1、term单字段精确匹配查询
- 2、terms多字段精确匹配
- 3、range范围查询
- 4、exists是否存在查询
- 5、ids根据一组id查询
- 6、prefix前缀匹配
- 7、wildcard通配符匹配
- 8、fuzzy支持编辑距离的模糊查询
- 9、regexp正则匹配查询
- 10、term set用于解决多字段中的文档匹配问题
- 三、全文检索
- 1、match分词查询
- 2、mutil_match多字段查询
- 3、match_phrase短语查询
- 4、query_string支持与或非表达式的查询
- 5、simple_query_string
- 四、bool query布尔查询
- 五、highlight高亮显示
- 六、地理空间位置查询
- 七、ElasticSearch8.x 向量检索
一、match_all匹配所有文档
1、介绍:
match_all查询是一个特殊的查询类型,它用于匹配索引中的所有文档,而不考虑任何特定的查询条件。
- 基本语法:
GET /<your-index-name>/_search
{"query": {"match_all": {}}
}
- 高级用法
可以再match_all查询中添加额外的参数来控制搜索结果的显示,例如设置返回的文档数量(size)、开始返回的文档位置(from)、排序规则(sort)以及选择返回哪些字段(source)。
例如,如果返回索引中的前10个文档,并且按照文档的评分进行排序,可以使用以下查询。
实现分页效果:
GET /<your-index-name>/_search
{"query": {"match_all": {}},"from": 0,"size": 3
}
实现排序:
GET /<your-index-name>/_search
{"query": {"match_all": {}},"size": 10,"sort":[{"_source": {"order":"desc"}}]
}
_source的用法:
不查看源数据,仅查看元字段:
GET /<your-index-name>/_search
{"query": {"match_all": {}},"_source": false
}
返回指定的字段:
GET /<your-index-name>/_search
{"query": {"match_all": {}},"_source": ["field1","field2"]
}
二、精确匹配
精确匹配指的是搜索内容不经过文本分析直接用于文本匹配,这个过程类似于数据库的SQL查询,搜索的对象大多是索引的非text类型字段。此类检索主要应用于结构化数据,如ID、状态和标签等。
1、term单字段精确匹配查询
对bool,日期,数字,结构化的文本可以利用term做精确匹配,查询姓名为张三的员工信息:
GET /<your-index-name>/_search
{"query": {"term": {"name": {"value": "张三"}}}
}
注意:最好不要再term查询的字段中使用text字段,因为text字段会被分词,这样做既没有意义,还很有可能什么也查不到。
在ES中,Term查询,对输入不做分词。会将输入作为一个整体,在倒排索引中查找准确的词项,并且使用相关度算分公式为每个包含该词项的文档进行相关度算分。
可以通过Constant Score将查询转换成一个Filtering,避免算分,并利用缓存,提高性能:
- 将Query转成Filter,忽略TF-IDF计算,避免相关性算分的开销
GET /<your-index-name>/_search
{"query": {"constant_score": {"filter": {"term": {"address.keyword":"value"}}}}
}
2、terms多字段精确匹配
主要应用与多值精确匹配场景,它允许用户在单个查询中指定多个词条进行精确匹配。这种查询方式适合从文档中查找包含多个特定值的字段,例如筛选出具有多个特定标签或状态的项目。而terms检索是针对未分析的字段及逆行精确匹配的,因此他在处理关键词、数字、日期等结构化数据时表现良好。
GET /<your-index-name>/_search
{"query": {"terms": {"<filed_name>": ["value1","value2","value3"]}}
}
3、range范围查询
range检索时Elasticsearch中一种针对指定字段值在给定范围内的文档的检索类型。这种查询适合对数字、日期或者其他可排序数据类型的字段进行范围赛选。range检索支持多种比较操作符,如大于(gt)、大于等于(gte)、小于(lt)和小于等于(lte)等,可以实现灵活的区间查询。
GET /<your-index-name>/_search
{"query": {"range": {"<filed_name>": ["gte":"<lower_bound>","lte":"<upper_bound>","gt":"<greater_than_bound>","lt":"less_than_bound"]}}
}
4、exists是否存在查询
exists检索在Elasticsearch中用于筛选具有特定字段值的文档。这种查询类型适用于检查文档中是否存在某个字段,或者该字段是否包含非空值。通过使用exists检索,你可以有效地过滤掉缺少关键信息的文档,从而专注于包含所需数据的结果。应用场景包括但不限于数据完整性检查、查询特定属性的文档以及对可选字段进行筛选等。
GET /<your-index-name>/_search
{"query": {"exists": {"field": "<field_name>"}}
}
5、ids根据一组id查询
可以基于ID组快速召回相关数据,从而实现高效的文档检索。
GET /<your-index-name>/_search
{"query": {"inds": {"values": ["id1","id2","id3",...]}}
}
6、prefix前缀匹配
prefix会对分词后的term进行前缀搜索:
- 它不会对要搜索的字符串分词,传入的前缀就是想要查找的前缀。
- 默认状态下,前缀查询不做相关性分数计算,它只是将所有匹配的文档返回,然后赋予所有相关分数值为1。
prefix的原理:
需要遍历所有倒排索引,并比较每个词项是否以所搜索的前缀开头。
GET /<your-index-name>/_search
{"query": {"prefix": {"your_field_name":{"value":"your_prefix_string"} }}
}
需要注意的是,这种查询方式仅适用于关键字类型(keyword)的字段。
7、wildcard通配符匹配
wildcard检索是Elasticsearch中一种支持通配符匹配的查询类型,它允许在检索时使用通配符表达式来匹配文档的字段值。通配符包括两种:
- 星号(*):表示零或多个字符,可用于匹配任意长度的字符串。
- 问号(?):表示一个字符,用于匹配任意单个字符。
wildcard检索适用于对部分已知内容的文本字段进行模糊检索。例如,在文件名或产品型号等具有一定规律的字段中,使用通配符检索可以方便地找到满足特定模式的文档。
需要注意的是,通配符查询可能会导致较高的计算负担,因此在实际应用中应该谨慎使用,尤其是在涉及大量文档的情况下。
GET /<your-index-name>/_search
{"query": {"wildcard": {"your_field_name":{"value":"your_prefix_string"} }}
}
8、fuzzy支持编辑距离的模糊查询
是一种强大的搜索功能,它能够在用户输入内容存在拼写错误或上下文不一致时,仍然返回与搜索词相似的文档。通过使用编辑距离算法来度量输入词与文档中词条的相似度,模糊查询在保证搜索结果相关性的同时,有效地提高了搜索容错能力。
编辑距离是指从一个单词转换到另一个单词需要编辑单字符的次数。如中文集团到中威集团编辑距离就是1,只需要修改一个字符;如果fuzziness值在这里设置成2,会把编辑距离为2的东东集团也查出来。
GET /<your-index-name>/_search
{"query": {"fuzzy": {"your_field":{"value":"search_term","fuzziness":"AUTO","prefix_length":1} }}
}
- fuzziness参数用于编辑距离的设置,其默认值为AUTO,支持的数值为[0,1,2]。如果值设置越界会报错。
- prefix_length: 搜索词的前缀长度,在此长度内不会应用模糊匹配。默认是0,即整个词都会被模糊匹配。
9、regexp正则匹配查询
10、term set用于解决多字段中的文档匹配问题
terms set检索是Elasticsearch中一种功能强大的检索类型,主要用于解决多值字段中的文档匹配问题,在处理具有多个属性、分类或标签的复杂数据时非常有用。
从应用场景来说,terms set检索在处理多值字段和特定匹配条件时具有很大的优势。它适用于标签系统、搜索引擎、电子商务系统、文档管理系统和技能匹配等场景。
GET /<your-index-name>/_search
{"query": {"terms_set": {"<field_name>":{"terms":["<term1>","<term2>",...],"minimum_should_match_field":"<minimum_should_match_field_name>" or"minimum_should_match_script":{"source":"<script>"}} }}
}
- <field_name>: 指定要查询的字段名,这个字段通常是一个多值字段。
- terms:提供一组词项,用于在指定字段中进行匹配。
- minimum_should_match_field: 指定一个包含匹配数量的字段名,其值应用作要匹配的最少术语数,以便返回文档。
- minimum_should_match_script: 提供一个自定义脚本,用于动态计算匹配数量。如果需要动态设置匹配所需的术语数,这个参数将非常有用。
三、全文检索
全文检索查询旨在基于相关性搜索和匹配文本数据。这些查询会对输入的文本进行分析,将其拆分为词项(单个单词),并执行诸如分词、词干处理和标准化等操作。此类检索主要应用于非结构化文本数据,如文章和评论等。
1、match分词查询
match是一种全文检索查询,它使用分析器将查询字符串分解成单独的词条,并在倒排索引中搜索这些词条。match查询适用于文本字段,并且可以通过多种参数来调整搜索行为。
对于match查询,其底层逻辑的概述:
- 分词:首先,输入的查询文本会被分词器进行分词。分词器会将文本拆分成一个个词项(terms),如单词、短语或特定字符。分词器通常根据特定的语言规则和配置进行操作。
- 匹配计算:一旦查询被分词,ES将根据查询类型和参数计算文档与查询的匹配度。对于match查询,ES将比较查询的词项与倒排索引中的词项,并计算文档的相关性得分。相关性得分衡量了文档与查询的匹配程度。
- 结果返回:根据相关性得分,ES将返回最匹配的文档作为搜索结果。搜索结果通常按照相关性得分进行排序,以便最相关的文档排在前面。
GET /<your-index-name>/_search
{"query": {"match": {"field_name":"value"}}
}
2、mutil_match多字段查询
multi_match查询在Elasticsearch中用于在多个字段上执行相同的搜索操作。它可以接受一个查询字符串,并在指定的字段集合中搜索这个字符串。multi_match查询提供了灵活的匹配类型和操作符选项,以便根据不同的搜索需求调整搜索行为。
GET /<your-index-name>/_search
{"query": {"multi_match": {"query":"<query_string>","fields":["<field1>","<field2>",...]}}
}
3、match_phrase短语查询
用于执行短语搜索,它不仅仅匹配整个短语,而且还考虑了短语中各个词的顺序和位置。这种查询类型对于搜索精确短语非常有用,尤其是在用户输入的查询与文档中的文本表达方式需要严格匹配时。
GET /<your-index-name>/_search
{"query": {"match_parse": {"<field_name>": {"query":"<phrase>"}}}
}
4、query_string支持与或非表达式的查询
是一种灵活的查询类型,它允许使用Lucene查询语法来构建复杂的搜索查询。这种查询类型支持多种逻辑运算符,包括与(AND)、或(OR)和非(NOT),以及通配符、模糊搜索和正则表达式等功能。query_string查询可以在单个或多个字段上进行搜索,并且可以处理复杂的查询逻辑。
应用场景包括高级搜索、数据分析和报表等,适合处理满足特定需求、要求支持与或非表达式的复杂查询任务,通常用于专业领域或需要高级查询功能的应用中。
GET /<your-index-name>/_search
{"query": {"query_string": {"query":"<query_string>","default_field":"<field_name>"}}
}
- <your_query_string>是查询逻辑,可以包含上述提到的逻辑运算符和通配符等。
- <field_name>是默认搜索字段,如果省略则会搜索所有可索引字段。
5、simple_query_string
类似Query String,但是会忽略错误的语法,同时支持部分查询语法,不支持AND OR NOT,会当作字符串处理。支持部分逻辑:
- +替代AND
- |替代OR
- -替代NOT
在生产环境中推荐使用simple_query_string而不是query_string,主要是因为simple_query_string提供了宽松的语法,能够容忍一定程度的输入错误,而不会导致整个查询失败。
GET /<your-index-name>/_search
{"query": {"simple_query_string": {"query":"<query_string>","fields":["<field1>","<field2>",...],"default_operator":"OR" 或 "AND"}}
}
其中<query_string>是要搜索的查询表达式,,,…是搜索可以在其中进行的字段列表,default_operator定义了查询字符串中未指定操作符时的默认逻辑运算符,可以使OR或AND。
四、bool query布尔查询
布尔查询可以按照布尔逻辑条件组织多条查询语句,只有符合整个布尔条件的文档才会被搜索出来。
在布尔条件中,可以包含两种不同的上下文:
- 搜索上下文(query context):使用搜索上下文时,Elasticsearch需要计算每个文档与搜索条件的相关度得分,这个得分的计算需要使用一套复杂的计算公式,有一定的性能开销,带文本分析的全文检索的查询语句很适合放在搜索上下文中。
- 过滤上下文(filter context):使用过滤上下文时,Elasticsearch只需要判断搜索条件跟文档数据是否匹配,例如使用term query判断一个值是否跟搜索内容一致,使用Range query判断某数据是否位于某个区间等。过滤上下文的查询不需要进行相关度得分计算,还可以使用缓存加快响应速度,很多术语级查询语句都适合放在过滤上下文中。
布尔查询一种支持4中组合类型: