SpringBoot 集成 Elasticsearch:如何通过 High Level Client 实现嵌套文档查询?

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. 常见问题解决方案
  1. 查询无结果

    • 检查字段路径是否正确(区分./
    • 确认索引映射中字段定义为nested类型
  2. 性能优化

    // 添加路径过滤器
    nestedQuery.innerHit(new InnerHitBuilder()
        .setSize(5)  // 限制返回嵌套文档数量
    );
    

  3. 聚合嵌套文档

    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. 常见问题解决方案
  1. 查询无结果

    • 检查字段路径是否正确(区分./
    • 确认索引映射中字段定义为nested类型
  2. 性能优化

    // 添加路径过滤器
    nestedQuery.innerHit(new InnerHitBuilder()
        .setSize(5)  // 限制返回嵌套文档数量
    );
    

  3. 聚合嵌套文档

    AggregationBuilder aggregation = AggregationBuilders.nested("nested_items", "items")
        .subAggregation(AggregationBuilders.terms("product_count").field("items.product_name.keyword"));
    

注意:嵌套文档查询需要严格遵循Elasticsearch的嵌套数据模型,每个嵌套对象在内部作为独立文档存储,需使用nested查询保证查询原子性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值