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的索引中,具体操作如下:
- 修改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 }
- 标记B类的目标字段为可索引
给B类的fieldToBeIndexed字段加上@Field注解,标记该字段需要被索引:
@Entity Class B { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(updatable = false) @JsonIgnore private Long id; @Field // 新增注解,标记为可索引字段 private String fieldToBeIndexed; // ** 想要索引此字段 ** }
- 重建索引
修改实体类后,需要重新生成Hibernate Search的索引,确保新增字段被正确收录。可通过代码触发索引重建:
fullTextEntityManager.createIndexer().startAndWait();
- 编写搜索查询
现在可以针对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
相关产品推荐
相关产品推荐

