Bắt đầu với Lucene: Hướng dẫn sử dụng Java API cơ bản

1. Chuẩn bị môi trường

JDK: 1.8.0_162
Môi trường phát triển: Eclipse Neon.3
Cơ sở dữ liệu: MySQL 5.7.20
Lucene: 4.10.4 (phiên bản ổn định, hỗ trợ tốt các bộ phân tích từ)

2. Chuẩn bị dữ liệu

SET FOREIGN_KEY_CHECKS=0;

-- Cấu trúc bảng sách
DROP TABLE IF EXISTS `book`;
CREATE TABLE `book` (
   `id` int(11) DEFAULT NULL,
   `bookname` varchar(500) DEFAULT NULL,
   `price` float DEFAULT NULL,
   `pic` varchar(200) DEFAULT NULL,
   `bookdesc` varchar(2000) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- Dữ liệu mẫu
INSERT INTO `book` VALUES ('1', 'java từ cơ bản đến nâng cao', '56', '1.jpg', '...');
INSERT INTO `book` VALUES ('2', 'java web phát triển', '80', '2.jpg', '...');

3. Tạo dự án

3.1 Tạo Maven Project (chọn kiểu gói là jar)

3.2 Cấu hình pom.xml

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.healchow</groupId>
  <artifactId>lucene-first</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <dependencies>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.44</version>
    </dependency>
    <dependency>
      <groupId>org.apache.lucene</groupId>
      <artifactId>lucene-core</artifactId>
      <version>4.10.4</version>
    </dependency>
  </dependencies>
</project>

4. Viết mã nền tảng

4.1 Lớp đối tượng sách

public class Sach {
    private Integer sachId;
    private String tenSach;
    private Float gia;
    private String hinhAnh;
    private String moTa;
    
    // Getter/Setter
    @Override
    public String toString() {
        return "Sach [sachId=" + sachId + ", tenSach=" + tenSach + "]";
    }
}

4.2 Giao diện truy xuất sách

public interface SachDAO {
    List<Sach> layDanhSachSach();
}

4.3 Triển khai giao diện

public class SachDAOImpl implements SachDAO {
    public List<Sach> danhSachTatCa() {
        List<Sach> sachList = new ArrayList<>();
        Connection conn = null;
        
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection(
                "jdbc:mysql://localhost:3306/lucene", "root", "123456");
            
            String sql = "SELECT * FROM sach";
            PreparedStatement stmt = conn.prepareStatement(sql);
            ResultSet rs = stmt.executeQuery();
            
            while (rs.next()) {
                Sach sach = new Sach();
                sach.setSachId(rs.getInt("id"));
                sach.setTenSach(rs.getString("bookname"));
                sachList.add(sach);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try { conn.close(); } catch (SQLException e) {}
        }
        return sachList;
    }
}

5. Quy trình tạo chỉ mục

  • Thu thập dữ liệu
  • Tạo đối tượng Document
  • Tạo bộ phân tích từ Analyzer
  • Cấu hình IndexWriterConfig
  • Xác định vị trí lưu chỉ mục
  • Viết chỉ mục bằng IndexWriter

5.1 Mã ví dụ

public class QuanLyChiMuc {
    @Test
    public void taoChiMuc() throws IOException {
        SachDAO sachDAO = new SachDAOImpl();
        List<Sach> sachList = sachDAO.danhSachTatCa();
        
        List<Document> danhSachTàiLiệu = new ArrayList<>();
        for (Sach sach : sachList) {
            Document doc = new Document();
            doc.add(new TextField("sachId", sach.getSachId()+"", Store.YES));
            doc.add(new TextField("tenSach", sach.getTenSach(), Store.YES));
            danhSachTàiLiệu.add(doc);
        }
        
        Analyzer analyzer = new StandardAnalyzer();
        IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_10_2, analyzer);
        Directory dir = FSDirectory.open(new File("C:/lucene_index"));
        IndexWriter writer = new IndexWriter(dir, config);
        
        for (Document doc : danhSachTàiLiệu) {
            writer.addDocument(doc);
        }
        writer.close();
    }
}

6. Sử dụng công cụ Luke

6.1 Hướng dẫn sử dụng

Trên Windows: chạy start.bat sau khi cấu hình JDK.
Trên macOS: chạy ./start.sh trong terminal.

7. Quy trình tìm kiếm

  • Tạo bộ phân tích từ
  • Xây dựng truy vấn
  • Đọc chỉ mục
  • Tìm kiếm bằng IndexSearcher
  • Xử lý kết quả

7.2 Mã ví dụ

public class TimKiem {
    @Test
    public void testTimKiem() throws Exception {
        Analyzer analyzer = new StandardAnalyzer();
        QueryParser parser = new QueryParser("tenSach", analyzer);
        Query query = parser.parse("lucene");
        
        Directory dir = FSDirectory.open(new File("C:/lucene_index"));
        IndexReader reader = DirectoryReader.open(dir);
        IndexSearcher searcher = new IndexSearcher(reader);
        
        TopDocs results = searcher.search(query, 10);
        System.out.println("Tổng kết quả: " + results.totalHits);
        
        for (ScoreDoc scoreDoc : results.scoreDocs) {
            Document doc = searcher.doc(scoreDoc.doc);
            System.out.println("Tên sách: " + doc.get("tenSach"));
        }
        reader.close();
    }
}

8. Phương thức IndexSearcher

Phương thứcMô tả
search(query, n)Tìm n kết quả tốt nhất
search(query, filter, n)Tìm với điều kiện lọc

Thẻ: lucene Java API Maven mysql Text indexing

Đăng vào ngày 17 tháng 6 lúc 19:28