SpringBoot整合Es

SpringBoot整合Es

1.Spring Data Elasticsearch

优势

  • 官方支持的 Spring 生态组件

  • 提供 Repository 抽象,简化 CRUD 操作

  • 与 Spring 事务管理集成良好

  • 支持基于方法名的查询自动生成

  • 注解驱动的映射配置(@Document, @Id, @Field等)

劣势

  • 对 Elasticsearch 新版本支持有时滞后

  • 复杂查询可能需要使用 @Query 注解或自定义实现

  • 高级功能支持不如直接使用 REST Client 灵活

适用场景:简单的 CRUD 操作和基础搜索需求

具体使用

继承ElasticsearchRepository之后CRUD

UserEsRepository extends ElasticsearchRepository<UserEs, String>
//第一个参数为类型、方便理解加入到里面
//第二个参数为实际传入
UserEsRepository.save(User user)
UserEsRepository.saveAll(List<User> users)
UserEsRepository.findById(String id)
UserEsRepository.deleteById(String id)
UserEsRepository.findAll()

复杂查询NativeSearchQueryBuilder

先注入ElasticsearchOperations

可采用构建请求体

可采用query

2. Elasticsearch REST High Level Client

三步走或两步走战略?!

//查询体
// 1.创建requet确定查找索引
SearchRequest searchRequest = new SearchRequest("fs_news_tag_analysis");
// 2.创建builder确定查询体
// 注意:前两步是必须的
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
​
// 3.这第三步主要看自己采用什么查询
​
// 3.1.1 boolQuery,用于组合多个查询条件取并集
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.must(QueryBuilders.termQuery("source", source));     boolQuery.must(QueryBuilders.rangeQuery("new_add_date").gte(startDate).lte(endDate));
// 3.1.2 最后塞回sourceBuilder
sourceBuilder.query(boolQuery);
​
// 3.2.1 若是不采用boolQuery,可直接使用sourceBuilder,就像上面must里面的代码一样
// 注意多个这样的查询会返回合集
sourceBuilder.query(QueryBuilders.termQuery("source", source))
​
// 4.再把sourceBuilder塞回searchRequest传递给client执行
searchRequest.source(sourceBuilder);
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

现在对于QueryBuilder说明

Match

① Match Query

匹配查询(会对查询文本分词):

QueryBuilders.matchQuery("title", "elasticsearch tutorial")
② Match Phrase Query

短语精确匹配(要求分词后的顺序一致):

QueryBuilders.matchPhraseQuery("title", "elasticsearch tutorial")
③ Multi Match Query

多字段匹配(在多个字段中搜索相同的关键词):

QueryBuilders.multiMatchQuery("elasticsearch", "title", "content")
④ Query String Query

类似 Lucene 语法的查询:

QueryBuilders.queryStringQuery("title:elasticsearch AND content:tutorial")

Term

① Term Query

精确匹配某个词:

QueryBuilders.termQuery("status", "published")
② Terms Query

匹配多个词项(相当于 SQL 的 IN):

QueryBuilders.termsQuery("tags", "java", "elasticsearch", "database")
③ Range Query

范围查询(数字、日期等):

QueryBuilders.rangeQuery("price")
    .gte(10)    // >= 10
    .lte(100)   // <= 100
QueryBuilders.rangeQuery("new_add_date").gte(startDate).lte(endDate)
④ Exists Query

查询某字段存在的文档:

QueryBuilders.existsQuery("author")
⑤ Wildcard Query

通配符查询(* 匹配多个字符,? 匹配单个字符):

QueryBuilders.wildcardQuery("title", "elast*")
⑥ Prefix Query

前缀匹配:

QueryBuilders.prefixQuery("title", "elast")
⑦ Fuzzy Query

模糊查询(允许拼写错误):

QueryBuilders.fuzzyQuery("title", "elastiksearch")
    .fuzziness(Fuzziness.AUTO)  // 允许的编辑距离

Bool Query

① Bool Query

组合多个 must(必须满足)、should(或)、must_not(必须不满足)查询:

java

QueryBuilders.boolQuery()
    .must(QueryBuilders.termQuery("status", "published"))
    .should(QueryBuilders.termQuery("category", "tech"))
    .mustNot(QueryBuilders.termQuery("locked", true))
② Constant Score Query

固定分数查询(忽略相关性评分):

QueryBuilders.constantScoreQuery(QueryBuilders.termQuery("status", "published"))
    .boost(2.0f)  // 设置固定分数

4. 特殊查询

① Nested Query

嵌套对象查询:

QueryBuilders.nestedQuery("comments",
    QueryBuilders.boolQuery()
        .must(QueryBuilders.termQuery("comments.user", "Alice"))
        .must(QueryBuilders.rangeQuery("comments.likes").gte(10))
)
② Script Query

脚本查询(使用 Painless 脚本进行复杂条件判断):

QueryBuilders.scriptQuery(
    new Script("doc['price'].value > params.threshold",
        ScriptType.INLINE,
        "painless",
        Map.of("threshold", 100)
    )
)

总结 常用query

查询类型适用场景示例
matchQuery全文搜索(分词)QueryBuilders.matchQuery("title", "elasticsearch")
termQuery精确匹配(不分词)QueryBuilders.termQuery("status", "published")
rangeQuery范围查询QueryBuilders.rangeQuery("price").gte(10).lte(100)
boolQuery组合多个查询.must(termQuery).should(matchQuery)
wildcardQuery通配符匹配QueryBuilders.wildcardQuery("title", "elast*")
nestedQuery嵌套对象查询QueryBuilders.nestedQuery("comments", termQuery)

以上是query的一些参数方法说明,接下来是aggregation的一些参数方法说明

基本语法结构

json

{
  "aggs": {
    "聚合名称": {
      "聚合类型": {
        "field": "字段名"
      }
    }
  }
}

示例

  1. 按国家分组统计文档数量:

json

{
  "aggs": {
    "countries": {
      "terms": {
        "field": "country.keyword"
      }
    }
  }
}
  1. 按价格范围分组:

json

{
  "aggs": {
    "price_ranges": {
      "range": {
        "field": "price",
        "ranges": [
          { "to": 50 },
          { "from": 50, "to": 100 },
          { "from": 100 }
        ]
      }
    }
  }
}

1. Terms Aggregation (词项聚合)

  • 返回字段的每个唯一值及其计数

  • 示例:

json

{
  "aggs": {
    "sources": {
      "terms": {
        "field": "source.keyword",
        "size": 10
      }
    }
  }
}
  • 返回结构

json

"aggregations": {
  "sources": {
    "buckets": [
      {
        "key": "新闻源A",
        "doc_count": 100
      },
      {
        "key": "新闻源B",
        "doc_count": 80
      }
    ]
  }
}

2. Date Histogram Aggregation (日期直方图聚合)

  • 按固定时间间隔分组

  • 示例:

json

{
  "aggs": {
    "by_month": {
      "date_histogram": {
        "field": "publish_date",
        "calendar_interval": "month"
      }
    }
  }
}
  • 返回结构

json

"aggregations": {
  "by_month": {
    "buckets": [
      {
        "key_as_string": "2023-01-01T00:00:00.000Z",
        "key": 1672531200000,
        "doc_count": 50
      },
      {
        "key_as_string": "2023-02-01T00:00:00.000Z",
        "key": 1675209600000,
        "doc_count": 65
      }
    ]
  }
}

3. Range Aggregation (范围聚合)

  • 按自定义范围分组

  • 示例:

json

{
  "aggs": {
    "price_ranges": {
      "range": {
        "field": "price",
        "ranges": [
          { "to": 50 },
          { "from": 50, "to": 100 },
          { "from": 100 }
        ]
      }
    }
  }
}
  • 返回结构

json

"aggregations": {
  "price_ranges": {
    "buckets": [
      {
        "key": "*-50.0",
        "to": 50.0,
        "doc_count": 20
      },
      {
        "key": "50.0-100.0",
        "from": 50.0,
        "to": 100.0,
        "doc_count": 30
      },
      {
        "key": "100.0-*",
        "from": 100.0,
        "doc_count": 50
      }
    ]
  }
}

4. Histogram Aggregation (直方图聚合)

  • 按固定数值间隔分组

  • 示例:

json

{
  "aggs": {
    "price_histogram": {
      "histogram": {
        "field": "price",
        "interval": 50
      }
    }
  }
}
  • 返回结构

json

"aggregations": {
  "price_histogram": {
    "buckets": [
      {
        "key": 0,
        "doc_count": 10
      },
      {
        "key": 50,
        "doc_count": 25
      },
      {
        "key": 100,
        "doc_count": 35
      }
    ]
  }
}

5. Nested Aggregation (嵌套聚合)

  • 对嵌套文档进行聚合

  • 示例:

json

{
  "aggs": {
    "products": {
      "nested": {
        "path": "products"
      },
      "aggs": {
        "categories": {
          "terms": {
            "field": "products.category.keyword"
          }
        }
      }
    }
  }
}
  • 返回结构

json

"aggregations": {
  "products": {
    "doc_count": 100,
    "categories": {
      "buckets": [
        {
          "key": "电子产品",
          "doc_count": 60
        },
        {
          "key": "家居用品",
          "doc_count": 40
        }
      ]
    }
  }
}

获取聚合结果的通用方法

无论哪种聚合类型,都可以通过您定义的聚合名称获取结果:

java

// Java High Level Client 示例
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
​
// 获取terms聚合
Terms terms = response.getAggregations().get("sources");
    // 这儿额外对terms中的key和count字段作出说明,为了获取所有聚合类别的情况名称(按照哪样的情况分组的)
    // bucket里面有key、count,
    // key为具体字段匹配值、count为该key下的文档数;即getKey和getCount记得格式该转换的转换String还是int
    // 这两在最开始的terms设置的name下面
    List<String> sources = new ArrayList<>();
    for (Terms.Bucket bucket : sourceTerms.getBuckets()) {
        sources.add(bucket.getKeyAsString());
    }
​
// 获取date_histogram聚合
ParsedDateHistogram dateHistogram = response.getAggregations().get("by_month");
​
// 获取range聚合
ParsedRange range = response.getAggregations().get("price_ranges");
​
// 获取histogram聚合
ParsedHistogram histogram = response.getAggregations().get("price_histogram");
​
// 获取nested聚合
ParsedNested nested = response.getAggregations().get("products");

每种聚合类型都有对应的解析类,但获取方式都是通过您定义的聚合名称从getAggregations()中获取。

3. Elasticsearch Java API Client

4. Jest Client (已逐渐淘汰)

5. Spring Boot + Elasticsearch SQL (JDBC)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值