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": "字段名"
}
}
}
}
示例
-
按国家分组统计文档数量:
json
{
"aggs": {
"countries": {
"terms": {
"field": "country.keyword"
}
}
}
}
-
按价格范围分组:
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()中获取。
1万+

被折叠的 条评论
为什么被折叠?



