【Lucene】索引庫的基本操作(增刪改查)

1. 增加

1.1 Field域的屬性

  • 是否分析:是否對域的內容進行分詞處理。前提是我們要對域的內容進行查詢。
  • 是否索引:將Field分析後的詞或整個Field值進行索引,只有索引方可搜索到。
    比如:商品名稱、商品簡介分析後進行索引,訂單號、身份證號不用分析但也要索引,這些將來都要作爲查詢條件。
  • 是否存儲:將Field值存儲在文檔中,存儲在文檔中的Field纔可以從Document中獲取
    比如:商品名稱、訂單號,凡是將來要從Document中獲取的Field都要存儲。

是否存儲的標準:是否要將內容展示給用戶

Field類 數據類型 Analyzed是否分析 Indexed 是否索 Stored 是否存儲 說明
StringField(FieldName, FieldValue,Store.YES)) 字符串 N Y Y或N 這個Field用來構建一個字符串Field,但是不會進行分析,會將整個串存儲在索引中,比如(訂單號,姓名等)是否存儲在文檔中用Store.YES或Store.NO決定
LongPoint(String name, long… point) Long型 Y Y N 可以使用LongPoint、IntPoint等類型存儲數值類型的數據。讓數值類型可以進行索引。但是不能存儲數據,如果想存儲數據還需要使用StoredField。
StoredField(FieldName, FieldValue) 重載方法,支持多種類型 N N Y 這個Field用來構建不同類型Field 不分析,不索引,但要Field存儲在文檔中
TextField(FieldName, FieldValue, Store.NO) 或 TextField(FieldName, reader) 字符串 或 流 Y Y Y或N 如果是一個Reader, lucene猜測內容比較多,會採用Unstored的策略.

1.2 添加文檔實現

//添加索引
@Test
public void addDocument() throws Exception {
    //索引庫存放路徑
    Directory directory = FSDirectory.open(new File("E:\\practice\\lucene\\directory").toPath());
    IndexWriterConfig config = new IndexWriterConfig(new IKAnalyzer());
    //創建一個indexwriter對象
    IndexWriter indexWriter = new IndexWriter(directory, config);
    //創建一個Document對象
    Document document = new Document();
    //向document對象中添加域。
    //不同的document可以有不同的域,同一個document可以有相同的域。
    document.add(new TextField("filename", "新添加的文檔", Field.Store.YES));
    document.add(new TextField("content", "新添加的文檔的內容", Field.Store.NO));
    //LongPoint創建索引
    document.add(new LongPoint("size", 1000l));
    //StoreField存儲數據
    document.add(new StoredField("size", 1000l));
    //不需要創建索引的就使用StoreField存儲
    document.add(new StoredField("path", "文件地址"));
    //添加文檔到索引庫
    indexWriter.addDocument(document);
    //關閉indexwriter
    indexWriter.close();

}

2. 刪除

2.1 刪除全部

//刪除全部索引
@Test
public void deleteAllIndex() throws Exception {
    //索引庫存放路徑
    Directory directory = FSDirectory.open(new File("E:\\practice\\lucene\\directory").toPath());
    IndexWriterConfig config = new IndexWriterConfig(new IKAnalyzer());
    //創建一個indexwriter對象
    IndexWriter indexWriter = new IndexWriter(directory, config);
	//刪除全部索引
	indexWriter.deleteAll();
	//關閉indexwriter
	indexWriter.close();
}

2.2 指定條件刪除

//根據查詢條件刪除索引
@Test
public void deleteIndexByQuery() throws Exception {
    //索引庫存放路徑
    Directory directory = FSDirectory.open(new File("E:\\practice\\lucene\\directory").toPath());
    IndexWriterConfig config = new IndexWriterConfig(new IKAnalyzer());
    //創建一個indexwriter對象
    IndexWriter indexWriter = new IndexWriter(directory, config);
	//創建一個查詢條件
	Query query = new TermQuery(new Term("filename", "apache"));
	//根據查詢條件刪除
	indexWriter.deleteDocuments(query);
	//關閉indexwriter
	indexWriter.close();
}

3. 修改

原理就是先刪除後添加。

//修改索引庫
@Test
public void updateIndex() throws Exception {
    //索引庫存放路徑
    Directory directory = FSDirectory.open(new File("E:\\practice\\lucene\\directory").toPath());
    IndexWriterConfig config = new IndexWriterConfig(new IKAnalyzer());
    //創建一個Document對象
    Document document = new Document();
    //向document對象中添加域。
    //不同的document可以有不同的域,同一個document可以有相同的域。
    document.add(new TextField("filename", "要更新的文檔", Field.Store.YES));
    document.add(new TextField("content", " Lucene 簡介 Lucene 是一個基於 Java 的全文信息檢索工具包," +
                                                       "它不是一個完整的搜索應用程序,而是爲你的應用程序提供索引和搜索功能。",
                Field.Store.YES));
    indexWriter.updateDocument(new Term("content", "java"), document);
    //關閉indexWriter
    indexWriter.close();
}

4. 查詢

對要搜索的信息創建Query查詢對象,Lucene會根據Query查詢對象生成最終的查詢語法,類似關係數據庫Sql語法一樣Lucene也有自己的查詢語法,比如:“name:lucene”表示查詢Field的name爲“lucene”的文檔信息。

可通過兩種方法創建查詢對象:

  1. 使用Lucene提供Query子類
  2. 使用QueryParse解析查詢表達式

4.1 使用TermQuery查詢

TermQuery,通過項查詢,TermQuery不使用分析器所以建議匹配不分詞的Field域查詢,比如訂單號、分類ID號等。

指定要查詢的域和要查詢的關鍵詞。

//使用Termquery查詢
@Test
public void testTermQuery() throws Exception {
    Directory directory = FSDirectory.open(new File("E:\\practice\\lucene\\directory").toPath());
    IndexReader indexReader = DirectoryReader.open(directory);
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    //創建查詢對象
    Query query = new TermQuery(new Term("content", "lucene"));
    //執行查詢
    TopDocs topDocs = indexSearcher.search(query, 10);
    //共查詢到的document個數
    System.out.println("查詢結果總數量:" + topDocs.totalHits);
    //遍歷查詢結果
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        Document document = indexSearcher.doc(scoreDoc.doc);
        System.out.println(document.get("filename"));
        //System.out.println(document.get("content"));
        System.out.println(document.get("path"));
        System.out.println(document.get("size"));
    }
    //關閉indexreader
    indexSearcher.getIndexReader().close();
}

4.2 數值範圍查詢

@Test
public void testRangeQuery() throws Exception {
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    Query query = LongPoint.newRangeQuery("size", 0L, 10000L);
    printResult(query, indexSearcher);
}

private void printResult(Query query, IndexSearcher indexSearcher) throws Exception {
    //執行查詢
    TopDocs topDocs = indexSearcher.search(query, 10);
    //共查詢到的document個數
    System.out.println("查詢結果總數量:" + topDocs.totalHits);
    //遍歷查詢結果
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        Document document = indexSearcher.doc(scoreDoc.doc);
        System.out.println(document.get("filename"));
        //System.out.println(document.get("content"));
        System.out.println(document.get("path"));
        System.out.println(document.get("size"));
    }
    //關閉indexreader
    indexSearcher.getIndexReader().close();
}

4.3 使用queryparser查詢

通過QueryParser也可以創建Query,QueryParser提供一個Parse方法,此方法可以直接根據查詢語法來查詢。Query對象執行的查詢語法可通過System.out.println(query);查詢。
需要使用到分析器。建議創建索引時使用的分析器和查詢索引時使用的分析器要一致。
需要加入queryParser依賴的jar包。

        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-queryparser</artifactId>
            <version>7.4.0</version>
        </dependency>
@Test
public void testQueryParser() throws Exception {
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    //創建queryparser對象
    //第一個參數默認搜索的域
    //第二個參數就是分析器對象
    QueryParser queryParser = new QueryParser("content", new IKAnalyzer());
    Query query = queryParser.parse("Lucene是java開發的");
    //執行查詢
    printResult(query, indexSearcher);
}

private void printResult(Query query, IndexSearcher indexSearcher) throws Exception {
    //執行查詢
    TopDocs topDocs = indexSearcher.search(query, 10);
    //共查詢到的document個數
    System.out.println("查詢結果總數量:" + topDocs.totalHits);
    //遍歷查詢結果
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        Document document = indexSearcher.doc(scoreDoc.doc);
        System.out.println(document.get("filename"));
        //System.out.println(document.get("content"));
        System.out.println(document.get("path"));
        System.out.println(document.get("size"));
    }
    //關閉indexreader
    indexSearcher.getIndexReader().close();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章