基于Lucene的多场景检索体系开发指南

[复制链接]
发表于 2025-9-22 07:29:19 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
基于Lucene的多场景检索体系开发指南


官网

https://lucene.apache.org/
一、项目构建立置 (pom.xml)

  1. <dependencies>
  2.     <!-- Lucene核心库 -->
  3.     <dependency>
  4.         <groupId>org.apache.lucene</groupId>
  5.         <artifactId>lucene-core</artifactId>
  6.         <version>8.11.1</version>
  7.     </dependency>
  8.    
  9.     <!-- 文本解析工具 -->
  10.     <dependency>
  11.         <groupId>org.apache.poi</groupId>
  12.         <artifactId>poi-ooxml</artifactId>
  13.         <version>5.2.3</version>
  14.     </dependency>
  15.    
  16.     <!-- MySQL连接器 -->
  17.     <dependency>
  18.         <groupId>mysql</groupId>
  19.         <artifactId>mysql-connector-java</artifactId>
  20.         <version>8.0.30</version>
  21.     </dependency>
  22.    
  23.     <!-- 网络请求处理 -->
  24.     <dependency>
  25.         <groupId>org.jsoup</groupId>
  26.         <artifactId>jsoup</artifactId>
  27.         <version>1.15.3</version>
  28.     </dependency>
  29. </dependencies>
复制代码
二、根本索引构建类

  1. public abstract class BaseIndexer {
  2.     protected Directory directory;
  3.     protected Analyzer analyzer;
  4.     protected IndexWriter writer;
  5.     public BaseIndexer(String indexPath) throws IOException {
  6.         this.directory = FSDirectory.open(Paths.get(indexPath));
  7.         this.analyzer = new StandardAnalyzer();
  8.         IndexWriterConfig config = new IndexWriterConfig(analyzer);
  9.         this.writer = new IndexWriter(directory, config);
  10.     }
  11.     public abstract void buildIndex() throws Exception;
  12.     public void close() throws IOException {
  13.         writer.close();
  14.         directory.close();
  15.     }
  16. }
复制代码
三、多场景实现方案

1. Office文档检索

  1. public class DocumentIndexer extends BaseIndexer {
  2.     public DocumentIndexer(String indexPath) throws IOException {
  3.         super(indexPath);
  4.     }
  5.     @Override
  6.     public void buildIndex() throws Exception {
  7.         // 支持docx/xlsx/pptx格式
  8.         File folder = new File("docs/");
  9.         for (File file : folder.listFiles()) {
  10.             String content = parseDocument(file);
  11.             addDocument(file.getName(), content, file.getAbsolutePath());
  12.         }
  13.     }
  14.     private String parseDocument(File file) {
  15.         // 使用POI解析不同文档格式
  16.         if(file.getName().endsWith(".docx")) {
  17.             // Word解析逻辑
  18.         } else if(file.getName().endsWith(".xlsx")) {
  19.             // Excel解析逻辑
  20.         } else if(file.getName().endsWith(".pptx")) {
  21.             // PPT解析逻辑
  22.         }
  23.         return extractedText;
  24.     }
  25.     private void addDocument(String title, String content, String path) {
  26.         Document doc = new Document();
  27.         doc.add(new TextField("title", title, Field.Store.YES));
  28.         doc.add(new TextField("content", content, Field.Store.NO));
  29.         doc.add(new StringField("path", path, Field.Store.YES));
  30.         writer.addDocument(doc);
  31.     }
  32. }
复制代码
2. 数据库表检索

  1. public class DatabaseIndexer extends BaseIndexer {
  2.     private Connection connection;
  3.     public DatabaseIndexer(String indexPath, String dbUrl, String user, String password) throws Exception {
  4.         super(indexPath);
  5.         this.connection = DriverManager.getConnection(dbUrl, user, password);
  6.     }
  7.     @Override
  8.     public void buildIndex() throws Exception {
  9.         Statement stmt = connection.createStatement();
  10.         ResultSet rs = stmt.executeQuery("SELECT * FROM knowledge_base");
  11.         
  12.         while(rs.next()) {
  13.             Document doc = new Document();
  14.             doc.add(new StringField("id", rs.getString("id"), Field.Store.YES));
  15.             doc.add(new TextField("title", rs.getString("title"), Field.Store.YES));
  16.             doc.add(new TextField("content", rs.getString("content"), Field.Store.NO));
  17.             writer.addDocument(doc);
  18.         }
  19.     }
  20. }
复制代码
3. Wiki知识库检索

  1. public class WikiIndexer extends BaseIndexer {
  2.     public WikiIndexer(String indexPath) throws IOException {
  3.         super(indexPath);
  4.     }
  5.     @Override
  6.     public void buildIndex() throws Exception {
  7.         List<String> urls = fetchAllWikiUrls(); // 获取所有页面链接
  8.         
  9.         for(String url : urls) {
  10.             String content = fetchWikiContent(url);
  11.             addDocument(url, content);
  12.         }
  13.     }
  14.     private String fetchWikiContent(String url) {
  15.         // 使用Jsoup解析HTML内容
  16.         Document doc = Jsoup.connect(url).get();
  17.         return doc.select(".wiki-content").text();
  18.     }
  19. }
复制代码
四、场景差异对比表

对比维度Office文档数据库表Wiki网站数据来源当地文件体系关系型数据库Web服务器分析方式Apache POI/TikaJDBC直连查询HTTP哀求+HTML分析更新频率文件变更监听数据库触发器/定时任务定时爬取存储布局非布局化文本布局化字段映射半布局化HTML内容增量更新文件修改时间戳判断增量ID/时间戳查询页面Last-Modified头验证性能考量大文件分块处置惩罚批量提交优化爬虫速率限定五、典范搜刮实现

  1. public class Searcher {
  2.     public List<SearchResult> search(String indexPath, String queryStr) throws Exception {
  3.         DirectoryReader reader = DirectoryReader.open(FSDirectory.open(Paths.get(indexPath)));
  4.         IndexSearcher searcher = new IndexSearcher(reader);
  5.         QueryParser parser = new QueryParser("content", new StandardAnalyzer());
  6.         
  7.         TopDocs results = searcher.search(parser.parse(queryStr), 10);
  8.         List<SearchResult> matches = new ArrayList<>();
  9.         
  10.         for(ScoreDoc scoreDoc : results.scoreDocs) {
  11.             Document doc = searcher.doc(scoreDoc.doc);
  12.             matches.add(new SearchResult(
  13.                 doc.get("title"),
  14.                 doc.get("path"),
  15.                 scoreDoc.score
  16.             ));
  17.         }
  18.         
  19.         reader.close();
  20.         return matches;
  21.     }
  22. }
复制代码
六、实施留意事项


  • 分词计谋:根据中文特性发起使用IKAnalyzer替换StandardAnalyzer
  • 权限控制:Wiki爬取需处置惩罚Cookie认证和反爬机制
  • 增量索引:发起为数据库表增加last_modified字段
  • 性能优化:文档超过10MB时启用PositionalSpanQuery
  • 非常处置惩罚:添加RetryPolicy应对网络颠簸
  • 日记追踪:在document.addField()时记录原始数据ID
完备项目包罗以下模块:
  1. src/
  2. ├── main/
  3. │   ├── java/
  4. │   │   ├── indexer/      # 各类型索引构建类
  5. │   │   ├── searcher/     # 搜索服务类
  6. │   │   ├── model/        # 数据模型定义
  7. │   │   └── App.java      # 启动类
  8. │   └── resources/
  9. │       └── log4j.properties # 日志日志配置
  10. └── test/                 # 单元测试
复制代码
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表