lucene索引庫的CRUD操作與維護
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 |
Long型 |
Y |
Y |
N |
可以使用LongPoint、IntPoint等型別儲存數值型別的資料。讓數值型別可以進行索引。但是不能儲存資料,如果想儲存資料還需要使用StoredField。 |
StoredField(FieldName, FieldValue) |
過載方法,支援多種型別 |
N |
N |
Y |
這個Field用來 不分析,不索引,但要Field儲存在文件中 |
TextField(FieldName, FieldValue, Store.NO) 或 TextField(FieldName, reader) |
字串 或 流 |
Y |
Y |
Y或N |
如果是一個Reader, lucene猜測內容比較多,會採用Unstored的策略. |
新增文件:
//新增索引
@Test
public void addDocument() throws Exception {
//索引庫存放路徑
Directory directory = FSDirectory.open(new File("D:\\temp\\index").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", "d:/temp/1.txt"));
//新增文件到索引庫
indexWriter.addDocument(document);
//關閉indexwriter
indexWriter.close();
}
刪除文件:
//刪除全部索引
@Test
public void deleteAllIndex() throws Exception {
IndexWriter indexWriter = getIndexWriter();
//刪除全部索引
indexWriter.deleteAll();
//關閉indexwriter
indexWriter.close();
}
說明:將索引目錄的索引資訊全部刪除,直接徹底刪除,無法恢復。
此方法慎用!!
指定條件刪除:
7.2.2指定查詢條件刪除
//根據查詢條件刪除索引
@Test
public void deleteIndexByQuery() throws Exception {
IndexWriter indexWriter = getIndexWriter();
//建立一個查詢條件
Query query = new TermQuery(new Term("filename", "apache"));
//根據查詢條件刪除
indexWriter.deleteDocuments(query);
//關閉indexwriter
indexWriter.close();
}
索引庫的修改:
@Test
public void updateIndex() throws Exception {
IndexWriter indexWriter = getIndexWriter();
//建立一個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();
}
索引庫查詢:
- TermQuery
TermQuery,通過項查詢,TermQuery不使用分析器所以建議匹配不分詞的Field域查詢,比如訂單號、分類ID號等。
//使用Termquery查詢
@Test
public void testTermQuery() throws Exception {
Directory directory = FSDirectory.open(new File("D:\\temp\\index").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();
}
數值範圍查詢:
@Test
public void testRangeQuery() throws Exception {
IndexSearcher indexSearcher = getIndexSearcher();
Query query = LongPoint.newRangeQuery("size", 0l, 10000l);
printResult(query, indexSearcher);
}
queryparser查詢:
通過QueryParser也可以建立Query,QueryParser提供一個Parse方法,此方法可以直接根據查詢語法來查詢。Query物件執行的查詢語法可通過System.out.println(query);查詢。
需要使用到分析器。建議建立索引時使用的分析器和查詢索引時使用的分析器要一致。
需要加入queryParser依賴的jar包。:lucene-queryparser-7.4.0.jar
@Test
public void testQueryParser() throws Exception {
IndexSearcher indexSearcher = getIndexSearcher();
//建立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();
}