首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Hibernate Search 全文檢索完整整合指南:從 Maven 依賴到中文分詞與多條件查詢

     編輯:Java 相關知識

Maven 依賴配置

<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-search-orm</artifactId>
  <version>${hibernate-search.version}</version>
</dependency>
<dependency>
  <groupId>org.apache.lucene</groupId>
  <artifactId>lucene-analyzers-smartcn</artifactId>
  <version>${lucene.version}</version>
</dependency>
<dependency>
  <groupId>org.apache.lucene</groupId>
  <artifactId>lucene-queryparser</artifactId>
  <version>${lucene.version}</version>
</dependency>

Spring 整合配置

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
  <property name="hibernateProperties">
    <props>
      <prop key="hibernate.search.default.indexBase">indexes/</prop> <!-- 索引儲存路徑 -->
      <prop key="hibernate.search.analyzer">org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer</prop> <!-- 全域中文分詞 -->
    </props>
  </property>
</bean>

實體類註解映射

@Indexed
@AnalyzerDef(name = "enTopicAnalyzer",
  charFilters = @CharFilterDef(factory = HTMLStripCharFilterFactory.class),
  tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),
  filters = {
    @TokenFilterDef(factory = StandardFilterFactory.class),
    @TokenFilterDef(factory = StopFilterFactory.class),
    @TokenFilterDef(factory = PhoneticFilterFactory.class, params = @Parameter(name="encoder", value="DoubleMetaphone")),
    @TokenFilterDef(factory = SnowballPorterFilterFactory.class, params = @Parameter(name="language", value="English"))
  })
public class Topic {
  @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
  @Analyzer(definition = "enTopicAnalyzer")
  private String title;

  @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
  @Analyzer(definition = "enTopicAnalyzer")
  private String content;

  @Enumerated(EnumType.STRING)
  @Field(index=Index.YES, analyze=Analyze.NO, store=Store.NO, bridge=@FieldBridge(impl=EnumBridge.class))
  private TopicStatus status;
}

索引建立與重建

FullTextSession fts = Search.getFullTextSession(sessionFactory.openSession());
try {
    fts.createIndexer().startAndWait(); // 全量建立索引
} catch (InterruptedException e) { log.error(e); }
finally { fts.close(); }

查詢 API 實戰

單欄位關鍵字查詢

QueryBuilder qb = fts.getSearchFactory().buildQueryBuilder().forEntity(Show.class).get();
org.apache.lucene.search.Query luceneQuery = qb.keyword()
    .onFields("title", "content")
    .matching(keyword)
    .createQuery();

FullTextQuery hibernateQuery = fts.createFullTextQuery(luceneQuery, Show.class);
List<Show> results = hibernateQuery.list();

多條件組合查詢

MustJunction must = qb.bool()
    .must(qb.keyword().onFields("title", "content").matching(keyword).createQuery());

if (status != null) {
    must.must(qb.keyword().onField("status").matching(status).createQuery());
}
if (excludeStatus != null) {
    must.must(qb.keyword().onField("status").matching(excludeStatus).createQuery()).not();
}
if (username != null) {
    must.must(qb.keyword().onField("owner.username").ignoreFieldBridge().matching(username).createQuery());
}

FullTextQuery query = fts.createFullTextQuery(must.createQuery(), Topic.class);

中文分詞配置三種方式

  1. 全域配置:hibernate.search.analyzer=org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer
  2. 類級別:@Indexed @Analyzer(impl=SmartChineseAnalyzer.class)
  3. 欄位級別:@Field(analyzer=@Analyzer(impl=SmartChineseAnalyzer.class))

需額外引入 lucene-analyzers-smartcn 依賴。其他熱門分詞器:IKAnalyzer、paoding、mmseg4j。

常見坑點與避坑指南

  • 修改實體註解後必須重建索引:單元測試通過但正式環境報錯,多半是忘記 createIndexer()
  • 中文分詞預設按字切分:未配置分詞器時「測試」會被拆成「測」「試」,導致搜尋不到
  • Enum 欄位需自訂 FieldBridge:預設不支援 Enum 直接索引
  • Projection 查詢需 store=Store.YES:若只回傳部分欄位,對應欄位必須存儲原值

總結

Hibernate Search 無縫整合 Hibernate ORM 與 Lucene,透過註解驅動索引映射、支援靈活的分詞器鏈與多條件組合查詢。關鍵成功因子:正確配置中文分詞器、建立索引流程自動化、善用 MustJunction 構建複雜查詢邏輯。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved