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

Hibernate Search Lucene:如何索引关联对象B的字段以搜索A

问题描述

我有两个JPA实体类:

待搜索的实体类A:

@Entity
@Indexed
Class A {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(updatable = false, nullable = false)
    protected Long id;


    @JsonIgnore
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "b_id", referencedColumnName = "id")
    protected B b; // 外键关联B
}

实体类B:

@Entity
Class B {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(updatable = false)
    @JsonIgnore
    private Long id;


    private String fieldToBeIndexed; // ** 想要索引此字段 **

}

我的项目里只针对A类执行搜索,示例代码如下:
FullTextQuery fullTextQuery = fullTextEntityManager.createFullTextQuery(query, A);

我希望通过输入B的fieldToBeIndexed字段值来搜索A,请问该怎么实现?如何索引B的这个字段,让A能基于它被搜索?


解决方案

要实现通过B的fieldToBeIndexed搜索A,需借助Hibernate Search的关联索引能力,把B的目标字段嵌入到A的索引中,具体操作如下:

  1. 修改A类的关联字段注解
    在A类的b字段上添加@IndexedEmbedded注解,明确指定要嵌入索引的B类字段:
@Entity
@Indexed
Class A {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(updatable = false, nullable = false)
    protected Long id;


    @JsonIgnore
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "b_id", referencedColumnName = "id")
    @IndexedEmbedded(includePaths = "fieldToBeIndexed") // 新增注解,指定嵌入的B类字段
    protected B b; // 外键关联B
}
  1. 标记B类的目标字段为可索引
    给B类的fieldToBeIndexed字段加上@Field注解,标记该字段需要被索引:
@Entity
Class B {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(updatable = false)
    @JsonIgnore
    private Long id;

    @Field // 新增注解,标记为可索引字段
    private String fieldToBeIndexed; // ** 想要索引此字段 **

}
  1. 重建索引
    修改实体类后,需要重新生成Hibernate Search的索引,确保新增字段被正确收录。可通过代码触发索引重建:
fullTextEntityManager.createIndexer().startAndWait();
  1. 编写搜索查询
    现在可以针对A索引中嵌入的b.fieldToBeIndexed字段构建查询,示例代码如下:
// 创建查询构建器
QueryBuilder queryBuilder = fullTextEntityManager.getSearchFactory()
        .buildQueryBuilder().forEntity(A.class).get();
// 构建匹配b.fieldToBeIndexed的lucene查询
org.apache.lucene.search.Query luceneQuery = queryBuilder
        .keyword()
        .onField("b.fieldToBeIndexed")
        .matching(searchInput) // searchInput为搜索框输入的内容
        .createQuery();

// 执行搜索并获取结果
FullTextQuery fullTextQuery = fullTextEntityManager.createFullTextQuery(luceneQuery, A.class);
List<A> results = fullTextQuery.getResultList();

关键说明

  • @IndexedEmbedded的作用是将关联实体的指定字段嵌入到当前实体的索引中,这样A的索引就会包含B的fieldToBeIndexed字段值。
  • @Field用于标记B类中需要被索引的字段,确保该字段内容被加入索引库。
  • 由于A关联B的fetch类型是EAGER,Hibernate Search在索引A时会自动加载B实例,获取对应字段的值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 08:53:13