查询
介绍
检索是es最核心的功能,它能够快速、精准的从海量数据中检索出用户最想要的数据。而在es中有很多查询关键词,如:match、term、math_pharse等,它们应用在各种检索场景下,使用错了关键词会导致准确性、查询速度大打折扣。
检索分类
精确匹配
精确匹配是es中根据确切的值查询文档的方式;精确匹配不对文档进行分词处理,它是将整个文档当作一个完整的词条,查询的关键词必须与文档中的词一模一样,才会被查询回来。它的目的主要应用于结构化数据,例如:主键、标签等内容。
全文检索
全文检索es中一种对文档内容进行深入分析和处理的方式,以便查询到与之有关的文档。它通常考虑词汇的语义关联等,并根据文档与查询关键字的相关程度来进行评分。它主要根据文档的分词器有关,分词器会对文档进行深度处理,把文档拆分成若干个词汇。全文检索主要应用于非结构化文本数据,例如:文档、评价等。
组合索引
组合查询是将多个查询条件组合在一起的检索方式。用户可以根据多个因素来定位相关的文档,从而实现较为复杂的查询。
示例
在平时工作中最常见的就是精确匹配、全文检索、组合这三种;下面会挑一些常用的关键词详细介绍。
数据准备:
PUT test_index
{
"mappings": {
"properties": {
"age": {
"type": "long"
},
"brith": {
"type": "date",
"format": "[yyyy-MM-dd HH:mm:ss]"
},
"city": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword"
}
}
},
"pinyin": {
"type": "text",
"analyzer": "english"
},
"tags": {
"type": "keyword"
},
"title": {
"type": "text"
}
}
}
}
POST test_index/_doc
{
"title":"德玛西亚",
"brith":"2024-07-20 10:00:00",
"city":"德玛西亚-地点1",
"pinyin":"de ma xi ya"
}
POST test_index/_doc
{
"title":"德玛皇子",
"brith":"2024-07-20 10:00:00",
"city":"德玛西亚-地点2",
"pinyin":"de ma huang zi"
}
POST test_index/_doc
{
"title":"卡特琳娜",
"brith":"2024-07-20 10:00:00",
"tags":["刺客","法师"],
"city":"诺克萨斯-地点1",
"age":1,
"pinyin":"ka te lin na"
}
POST test_index/_doc
{
"title":"诺克萨斯",
"brith":"2024-08-20 10:00:00",
"tags":"展示",
"city":"诺克萨斯-地点2",
"age":3,
"pinyin":"nuo ke sa si"
}
查看它的分词:
GET test_index/_analyze
{
"text":"德玛西亚"
}
------------- 结果-------------
{
"tokens" : [
{
"token" : "德",
"start_offset" : 0,
"end_offset" : 1,
"type" : "<IDEOGRAPHIC>",
"position" : 0
},
{
"token" : "玛",
"start_offset" : 1,
"end_offset" : 2,
"type" : "<IDEOGRAPHIC>",
"position" : 1
},
{
"token" : "西",
"start_offset" : 2,
"end_offset" : 3,
"type" : "<IDEOGRAPHIC>",
"position" : 2
},
{
"token" : "亚",
"start_offset" : 3,
"end_offset" : 4,
"type" : "<IDEOGRAPHIC>",
"position" : 3
}
]
}
term
POST test_index/_search
{
"query": {
"term": {
"title": {
"value": "德玛西亚"
}
}
}
}
POST test_index/_search
{
"query": {
"term": {
"title": {
"value": "德"
}
}
}
}
第一个命令的结果是空,因为分词后没有“俄罗斯”这个词语,没办法完全匹配,如果把title的属性只设置为keyword,则不会对“德玛西亚”进行分词就可以匹配到。第二个命令会返回“俄罗斯与乌克兰”这条数据因为分词后有“俄”这个词。
terms
terms主要应用于多个值的精确匹配场景,它允许用户在单个查询中指定多个值来进行精确的匹配。例如:
POST test_index/_search
{
"query": {
"terms": {
"title": [
"德"
]
}
}
}
range
它是一种范围检索,允许用户查询一段范围内容的数据。它支持多种比较操作符:gt、gte、lt、lte等。示例:
POST test_index/_search
{
"query": {
"range": {
"brith": {
"gte": "2024-07-19 10:00:00",
"lte": "2024-07-21 09:00:00"
}
}
}
}
exists
它用于筛选索引中具有特定字段值的文档。它适用于检查文档是否存在某个字段,或者该字段是否包含非空值。示例:
POST test_index/_search
{
"query": {
"exists": {
"field": "tags"
}
}
}
wildcard
wildcard支持通配符匹配,它允许在检索时使用通配符边大师来匹配文档的字段值。
* :表示0个或者多个字符,可用于匹配人意长度的字符串。
? :表示一个字符,用于匹配任意单个字符。
这种查询会匹配索引中的全部文档,实际开发中慎重使用。
POST test_index/_search
{
"query": {
"wildcard": {
"tags": {
"value": "?客*"
}
}
}
}
prefix
前缀索引,它允许根据指定前缀查询文档的字段值,它适合查询以特定字符开头的字段。例如:
POST test_index/_search
{
"query": {
"prefix": {
"city.keyword": {
"value": "诺克萨斯"
}
}
}
}
term_set
它是es中功能比较强大的检索类型;主要解决多值字段的文档匹配问题,在处理具有多个属性的复杂数据时非常有用。它的核心功能在于匹配一定数量给定词项的文档,其中匹配的数量可以是固定值,也可以是动态值。示例:查询给定标签,并且每年至少学会一个标签的英雄。
POST test_index/_search
{
"query": {
"terms_set":{
"tags":{ -- 通常匹配数组或集合
"terms":["刺客","展示"],
"minimum_should_match_field": "age" -- 给定一个词项,例如年龄。
}
}
}
}
fuzzy
平时在搜索的时候难免会有打错字的时候,此时fuzzy就派上了用场。如:
POST test_index/_search
{
"query": {
"fuzzy": {
"pinyin": {
"value": "maa"
}
}
}
}
match全文检索
match检索适合应用于高召回率和结果精确要求比较低的场景;它的本质上由bool检索和term检索相结合构成的,这意味着在确保较高召回率的前提下,它会牺牲一定的精确度和性能来满足各种查询需求。 当使用match对一个值进行查询时,会先对该值进行分词,分词后再以bool组成term进行查询。例:
POST test_index/_search
{
"query": {
"match": {
"title": "德玛西亚"
}
}
}
此时会召唤回来两条,"德玛西亚"因为分数更高会在最前面,“德玛皇子”匹配度较低排在后面。
match_phrase
它适用于注重精确度的召回场景,与match不同,它更适合成为短语匹配查询。因为它要求查询的词条顺序和文档中的词条顺序保持一致,所以它的精确度会更高。例:
POST test_index/_search
{
"query": {
"match_phrase": {
"title": "玛皇"
}
}
}
当使用match_phrase时只能召回回来"德玛皇子",而使用match时可以把两个都召回回来。
multi_match
它适用于多个字段上支持match的场景,由于该方法同时检索多个字段所以性能上会比单个检索更快。例:
POST test_index/_search
{
"query": {
"multi_match": {
"query": "诺克萨斯",
"fields": ["title" ,"city"]
}
}
}
bool
bool组合检索是一种功能强大的查询方式,当需要同时满足多个条件时可以采用bool关键词。它主要包括四种子查询:
- must:查询结果必须满足指定条件
- must_not:查询条件必须不满足指定条件。
- filter:过滤条件;使用filter时会缓存数据提高查询性能。
- should:查询时满足部分条件,由minimum_should_match参数控制。
POST test_index/_search
{
"query": {
"bool": {
"must": [
{
"prefix": {
"city.keyword": {
"value": "诺克萨斯"
}
}
}
],
"must_not": [
{
"term": {
"tags": {
"value": "刺客"
}
}
}
]
}
}
}