ElasticSearch组合查询及实际应用

发布于:2025-03-17 ⋅ 阅读:(18) ⋅ 点赞:(0)

 一、引言

        在ElasticSearch快速入门一文中,我向大家简单介绍了ES和一些基本的查询语法,接下来我将结合黑马程序员的黑马旅游案例再深入介绍一些组合DSL,并将其与开发中的应用对照起来。

二、场景功能简介

        这部分我们简单介绍一下有哪些业务场景以及需要用到的查询和属性(注意并非所有属性,其他属性可自行扩展)。

1.条件查询回显ES索引库中的文档

(1)Boolean Query

BooleanQuery 是一个非常强大且常用的查询类型,它允许你组合多个查询条件来构建复杂的查询逻辑。BooleanQuery支持四种类型的子查询:mustshouldmust_notfilter。   

  • must

    • 必须条件:查询中所有 must 子句柄指定的条件都必须满足。这相当于逻辑运算中的 AND。如果一个文档满足所有 must 条件,那么它将被包含在查询结果中。

    • 评分相关性:must 条件会影响文档的相关性评分,即更符合 must 条件的文档会有更高的评分。

  • should

    • 可选条件:查询中 should 子句柄指定的条件至少有一个需要满足。这相当于逻辑运算中的 ORshould 子句柄通常用于指定那些理想条件下的查询,但不是强制要求。

    • 评分相关性:should 条件也会影响文档的相关性评分,满足的 should 条件越多,文档的相关性评分越高。

    • 最小匹配:可以通过 minimum_should_match 参数指定必须满足的最小 should 条件数。

  • must_not

    • 排除条件:查询中 must_not 子句柄指定的条件必须不满足。这相当于逻辑运算中的 NOT。如果一个文档不满足 must_not 条件,那么它将被包含在查询结果中。

  • filter

    • 过滤条件:filter 子句柄用于应用过滤查询结果,但不会影响文档的相关性评分。filter 子句柄通常用于那些不需要计算评分的查询条件,如范围查询、术语查询等。

    • 缓存:filter 条件通常会被缓存,这可以提高查询性能,特别是当相同的过滤条件被多次使用时。        

 (2)Bucket 聚合

Bucket 聚合是 Elasticsearch 中一种基于文档集合进行切分的聚合方式,它将文档集合分成多个 bucket,并对每个 bucket 进行计算和分析,类似GroupBy。

2.广告置顶 

(3)Function_score Query

function_score查询允许你修改由查询检索到的文档的分数。

  • script

    • 一个脚本,用于计算每个文档的新分数。脚本可以访问文档的字段值,并基于这些值计算分数。

    • 脚本中可以使用内置的数学函数和逻辑运算符。

  • boost

    • 一个乘法因子,用于调整 script 脚本计算出的分数。这允许你控制脚本分数的影响程度。

  • boost_mode

    • 指定如何将脚本分数与查询分数结合。常见的选项包括:

      • "replace":用脚本分数替换查询分数。

      • "multiply":将脚本分数与查询分数相乘。

      • "sum":将脚本分数与查询分数相加。

      • "avg":计算脚本分数和查询分数的平均值。

      • "max":取脚本分数和查询分数的最大值。

  • weight

    • 属性允许你控制评分函数对最终分数的影响程度。通过增加 weight 值,可以增强评分函数对文档相关性的影响。

3.通过经纬度点匹配附近酒店

(4)Geo-distance Query

Geo-distance Query基于距离查询,返回距离指定点一定范围内的文档。

  • distance

    • 指定要搜索的距离范围,可以是任意正数,并且可以附带单位(如 km 表示公里,mi 表示英里)。

  • location

    • 指定参考点的地理坐标。可以是如下格式之一:

      • 经纬度和经度的数组:[lon, lat]

      • GeoJSON 格式的点对象:{ "type": "point", "coordinates": [lon, lat]}

      • Well-Known Text(WKT)格式的字符串,例如:"POINT (lon lat)"

4.自动补全回显搜索框内容

(5)Suggestion

Elasticsearch 的自动补全(Suggestion)功能主要通过 suggest 查询来实现,它通常与 completion 类型的字段一起使用。

  • prefix

    • 指定自动补全的前缀字符串,用户输入的初始部分内容。这是触发自动补全功能的关键输入。

  • completion

    • 指定用于自动补全的字段,它必须是 completion 类型字段。

  • size

    • 指定返回的建议列表的大小,即返回的最大建议项数。

  • context

    • 提供上下文信息,用于改进自动补全的准确性。上下文可以是任何可以识别的字段,Elasticsearch 会使用这些上下文信息来优化建议的相关性。

  • skip_duplicates

    • 指定是否跳过重复的建议项。如果设置为 true,则自动补全结果中不会包含重复项。

  • sort

    • 指定对自动补全结果进行排序的方式。可以是 score(基于分数排序)或 score_desc(分数降序)。

  • source

    • 指定是否返回建议项的详细来源信息。如果设置为 true,则返回包含文档的详细信息。

  • context_values

    • 指定用于自动补全的上下文字段的值。这些值用于在提供建议时考虑额外的过滤条件。

  • collate

    • 指定是否对自动补全结果进行聚合。如果设置为 true,则对相同建议进行聚合。

 三、实际应用(RestHighLevelClient)

        这部分我会结合DSL和代码块展示给大家,流程大致分为创建Request对象->编辑DSL->发送请求->解析响应结果,大家可以自行对照理解扩展。

1.首先在配置类注入Bean对象

    @Bean
    public RestHighLevelClient client(){
        return new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://ip")));//ip换自己的主机ip和端口
    }

2.创建SearchRequest对象

        //准备Request
        SearchRequest request = new SearchRequest("hotel");

3.条件过滤查询

  • 查询

  • 解析

4.Buket聚合

  • 聚合

  • 解析

 5.Function_score Query(广告置顶)

  • 算分控制

  •  结果解析

经过前五步即可实现基本的条件过滤查询及广告置顶功能

 6.Geo-distance Query附近酒店

  • 查询

  •  解析

 至此附近酒店查询已完成

 7.Suggestion自动补全回显搜索框内容

此处根据首字母提示补全关键词,需要用到ES的pinyin分词插件,大家可以自行寻找教程安装

  •  DSL

  •  解析

 至此搜索框自动补全功能也已完成

        可见ES不但在海量数据检索提效上有重要意义,其对于特殊场景的处理也十分灵活精确,那ES可以代替MySQL吗,答案是否定的,他们两者各有千秋,在事务处理方面MySQL是优于ES的,在实际开发中往往会将两者结合使用发挥各自的长处。

        那么本次分享到这里就结束了,感谢阅读。