保持数据库与索引库的同步
说明:在一个系统中,假设索引功能存在,那么数据库和索引库应该是同一时候存在的。
这个时候须要保证索引库的数据和数据库中的数据保持一致性。
能够在对数据库进行增、删、改操作的同一时候对索引库也进行对应的操作。这样就能够保证数据库与索引库的一致性。
在对索引库进行操作时,增、删、改过程要把一个JavaBean封装成Document。而查询的过程是要把一个Document转化成JavaBean。在进行维护的工作中。要重复进行这种操作。所以我们有必要建立一个工具类来重用代码。
public 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;
}
}
什么情况下使用Index.NOT_ANALYZED当这个属性的值代表的是一个不可切割的总体。比如 ID什么情况下使用Index.ANALYZED
当这个属性的值代表的是一个可切割的总体
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();
}
}
原文:https://www.cnblogs.com/mqxnongmin/p/10522612.html