You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Hibernate Search 6在Elasticsearch中搜索索引实体所有字段

解决方案:让Hibernate Search支持搜索所有@FullTextField字段

问题背景

现有基于Hibernate Search 6.2.2和Elasticsearch 8.10的查询方法,仅能固定搜索addresses.address_key字段。需要修改为支持任意格式的查询字符串(如first_name:john),并覆盖所有标注@FullTextField的字段。

原始代码

查询方法

public Page<Employee> searchEmployee(String queryString) {
       try {
            SearchSession searchSession = Search.session(entityManager);

            SearchResult<Employee> searchResult = searchSession.search(Employee.class)
                    .extension(ElasticsearchExtension.get())
                    .where(f -> f.simpleQueryString().fields("addresses.address_key").matching(queryString))
                    .fetch(Math.toIntExact(page.getOffset()), page.getPageSize());

            Page<Employee> pageResult = new PageImpl<>(searchResult.hits(), page, searchResult.total().hitCount());
            return pageResult;
        } catch (SearchException pe) {
           throw pe;
        }
}

索引实体类

@Indexed(index = "employee")
public class Employee {

  @FullTextField(name = "employee_key")
  private String employeeKey;

  @FullTextField(name = "first_name")
  private String firstName;
    
  @IndexedEmbedded(includeEmbeddedObjectId = true, includeDepth = 2)
  private Address addresses;
}

public class Address {
    
  @FullTextField(name = "address_key")
  private String addressKey;

  @FullTextField(name = "street_name")
  private String streetName;

} 

修改方案

方案1:显式指定所有目标字段

直接在查询中列出所有@FullTextField对应的字段路径,同时补充缺失的page方法参数:

public Page<Employee> searchEmployee(String queryString, Pageable page) {
       try {
            SearchSession searchSession = Search.session(entityManager);

            SearchResult<Employee> searchResult = searchSession.search(Employee.class)
                    .extension(ElasticsearchExtension.get())
                    .where(f -> f.simpleQueryString()
                            .fields("employee_key", "first_name", 
                                    "addresses.address_key", "addresses.street_name")
                            .matching(queryString))
                    .fetch(Math.toIntExact(page.getOffset()), page.getPageSize());

            Page<Employee> pageResult = new PageImpl<>(searchResult.hits(), page, searchResult.total().hitCount());
            return pageResult;
        } catch (SearchException pe) {
           throw pe;
        }
}

方案2:配置实体默认搜索字段

在Employee类的@Indexed注解中配置默认搜索字段集合,查询时无需显式指定字段,代码更简洁:

修改后的实体类

@Indexed(index = "employee", defaultSearchFields = {
    "employee_key", 
    "first_name", 
    "addresses.address_key", 
    "addresses.street_name"
})
public class Employee {

  @FullTextField(name = "employee_key")
  private String employeeKey;

  @FullTextField(name = "first_name")
  private String firstName;
    
  @IndexedEmbedded(includeEmbeddedObjectId = true, includeDepth = 2)
  private Address addresses;
}

public class Address {
    
  @FullTextField(name = "address_key")
  private String addressKey;

  @FullTextField(name = "street_name")
  private String streetName;

} 

修改后的查询方法

public Page<Employee> searchEmployee(String queryString, Pageable page) {
       try {
            SearchSession searchSession = Search.session(entityManager);

            SearchResult<Employee> searchResult = searchSession.search(Employee.class)
                    .extension(ElasticsearchExtension.get())
                    .where(f -> f.simpleQueryString().matching(queryString))
                    .fetch(Math.toIntExact(page.getOffset()), page.getPageSize());

            Page<Employee> pageResult = new PageImpl<>(searchResult.hits(), page, searchResult.total().hitCount());
            return pageResult;
        } catch (SearchException pe) {
           throw pe;
        }
}

关键说明

  • 两种方案都支持用户传入带字段限定的查询字符串(如first_name:john),Simple Query String语法会自动识别并搜索指定字段;若用户未指定字段(如john),则会搜索所有配置的字段
  • 方案1无需修改实体类,但后续新增@FullTextField字段时,需要同步更新查询代码中的字段列表
  • 方案2查询代码简洁,新增字段时只需更新实体类的defaultSearchFields配置,维护更方便
  • 原代码中缺失page方法参数,已补充到方法签名中避免编译错误

内容的提问来源于stack exchange,提问作者Gaurav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 12:35:16