SpringBoot集成Elasticsearch:嵌套文档查询实现指南
1. 前置条件
-
依赖配置(pom.xml):
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> -
索引映射示例(嵌套文档结构):
{ "properties": { "order_id": {"type": "keyword"}, "items": { "type": "nested", // 关键:声明为嵌套类型 "properties": { "product_name": {"type": "text"}, "quantity": {"type": "integer"} } } } }
2. 配置High Level Client
@Configuration
public class ElasticsearchConfig {
@Bean
public RestHighLevelClient client() {
return new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
}
}
3. 嵌套文档查询实现
@Service
public class OrderSearchService {
@Autowired
private RestHighLevelClient client;
public List<Order> searchNestedItems(String productName) throws IOException {
// 1. 创建嵌套查询
QueryBuilder nestedQuery = QueryBuilders.nestedQuery(
"items", // 嵌套字段路径
QueryBuilders.matchQuery("items.product_name", productName),
ScoreMode.None // 评分模式
);
// 2. 构建搜索请求
SearchRequest request = new SearchRequest("orders_index");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
.query(nestedQuery)
.size(10);
request.source(sourceBuilder);
// 3. 执行查询
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 4. 结果解析
return Arrays.stream(response.getHits().getHits())
.map(hit -> parseOrder(hit.getSourceAsString()))
.collect(Collectors.toList());
}
private Order parseOrder(String source) {
// JSON解析逻辑(使用Jackson/Gson)
}
}
4. 关键参数说明
| 参数 | 作用 |
|---|---|
nestedQuery() | 声明嵌套查询 |
"items" | 嵌套字段的路径(需与映射定义一致) |
ScoreMode | 可选值:Avg(平均分)、Max(最高分)、Total(总分)、None(无评分) |
5. 复杂查询示例(多条件嵌套)
// 组合查询:产品名包含"手机"且数量>2
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
.must(QueryBuilders.matchQuery("items.product_name", "手机"))
.must(QueryBuilders.rangeQuery("items.quantity").gt(2));
QueryBuilder nestedQuery = QueryBuilders.nestedQuery("items", boolQuery, ScoreMode.None);
6. 常见问题解决方案
-
查询无结果
- 检查字段路径是否正确(区分
.和/) - 确认索引映射中字段定义为
nested类型
- 检查字段路径是否正确(区分
-
性能优化
// 添加路径过滤器 nestedQuery.innerHit(new InnerHitBuilder() .setSize(5) // 限制返回嵌套文档数量 ); -
聚合嵌套文档
AggregationBuilder aggregation = AggregationBuilders.nested("nested_items", "items") .subAggregation(AggregationBuilders.terms("product_count").field("items.product_name.keyword"));
注意:嵌套文档查询需要严格遵循Elasticsearch的嵌套数据模型,每个嵌套对象在内部作为独立文档存储,需使用
nested查询保证查询原子性。
SpringBoot集成Elasticsearch:嵌套文档查询实现指南
1. 前置条件
-
依赖配置(pom.xml):
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> -
索引映射示例(嵌套文档结构):
{ "properties": { "order_id": {"type": "keyword"}, "items": { "type": "nested", // 关键:声明为嵌套类型 "properties": { "product_name": {"type": "text"}, "quantity": {"type": "integer"} } } } }
2. 配置High Level Client
@Configuration
public class ElasticsearchConfig {
@Bean
public RestHighLevelClient client() {
return new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
}
}
3. 嵌套文档查询实现
@Service
public class OrderSearchService {
@Autowired
private RestHighLevelClient client;
public List<Order> searchNestedItems(String productName) throws IOException {
// 1. 创建嵌套查询
QueryBuilder nestedQuery = QueryBuilders.nestedQuery(
"items", // 嵌套字段路径
QueryBuilders.matchQuery("items.product_name", productName),
ScoreMode.None // 评分模式
);
// 2. 构建搜索请求
SearchRequest request = new SearchRequest("orders_index");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
.query(nestedQuery)
.size(10);
request.source(sourceBuilder);
// 3. 执行查询
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 4. 结果解析
return Arrays.stream(response.getHits().getHits())
.map(hit -> parseOrder(hit.getSourceAsString()))
.collect(Collectors.toList());
}
private Order parseOrder(String source) {
// JSON解析逻辑(使用Jackson/Gson)
}
}
4. 关键参数说明
| 参数 | 作用 |
|---|---|
nestedQuery() | 声明嵌套查询 |
"items" | 嵌套字段的路径(需与映射定义一致) |
ScoreMode | 可选值:Avg(平均分)、Max(最高分)、Total(总分)、None(无评分) |
5. 复杂查询示例(多条件嵌套)
// 组合查询:产品名包含"手机"且数量>2
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
.must(QueryBuilders.matchQuery("items.product_name", "手机"))
.must(QueryBuilders.rangeQuery("items.quantity").gt(2));
QueryBuilder nestedQuery = QueryBuilders.nestedQuery("items", boolQuery, ScoreMode.None);
6. 常见问题解决方案
-
查询无结果
- 检查字段路径是否正确(区分
.和/) - 确认索引映射中字段定义为
nested类型
- 检查字段路径是否正确(区分
-
性能优化
// 添加路径过滤器 nestedQuery.innerHit(new InnerHitBuilder() .setSize(5) // 限制返回嵌套文档数量 ); -
聚合嵌套文档
AggregationBuilder aggregation = AggregationBuilders.nested("nested_items", "items") .subAggregation(AggregationBuilders.terms("product_count").field("items.product_name.keyword"));
注意:嵌套文档查询需要严格遵循Elasticsearch的嵌套数据模型,每个嵌套对象在内部作为独立文档存储,需使用
nested查询保证查询原子性。
5683

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



