当前位置: 首页 > news >正文

【Elasticsearch入门到落地】13、DSL查询详解:分类、语法与实战场景

接上篇《12、索引库删除判断以及文档增删改查》
上一篇我们讲解了如何判断索引库是否存在并删除它,以及如何对索引库中的文档进行增删改查操作。本篇我们进入ElasticSearch的DSL语法的详解。

Elasticsearch(ES)作为强大的分布式搜索引擎,其核心功能之一是通过DSL(Domain Specific Language)实现灵活的数据查询。本文将深入解析ES DSL查询的三大核心分类:全文检索查询、精确查询和地理查询,结合实际场景和语法示例,帮助开发者快速掌握ES查询精髓。

一、DSL查询基础结构

ES查询的基本结构遵循JSON格式,主要包含以下两部分:

GET /indexName/_search
{"query": {// 查询条件定义"查询类型":{"查询条件":"条件值"}},"from": 0,      // 分页起始位置"size": 10,     // 每页返回数量"sort": [       // 排序规则{"price": "asc"}]
}

二、全文检索查询

1. 使用场景

●博客文章内容搜索

●电商商品描述匹配

●日志分析中的文本挖掘
●任何需要基于文本相似度匹配的场景

2. 核心查询类型

(1)match查询(最常用)

GET /indexName/_search
{"query": {"match": {"title": {"query": "Elasticsearch教程","operator": "and",  // 可选:and/or"minimum_should_match": "75%", // 最小匹配度"fuzziness": "AUTO"  // 模糊匹配}}}
}

关键参数:
●operator:控制多个查询词的逻辑关系(默认OR)
●minimum_should_match:设置最低匹配词比例
●fuzziness:允许的拼写错误容忍度(AUTO/0/1/2)

案例测试1:

# 模糊搜索
GET /hotel/_search
{"query": {"match": {"all": "外滩如家"}}
}

案例结果1:

案例测试2:

# 模糊搜索
GET /hotel/_search
{"query": {"match": {"name": {"query": "7天酒店","operator": "and", "minimum_should_match": "75%","fuzziness": "AUTO"}}}
}

案例结果2:

(2)multi_match查询(多字段匹配)

GET /indexName/_search
{"query": {"multi_match": {"query": "大数据分析","fields": ["title^3", "content", "tags"], // ^3表示权重"type": "best_fields" // 匹配策略}}
}

匹配策略:
●best_fields:最佳字段匹配(默认)
●most_fields:多数字段匹配
●cross_fields:跨字段匹配
●phrase:短语匹配
●phrase_prefix:短语前缀匹配

案例测试:

GET /hotel/_search
{"query": {"multi_match": {"query": "外滩如家","fields": ["brand^3", "name", "business"], "type": "best_fields" }}
}

案例结果:

(3)match_phrase查询(短语匹配)

GET /indexName/_search
{"query": {"match_phrase": {"content": "快速排序算法","slop": 1 // 允许词间最大距离}}
}

match_phrase查询用于精确匹配短语,同时允许指定词间最大距离(通过 slop 参数)
slop表示允许的词序调整次数(例如将"上海 浦东 东站"调整为"上海浦东 东站"需要1次调整)

案例测试:

GET /hotel/_search
{"query": {"match_phrase": {"name": "上海浦东东站"}}
}

案例结果:

(4)query_string查询(复杂查询)

GET /indexName/_search
{"query": {"query_string": {"query": "(Java OR Python) AND 开发","default_field": "content","fields": ["title^2", "content"]}}
}

特点:
支持Lucene查询语法
可指定多个字段及权重
适合复杂查询需求

案例测试1:

GET /hotel/_search
{"query": {"query_string": {"query": "西藏 AND 万怡","default_field": "name"}}
}

案例结果1:

案例测试2:

GET /hotel/_search
{"query": {"query_string": {"query": "(机场 OR 地铁) AND 如家","fields": ["name", "business"]}}
}

案例结果2:

注意:query_string查询默认会对文本进行分词处理,如果name字段被映射为keyword类型而不是text类型,查询可能不会按预期工作。例如"商业区"可能被分词为"商"、"业"和"区"三个词,查询要求同时包含这三个词,但很多"商业区"酒店标识可能被分词为单个词,搜索时可以将"商业区"用引号括起来表示短语匹配:
"query": "(地铁 OR \"商业区\") AND 7天"

三、精确查询(Term-level Queries)

1. 使用场景

●用户ID精确查找
●订单状态筛选
●价格范围查询
●日期区间查询
●需要精确匹配而非文本分析的场景

2. 核心查询类型

(1)term查询(精确匹配)

GET /indexName/_search
{"query": {"term": {"status": "active" // 不进行分词,直接匹配}}
}

案例测试:

GET /hotel/_search
{"query": {"term": {"business": "宝安商业区" }}
}

案例结果:

(2)terms查询(多值精确匹配)

GET /indexName/_search
{"query": {"terms": {"tags": ["java", "elasticsearch", "分布式"]}}
}

案例测试:

GET /hotel/_search
{"query": {"terms": {"name": ["如家酒店","机场"] }}
}

案例结果:

(3)range查询(范围查询)

GET /indexName/_search
{"query": {"range": {"price": {"gte": 100,"lte": 500,"boost": 2.0 // 权重}}}
}

案例测试:

GET /hotel/_search
{"query": {"range": {"price": {"gte": 100,"lte": 140}}},"from": 0,      "size": 100,     "sort": [       {"price": "asc"}]
}

注:这里加了分页和排序,按照价格从低到高

案例结果:

(4)exists查询(字段存在性检查)

GET /indexName/_search
{"query": {"exists": {"field": "description"}}
}

案例测试:

GET /hotel/_search
{"query": {"exists": {"field": "city"}},"from": 0,      "size": 100,     "sort": [       {"price": "asc"}]
}

案例结果:

(5)bool组合查询(逻辑组合)

GET /indexName/_search
{"query": {"bool": {"must": [{"term": {"status": "active"}},{"range": {"price": {"gte": 100}}}],"filter": [  // filter过滤,但不参与评分{"term": {"category": "electronics"}}],"should": [  // 可选条件{"term": {"is_recommended": true}}],"minimum_should_match": 1}}
}

注:minimum_should_match只影响bool查询中的should部分,minimum_should_match参数用于控制should子句中的匹配条件,它指定了在should子句中至少需要匹配多少个条件才能使整个bool查询匹配。

案例测试:
寻找在上海,打分超过40分以上,价格不超过200元,且是如家的酒店,可选条件是二钻:

{"query": {"bool": {"must": [{"term": {"city": "上海"}},{"range": {"price": {"lte": 200}}},{"range": {"score": {"gte": 40}}}],"filter": [  {"term": {"brand": "如家"}}],"should": [  {"term": {"starName": "二钻"}}],"minimum_should_match": 1}}
}

案例结果:

四、地理查询(Geo Queries)

此场景不再举例子,大家按照需要查询关键坐标匹配即可。

1. 使用场景

●附近商家搜索
●物流配送范围查询
●基于地理位置的推荐系统
●轨迹分析

2. 核心查询类型

(1)geo_distance查询(距离查询)

GET /indexName/_search
{"query": {"bool": {"filter": {"geo_distance": {"distance": "10km","location": {  // 中心点坐标"lat": 39.57,"lon": 106.55}}}}}
}

(2)geo_bounding_box查询(矩形区域查询)

GET /indexName/_search
{"query": {"bool": {"filter": {"geo_bounding_box": {"location": {"top_left": {"lat": 30.0,"lon": 106.0},"bottom_right": {"lat": 29.0,"lon": 107.0}}}}}}
}

(3)geo_polygon查询(多边形区域查询)

GET /indexName/_search
{"query": {"bool": {"filter": {"geo_polygon": {"location": {"points": [{"lat": 30.0, "lon": 106.0},{"lat": 30.0, "lon": 107.0},{"lat": 29.0, "lon": 107.0},{"lat": 29.0, "lon": 106.0}]}}}}}
}

(4)geo_shape查询(复杂形状查询)

GET /indexName/_search
{"query": {"bool": {"filter": {"geo_shape": {"location": {"shape": {"type": "envelope",  // 矩形"coordinates": [[106.0, 30.0], [107.0, 29.0]]},"relation": "intersects" // 空间关系}}}}}
}

五、性能优化建议

1、全文检索优化:

●合理设置分词器
●使用minimum_should_match控制匹配精度
●避免在高频字段上使用match_all

2、精确查询优化:

●为常用精确查询字段设置keyword类型
●使用filter上下文提高缓存效率
●避免在bool查询中嵌套过多条件

3、地理查询优化:

●使用geo_point类型存储地理位置
●对地理查询使用filter上下文
●合理设置distance_type(arc/plane)

下一篇我们继续讲解DSL查询语法中“相关性算分”、“FunctionScoreQuery”和“BooleanQuery”的相关内容。

转载请注明出处:https://blog.csdn.net/acmman/article/details/148195366

http://www.xdnf.cn/news/623413.html

相关文章:

  • Python模块中的私有命名与命名空间管理:深入解析与实践指南
  • 刷题 | 牛客 - js中等题-下(更ing)30/54知识点解答
  • DPDK QDMA 驱动详解 - tx
  • S32K开发环境搭建详细教程(二、添加S32K3xx SDK)
  • python语法学习
  • 第十五章:数据治理之数据目录:摸清家底,建立三大数据目录
  • stable diffusion论文解读
  • 再论自然数全加和-1
  • 09 接口自动化-用例管理框架pytest之allure报告定制以及数据驱动
  • WPF 全屏显示实现(无标题栏按钮 + 自定义退出按钮)
  • 爬虫核心概念与工作原理详解
  • Redis学习专题(五)缓存穿透、缓存击穿、缓存雪崩
  • ​《Nacos终极指南:集群配置+负载均衡+健康检查+配置中心全解析,让微服务稳如老狗!》​
  • SQLAlchemy 2.0 查询使用指南
  • python使用pycharm和conda 设置默认使用清华镜像
  • 枚举类扩充处理
  • 【Qt】Qt 5.9.7使用MSVC2015 64Bit编译器
  • 基于SamOutV8的序列生成模型实现与分析
  • 如何把vue项目部署在nginx上
  • 用 AI 让学习更懂你:如何打造自动化个性化学习系统?
  • Linux10正式版发布,拥抱AI了!
  • PCB设计实践(二十七)电感的形态分类与应用场景深度解析
  • 【Linux】进程基本概念与基本操作
  • wordpress主题开发中常用的12个模板文件
  • 黑马k8s(十五)
  • 【触想智能】什么是工控一体机,工控一体机有什么用途?
  • 前端框架6
  • 折半搜索【2024华为智联杯 K.时光】
  • 安卓无障碍脚本开发全教程
  • Android-Glide学习总结