lucene索引庫的增刪改查操作
1. 索引庫的操作
保持數據庫與索引庫的同步
說明:在一個系統中,假設索引功能存在,那麽數據庫和索引庫應該是同一時候存在的。
這個時候須要保證索引庫的數據和數據庫中的數據保持一致性。
能夠在對數據庫進行增、刪、改操作的同一時候對索引庫也進行對應的操作。這樣就能夠保證數據庫與索引庫的一致性。
工具類DocumentUtils
在對索引庫進行操作時,增、刪、改過程要把一個JavaBean封裝成Document。而查詢的過程是要把一個Document轉化成JavaBean。在進行維護的工作中。要重復進行這種操作。所以我們有必要建立一個工具類來重用代碼。
什麽情況下使用Index.NOT_ANALYZEDpublic class DocumentUtils { /** * 從Article轉化為Document * @param article * @return */ public static Document article2Document(Article article){ Document document = new Document(); Field idField = new Field("id",article.getId().toString(),Store.YES,Index.NOT_ANALYZED); Field titleField = new Field("title",article.getTitle(),Store.YES,Index.ANALYZED); Field contentField = new Field("content",article.getContent(),Store.YES,Index.ANALYZED); document.add(idField); document.add(titleField); document.add(contentField); return document; } /** * 從Document轉化為Article * @param document * @return */ public static Article document2Article(Document document){ Article article = new Article(); article.setId(Long.parseLong(document.get("id"))); article.setTitle(document.get("title")); article.setContent(document.get("content")); return article; } }
當這個屬性的值代表的是一個不可切割的總體。比如 ID什麽情況下使用Index.ANALYZED
當這個屬性的值代表的是一個可切割的總體
LuceneUtils
LuceneUtils這個類把Directory和Analyzer進行了包裝。由於在創建IndexWriter時,須要用到這兩個類,而管理索引庫的操作都要用到IndexWriter這個類,所以我們對Directory和Analyzer進行了包裝
public class LuceneUtils { public static Directory directory = null; public static Analyzer analyzer = null; static { try { directory = FSDirectory.open(new File("./indexDir")); analyzer = new StandardAnalyzer(Version.LUCENE_30); } catch (Exception e) { e.printStackTrace(); } } }
管理索引庫
public class ArticleIndex {
//添加
@Test
public void testCreateIndex() throws Exception{
Article article = new Article();
article.setId(1L);
article.setTitle("lucene能夠做搜索引擎");
article.setContent("baidu,google都是非常好的搜索引擎");
IndexWriter indexWriter = new IndexWriter(LuceneUtils.directory,LuceneUtils.analyzer,MaxFieldLength.LIMITED);
indexWriter.addDocument(DocumentUtils.article2Document(article));
indexWriter.close();
}
@Test
public void testSearchIndex() throws Exception{
IndexSearcher indexSearcher = new IndexSearcher(LuceneUtils.directory);
QueryParser queryParser = new MultiFieldQueryParser(Version.LUCENE_30, new String[]{"title","content"}, LuceneUtils.analyzer);
Query query = queryParser.parse("baidu");
TopDocs topDocs = indexSearcher.search(query, 2);
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
List<Article> articleList = new ArrayList<Article>();
for(ScoreDoc scoreDoc:scoreDocs){
Document document = indexSearcher.doc(scoreDoc.doc);
Article article = DocumentUtils.document2Article(document);
articleList.add(article);
}
for(Article article:articleList){
System.out.println(article.getId());
System.out.println(article.getTitle());
System.out.println(article.getContent());
}
}
/**
* 普通情況下索引庫的刪除用關鍵詞
* @throws Exception
*/
@Test
public void testDeleteIndex() throws Exception{
IndexWriter indexWriter = new IndexWriter(LuceneUtils.directory,LuceneUtils.analyzer,MaxFieldLength.LIMITED);
//indexWriter.deleteAll()刪除全部的索引值
/**
* term就為關鍵詞對象
* ID的索引保存類型為Index.NOT_ANALYZED,直接寫ID也能夠刪除。
* title假設為Index.NOT_ANALYZED,那麽關鍵詞就不行。要整個內容才幹夠刪除。
*/
Term term = new Term("title", "lucene");
indexWriter.deleteDocuments(term);
indexWriter.close();
}
/**
* 改動
* 先刪除後添加
* lucene的更新操作與數據庫的更新操作是不一樣的。
* 由於在更新的時候,有可能變換了keyword的位置。這樣分詞器對keyword還得又一次查找。
* 並且還得在文件夾和內容中替換。這樣做的效率比較低,所以lucene的更新操作是刪除和添加兩步驟來完畢的。
*/
@Test
public void testUpdateIndex() throws Exception{
IndexWriter indexWriter = new IndexWriter(LuceneUtils.directory,LuceneUtils.analyzer,MaxFieldLength.LIMITED);
Term term = new Term("title", "lucene");
Article article = new Article();
article.setId(1L);
article.setTitle("lucene能夠做搜索引擎");
article.setContent("改動後的內容");
/**
* term是用刪除的
* document是用於添加的
*/
indexWriter.updateDocument(term, DocumentUtils.article2Document(article));
indexWriter.close();
}
}
lucene索引庫的增刪改查操作