SpringBoot與Hibernate Search整合,實現法律文書智能條款匹配系統
作者:Java知識日歷
Hibernate Search不僅能夠提供高效、準確的全文搜索功能,還能夠與現有的JPA體系無縫集成,簡化開發流程并降低維護成本。
Hibernate Search不僅能夠提供高效、準確的全文搜索功能,還能夠與現有的JPA體系無縫集成,簡化開發流程并降低維護成本。
哪些公司使用了Hibernate Search?
- Red Hat : 作為 Hibernate Search 的主要維護者,Red Hat 在其多個產品和服務中使用了 Hibernate Search。
- BBC:在內容管理系統中使用 Hibernate Search 提高新聞報道的檢索效率。
- CNN:在多媒體資產管理系統中使用 Hibernate Search 支持記者的工作流程。
- Adobe: 在其文檔管理系統中使用 Hibernate Search 來提供高效的搜索功能。
- MuleSoft:使用 Hibernate Search 提供集成平臺中的搜索功能。
- WildFly:紅帽的 WildFly 應用服務器也集成了 Hibernate Search 以支持搜索需求。
- US Department of Veterans Affairs (VA):在醫療記錄管理系統中使用 Hibernate Search 支持醫療服務。
- NASA:在數據管理系統中使用 Hibernate Search 處理大量的科學數據。
- Stanford University:在學術資源管理系統中使用 Hibernate Search 提高文獻檢索效率。
- Harvard University:在圖書館信息系統中使用 Hibernate Search 支持學生和研究人員的信息查詢。
- AT&T:在客戶服務系統中使用 Hibernate Search 提供快速響應的搜索功能。
- Verizon:在網絡管理系統中使用 Hibernate Search 優化設備信息的檢索。
應用場景
1. 文檔管理與檢索
- 法律文件存儲:將大量的法律文件(如合同、判決書、法規等)存儲在數據庫中,并通過 Hibernate Search 實現快速檢索。
- 版本控制:記錄每個條款的歷史版本,支持回滾到之前的版本。
2. 知識管理系統
- 案例庫:構建內部案例庫,律師可以通過關鍵詞快速查找相關案例。
- 法律研究:支持復雜的查詢條件,幫助律師進行深入的法律研究。
3. 客戶關系管理
- 客戶檔案:管理客戶的法律文件和歷史記錄,方便律師隨時查看。
- 溝通記錄:記錄與客戶的溝通記錄,支持全文搜索和高級過濾。
4. 合規性檢查
- 法規監測:自動監測最新的法律法規變化,并提醒律師進行相應的調整。
- 風險評估:通過搜索和分析相關法規,幫助企業進行合規性風險評估。
Hibernate Search 的優勢
1. 與JPA無縫集成
- 現有基礎:如果你已經在項目中使用了Spring Data JPA來管理數據庫操作,Hibernate Search可以直接與其集成,無需額外的配置和學習成本。
- 一致性:保持技術和架構的一致性,減少不同技術棧之間的切換和適配工作。
2. 強大的全文搜索功能
- 多字段搜索:支持在多個字段上進行全文搜索,滿足復雜的查詢需求。
- 模糊搜索:內置的模糊搜索功能可以幫助用戶找到拼寫錯誤或類似的條目。
- 高亮顯示:可以通過配置輕松實現搜索結果中的關鍵字高亮顯示,提高用戶體驗。
3. 豐富的查詢功能
- 布爾查詢:支持復雜的布爾邏輯(AND、OR、NOT),方便用戶構建精確的搜索條件。
- 范圍查詢:可以對數值型字段進行范圍查詢,例如日期范圍、價格范圍等。
- 排序和分頁:內置的支持排序和分頁功能,確保搜索結果的相關性和易用性。
4. 易于擴展和維護
- 模塊化設計:Hibernate Search的設計使得它可以很容易地與其他組件集成,便于未來的功能擴展。
- 社區和支持:擁有活躍的開源社區和豐富的文檔資源,遇到問題時可以獲得及時的幫助和解決方案。
5. 高性能
- 索引優化:Hibernate Search提供了高效的索引機制,確保快速的數據檢索能力。
- 緩存機制:利用緩存技術加速常用數據的訪問速度,提高系統性能。
6. 安全性
- 權限控制:可以根據不同的用戶角色分配不同的搜索權限,確保數據的安全性。
7. 自動索引管理
- 增量索引:Hibernate Search會自動處理實體對象的變化(如新增、修改、刪除),并在后臺更新索引。
- 批處理:支持批量索引操作,提高索引效率。
8. 靈活的分析器配置
- 多種分析器:提供多種內置分析器(如標準分析器、停用詞過濾器等),并允許自定義分析器以適應特定的語言和需求。
- 多語言支持:支持多種語言的文本分析,適合國際化應用。
代碼實操
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.0</version>
<relativePath/><!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>lawmatcher</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>lawmatcher</name>
<description>Law Document Clause Matching System</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.search.orm</groupId>
<artifactId>hibernate-search-mapper-orm</artifactId>
<version>6.2.0.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
添加點測試數據
添加一些中國《勞動法》的真實條款數據用于測試
-- 插入中國《勞動法》的部分條款數據
INSERT INTO legal_provision (title, content) VALUES
('第十七條', '勞動合同依法訂立即具有法律約束力,當事人必須履行勞動合同規定的義務。'), -- 合同生效即具法律效力
('第三十條', '用人單位解除勞動合同,應當提前三十日以書面形式通知勞動者本人。'), -- 解除合同需提前通知
('第四十四條', '有下列情形之一的,用人單位應當按照下列標準支付高于勞動者正常工作時間工資的工資報酬:(一)安排勞動者延長工作時間的,支付不低于工資百分之一百五十的工資報酬;(二)休息日安排勞動者工作又不能安排補休的,支付不低于工資百分之二百的工資報酬;(三)法定休假日安排勞動者工作的,支付不低于工資百分之三百的工資報酬。'), -- 加班費規定
('第五十條', '工資應當以貨幣形式按月支付給勞動者本人。不得克扣或者無故拖欠勞動者的工資。'), -- 工資發放規定
('第八十二條', '用人單位自用工之日起超過一個月不滿一年未與勞動者訂立書面勞動合同的,應當向勞動者每月支付二倍的月工資。'); -- 未簽訂合同的補償規定
application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/lawmatcher?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
# 使用MySQL 8的方言
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
# 自動更新數據庫模式
spring.jpa.hibernate.ddl-auto=update
# 顯示SQL語句
spring.jpa.show-sql=true
# Hibernate Search配置
spring.jpa.properties.hibernate.search.backend.directory.type=lucene
spring.jpa.properties.hibernate.search.backend.directory.root=/tmp/lucene-indexes
法律條款實體類
package com.example.lawmatcher.model;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.GenericField;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
/**
* 法律條款實體類
*/
@Entity
@Indexed
publicclass LegalProvision {
/**
* 主鍵ID
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/**
* 條款標題
*/
@GenericField
private String title;
/**
* 條款內容
*/
@FullTextField(analyzer = "standard")
private String content;
// Getters and setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
法律條款倉庫接口
package com.example.lawmatcher.repository;
import com.example.lawmatcher.model.LegalProvision;
import org.hibernate.search.mapper.orm.Search;
import org.hibernate.search.mapper.orm.session.SearchSession;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.util.List;
/**
* 法律條款倉庫接口
*/
@Repository
publicinterface LegalProvisionRepository extends JpaRepository<LegalProvision, Long> {
/**
* 根據內容搜索法律條款
*
* @param query 搜索關鍵字
* @return 匹配的法律條款列表
*/
default List<LegalProvision> searchByContent(String query) {
EntityManager entityManager = getEntityManager();
SearchSession searchSession = Search.session(entityManager);
return searchSession.search(LegalProvision.class)
.where(f -> f.match()
.fields("title", "content")
.matching(query))
.fetchHits(20);
}
/**
* 根據多個條件進行復雜查詢
*
* @param keyword 關鍵詞
* @param field 字段名
* @return 匹配的法律條款列表
*/
default List<LegalProvision> advancedSearch(String keyword, String field) {
EntityManager entityManager = getEntityManager();
SearchSession searchSession = Search.session(entityManager);
return searchSession.search(LegalProvision.class)
.where(f -> f.match()
.field(field)
.matching(keyword))
.fetchHits(20);
}
@PersistenceContext
EntityManager getEntityManager();
}
Controller
package com.example.lawmatcher.controller;
import com.example.lawmatcher.model.LegalProvision;
import com.example.lawmatcher.repository.LegalProvisionRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
publicclass LegalProvisionController {
@Autowired
private LegalProvisionRepository legalProvisionRepository;
/**
* 根據查詢關鍵字搜索法律條款
*
* @param query 查詢關鍵字
* @return 匹配的法律條款列表
*/
@GetMapping("/search")
public List<LegalProvision> search(@RequestParam String query) {
return legalProvisionRepository.searchByContent(query);
}
/**
* 根據多個條件進行復雜查詢
*
* @param keyword 關鍵詞
* @param field 字段名
* @return 匹配的法律條款列表
*/
@GetMapping("/advanced-search")
public List<LegalProvision> advancedSearch(@RequestParam String keyword, @RequestParam String field) {
return legalProvisionRepository.advancedSearch(keyword, field);
}
}
主應用程序類
package com.example.lawmatcher;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class LawMatcherApplication {
public static void main(String[] args) {
SpringApplication.run(LawMatcherApplication.class, args);
}
}
測試
GET http://localhost:8080/advanced-search?keyword=工資&field=content
Respons:
[
{
"id": 4,
"title": "第五十條",
"content": "工資應當以貨幣形式按月支付給勞動者本人。不得克扣或者無故拖欠勞動者的工資。"
},
{
"id": 5,
"title": "第八十二條",
"content": "用人單位自用工之日起超過一個月不滿一年未與勞動者訂立書面勞動合同的,應當向勞動者每月支付二倍的月工資。"
},
{
"id": 3,
"title": "第四十四條",
"content": "有下列情形之一的,用人單位應當按照下列標準支付高于勞動者正常工作時間工資的工資報酬:(一)安排勞動者延長工作時間的,支付不低于工資百分之一百五十的工資報酬;(二)休息日安排勞動者工作又不能安排補休的,支付不低于工資百分之二百的工資報酬;(三)法定休假日安排勞動者工作的,支付不低于工資百分之三百的工資報酬。"
}
]
責任編輯:武曉燕
來源:
Java知識日歷