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

PHP 呼叫 Java Lucene 實現全文檢索:跨語言整合完整方案

     編輯:PHP 綜合知識

架構設計

PHP 不直接操作 Lucene 索引,而是透過 PHP Java Bridge 或 exec() 呼叫 Java 類別,由 Java 端封裝 Lucene API 提供 createIndex()、search() 介面。

Java 端實現

package TestLucene;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.*;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.search.*;
import org.apache.lucene.store.FSDirectory;
import java.io.*;

public class TxtFileIndexer {
    public String createIndex(String indexDir, String dataDir) throws Exception {
        File idxDir = new File(indexDir);
        File datDir = new File(dataDir);
        Analyzer analyzer = new StandardAnalyzer();
        IndexWriter writer = new IndexWriter(FSDirectory.open(idxDir.toPath()), new IndexWriterConfig(analyzer));
        long start = System.currentTimeMillis();
        String result = "";
        for (File f : datDir.listFiles()) {
            if (f.isFile() && f.getName().endsWith(".html")) {
                result += "Indexing: " + f.getCanonicalPath() + "<br/>";
                Document doc = new Document();
                doc.add(new TextField("path", f.getCanonicalPath(), Field.Store.YES));
                doc.add(new TextField("contents", new FileReader(f)));
                writer.addDocument(doc);
            }
        }
        writer.close();
        result += "耗時: " + (System.currentTimeMillis()-start) + "ms";
        return result;
    }

    public String search(String keyword, String indexDir) throws Exception {
        File idxDir = new File(indexDir);
        if (!idxDir.exists()) return "索引不存在";
        IndexSearcher searcher = new IndexSearcher(DirectoryReader.open(FSDirectory.open(idxDir.toPath())));
        Query query = new TermQuery(new Term("contents", keyword.toLowerCase()));
        TopDocs hits = searcher.search(query, 100);
        String result = "結果:<br/>";
        for (ScoreDoc sd : hits.scoreDocs) {
            Document doc = searcher.doc(sd.doc);
            result += "<a href='getfile.php?w=" + urlencode(keyword) + "&f=" + urlencode(doc.get("path")) + "'>" + doc.get("path") + "</a><br/>";
        }
        return result;
    }
}

PHP 端呼叫方式

方式一:PHP Java Bridge (推薦生產)

<?php
require_once("https://localhost:8080/JavaBridge/java/Java.inc");
$indexer = new Java("TestLucene.TxtFileIndexer");
echo $indexer->createIndex("/var/lucene/index", "/var/www/html/docs");
echo $indexer->search("關鍵字", "/var/lucene/index");

方式二:命令列執行 (簡易)

<?php
$output = shell_exec('java -cp "/path/to/lucene/*:/path/to/classes" TestLucene.TxtFileIndexer createIndex /var/lucene/index /var/www/html/docs');
echo $output;

關鍵優化建議

  • 分詞器選擇:中文需用 SmartChineseAnalyzer (Lucene 內建) 或 IKAnalyzer、Jieba 等第三方
  • 索引優化:定期 writer.forceMerge(1)、使用 IndexWriterConfig.setRAMBufferSizeMB(256)
  • 搜尋效能:IndexSearcher 線程安全可複用、開啟 MMapDirectory (大索引)
  • 即時性:SearcherManager + ControlledRealTimeReopenThread 實現 NRT (近實時搜尋)

現代替代方案:純 PHP 或專用搜尋引擎

  1. Elasticsearch / OpenSearch:分散式、RESTful、生態完善,PHP 客戶端 elasticsearch/elasticsearch
  2. Meilisearch:輕量、即時、容錯率高,適合中小專案
  3. PHP 原生:zendframework/zend-search-lucene (Lucene 3.x 移植,效能較弱)
  4. Tantivy / Sonic:Rust 寫入,極快,via FFI/HTTP

結語

跨語言呼叫 Lucene 可行但維護成本高。新專案強烈建議直接採用 Elasticsearch/Meilisearch 等專用搜尋引擎,專注業務開發而非基建整合。

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