什么是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的广阔世界,让数据为您所用,解锁更多业务洞察与价值。
更多精彩内容请关注以下公众号