什么是Query DSL
- Query DSL主要由两部分组成:查询和过滤。
- 查询部分:用于指定搜索条件和匹配规则。例如,可以使用match查询进行全文检索,term查询进行精确匹配,range查询进行范围匹配等。
- 过滤部分:用于对查询结果进行进一步的筛选和过滤。与查询查询不同,过滤查询不会影响得分计算,只是对结果进行简单的筛选操作。
查询子句
- term查询:匹配一个精确值,如一个单词或一个数字
{ "term": { "name":"lifly" } }
- match查询:匹配一个查询字符串中的一个或多个单词
{ "match": { "content": "hello world" } }
- range查询:匹配一个数值范围
-
用于根据范围条件进行查询,例如指定价格在一定区间内的商品
-
范围符号
-
gte:大于等于
-
gt:大于
-
lte:小于等于
-
lt:小于
-
-
{ "range": { "age": { "gte": 20, "lte": 30 } } }
- 分页查询:指定要跳过的文档数量(from)和需要返回的文档数量(size)
{"size::10,"from":0,"query":{"match_all":{}}
}
- 分页结果排序:sort字段进行排序,desc,asc
{"sort":{"value":"desc,asc"}
}
-
bool查询:使用布尔逻辑(与、或、非)进行复杂的查询操作
-
"must"关键字用于指定必须匹配的条件,即所有条件都必须满足
-
"must_not"关键字指定必须不匹配的条件,即所有条件都不能满足
-
"should"关键字指定可选的匹配条件,即至少满足一个条件
-
{ "bool": { "must": [ { "match": { "title": "Elasticsearch" } }], "must_not": [{ "match": { "tag": "old" } } ],"should":[{"match":{"tag":"new"}}]}
}
查询子句实战
创建索引
PUT /mall-shop_dsl
{"settings": {"number_of_shards": 2,"number_of_replicas": 0},"mappings": {"properties": {"id": {"type": "keyword"},"title": {"type": "keyword"},"summary": {"type": "text"},"price": {"type": "float"}}}
}
插入数据
PUT /mall-shop_dsl/_bulk
{ "index": { "_index": "mall-shop_dsl" } }
{ "id": "1", "title": "Spring Boot","summary":"this is a summary Spring Boot video", "price": 9.99 }
{ "index": { "_index": "mall-shop_dsl" } }
{ "id": "2", "title": "java","summary":"this is a summary java video", "price": 19.99 }
{ "index": { "_index": "mall-shop_dsl" } }
{ "id": "3", "title": "Spring Cloud","summary":"this is a summary Spring Cloud video", "price": 29.99 }
{ "index": { "_index": "mall-shop_dsl" } }
{ "id": "4", "title": "Spring_Boot", "summary":"this is a summary Spring_Boot video","price": 59.99 }
{ "index": { "_index": "mall-shop_dsl" } }
{ "id": "5", "title": "SpringBoot","summary":"this is a summary SpringBoot video", "price": 0.99 }
查询dsl编写
精准查询 term 用于精确匹配一个指定字段的关键词,不进行分词处理
GET /mall-shop_dsl/_search
{"query":{"term":{"title":"Spring Boot"}}
}
match查询 用于执行全文搜索,它会将搜索查询与指定字段中的文本进行匹配
GET /mall-shop_dsl/_search
{"query":{"match": {"title": "SpringBoot"}}
}
match all查询,查询当前索引下所有数据
GET /mall-shop_dsl/_search
{"query":{"match_all": {}}
}
有条件查询,match对查询内容进行分词,然后进行查询,多个词条之间是or的关系
GET /mall-shop_dsl/_search
{"query":{"match": {"summary": "spring"}}
}
查询多个条件
GET /mall-shop_dsl/_search
{"query": {"match": {"summary": "spring cloud"}}
}
查询返回指定资源,source用于返回对应的字段
GET /mall-shop_dsl/_search
{"_source": ["title","price"], "query": {"term": {"title": {"value": "java"}}}
}
range查询,查询价格大于1元小于20的数据
GET /mall-shop_dsl/_search
{"query":{"range":{"price":{"gt":1,"lt":20}}}
}
分页查询,查询从0开始的每页2个文档数量的数据
GET /mall-shop_dsl/_search
{"size": 2,"from": 3,"query": {"match_all": {}}
}
bool查询,查询价格大于20,且title为java的数据
GET /mall-shop_dsl/_search
{"query":{"bool": {"must": [{"match": {"summary": "Cloud"}},{"range": {"price": {"gt": 20}}}]}}
}
Query DSL查询过滤Filter多案例实战
filter查询
- 对查询结果进行筛选和过滤,返回符合条件的文档。
- filter查询对结果进行缓存,提高性能查询,用于数字,日期日期,布尔逻辑,存在性检查等操作。
- term过滤:与term查询类似,但不会影响得分计算
- range()过滤:与range查询类似,但也不会影响得分计算
- exists过滤:匹配存在指定字段的文档
- missing过滤:匹配不存在指定字段的文档
- 语法格式:
{"query": {"bool": {"filter": {// 过滤条件}}}
}
案例一:使用term过滤器查询title为java的数据
GET /mall-shop_dsl/_search
{"query": {"bool": {"filter": [{"term": {"title": "java"}}]}}
}
使用range过滤器查询价格price在10-30之间的数据
GET /mall-shop_dsl/_search
{"query": {"bool": {"filter": [{"range": {"price": {"gte": 10,"lte": 30}}}]}}
}
match高级用法之多字段匹配和短语搜索实战
-
match高级用法之多字段匹配
-
多字段搜索匹配
-
业务查询,需要在多个字段上进行文本搜索,用multi_match
-
在match的基础上支持多个字段进行文本匹配查询。
-
语法格式
-
-
GET /index/_search
{"query": {"multi_match": {"query": "要搜索的文本","fields": ["字段1", "字段2", ...]}}
}
# query:需要匹配的查询文本。
# fields:一个包含需要进行匹配的字段列表的数组。
- 短语搜索匹配- elasticsearch提供的一种高级匹配查询类型,用于执行精确的短语搜索。- 相对于match查询,match_phrase会在匹配时考虑单词的顺序和位置- 语法格式
GET /index/_search
{"query": {"match_phrase": {"field_name": {"query": "要搜索的短语"}}}
}
# field_name:要进行匹配的字段名。
# query:要搜索的短语。
- 创建索引
PUT /product
{"settings": {"number_of_shards": 2,"number_of_replicas": 0},"mappings": {"properties": {"product_name": {"type": "text"},"description": {"type": "text"},"category": {"type": "keyword"}}}
}
插入数据
POST /product/_bulk
{ "index": { "_index": "product", "_id": "1" } }
{ "product_name": "iPhone 12", "description": "The latest iPhone model from Apple", "category": "electronics" }
{ "index": { "_index": "product", "_id": "2" } }
{ "product_name": "Samsung Galaxy S21", "description": "High-performance Android smartphone", "category": "electronics" }
{ "index": { "_index": "product", "_id": "3" } }
{ "product_name": "MacBook Pro", "description": "Powerful laptop for professionals", "category": "electronics" }
{ "index": { "_index": "product", "_id": "4" } }
{ "product_name": "Harry Potter and the Philosopher's Stone", "description": "Fantasy novel by J.K. Rowling", "category": "books" }
{ "index": { "_index": "product", "_id": "5" } }
{ "product_name": "The Great Gatsby", "description": "Classic novel by F. Scott Fitzgerald", "category": "books" }
- 在product_name和description字段上执行了一个multi_match,将查询文本设置为"iphone",对这两个字段进行搜索,并返回匹配到的文档,这个是or的关系,会有最佳匹配。
GET /product/_search
{"query": {"multi_match": {"query": "iphone","fields": ["product_name","description"]}}
}
使用match_phrase
查询在description
字段上执行了一个短语搜索将要搜索的短语设置为 “classic novel”。使用match_phrase
查询,Elasticsearch将会返回包含 “classic novel” 短语的文档
GET /product/_search
{"query": {"match_phrase": {"description": "classic novel"}}
}
日常单词拼写错误-fuzzy模糊查询案例实战
介绍
-
fuzzy查询是Elasticsearch中提供的一种模糊匹配查询类型,用在搜索时容忍一些拼写错误或近似匹配
-
使用fuzzy查询,可以根据指定的编辑距离(即词之间不同字符的数量)来模糊匹配查询词
-
fuzzy模糊查询是拼写错误的简单解决方案,但具有很高的 CPU 开销和非常低的精准度
-
参数介绍
-
filed_name:要进行模糊匹配的字段名。
-
value:要搜索的词
-
fuzziness:参数指定了模糊度
-
0,1,2
-
指定数字,表示最大编辑距离,较低的数字表示更严格的匹配,较高的数字表示更松散的匹配。
-
fuzziness的值,表示针对某个单词而言,而不是总的错误的数值。
-
-
auto:elasticsearch根据词的长度自动选择模糊度
-
如果字符串的长度大于5,那fuzziness的值自动设置为2
-
如果字符串的长度小于2,那fuzziness的值自动设置为0
-
-
-
松散匹配
GET /product/_search
{"query": {"fuzzy": {"description": {"value": "nov","fuzziness": "2"}}}
}
严格匹配
GET /product/_search
{"query": {"fuzzy": {"description": {"value": "nov","fuzziness": "1"}}}
}
自动检查
GET /product/_search
{"query": {"fuzzy": {"description": {"value": "novek","fuzziness": "auto"}}}
}
DSL搜索高亮显示案例实战
-
在 ES 中,高亮语法用于在搜索结果中突出显示与查询匹配的关键词
-
高亮显示是通过标签包裹匹配的文本来实现的,通常是 或其他 HTML 标签
-
基本用法:在 highlight 里面填写要高亮显示的字段,可以填写多个
-
在DSL查询语句中添加highlight字段,指定要高亮的字段以及高亮显示的前置和后置标签。
-
高亮显示通常只适用于全文检索查询(如match、multi_match等),因为这类查询会对文本进行分词处理,从而能够识别出与查询关键词匹配的文本片段。
单条件查询高亮显示(商品名称为iphone)
GET /product/_search
{"query": {"match": {"product_name": "iPhone"}},"highlight": {"fields": {"product_name": {}}}
}
多条件查询(title为iPhone,description中包含iphone的高亮显示)
GET /product/_search
{"query": {"bool": {"should": [{"match": {"product_name": "iphone"}},{"match": {"description": "iphone"}}]}},"highlight": {"fields": {"product_name": {},"description": {}}}
}
多条件查询(title为iPhone,description中包含iphone的高亮显示)修改样式
-
pre_tags:前置标签
-
post_tags:后置标签
-
fields:需要高亮的字段
GET /product/_search
{"query": {"bool": {"should": [{"match": {"product_name": "iphone"}},{"match": {"description": "iphone"}}]}},"highlight": {"pre_tags": "<font color='yellow'>","post_tags": "</font>","fields": {"product_name": {},"description": {}}}
}
通过本实战指南,您已掌握了Elasticsearch Query DSL的核心技能,从基础查询到高级搜索技巧,再到性能优化策略。实践是检验真理的唯一标准,鼓励您动手尝试这些示例,在真实项目中灵活运用这些知识,构建高性能、高灵活性的搜索解决方案。无论是处理海量数据的快速检索,还是构建精准的全文搜索体验,Query DSL都是您不可或缺的工具箱。继续探索Elasticsearch的广阔世界,让数据为您所用,解锁更多业务洞察与价值。
更多精彩内容请关注以下公众号