天天看点

Lucene6.1学习案例背景:

背景:

工作任务完成后,闲暇之计给自己充充电! Lucene是一个纯java全文检索工具包,采用倒排索引原理。 全文检索:指的是计算机索引程序通过扫描文章的每一个词,对每一个词建立一个索引,并指明该词在文章中出现的次数和位置。 索引的类型分为:1:为一索引、2:主键索引、3:聚集索引。索引就是加快检索表中数据的方法。 搜索:

    一:按被搜索的资源类型

    1、可以转为文本的

    2、多媒体类型的

    二:按照搜索方式:

    1、不处理语义,只是找出现了指定词语的所有文本。(指对词语进行匹配)

基本概念:

    1、使用流程:先建立索引,(索引库)在进行搜索。

    2、使用Lucene的数据结构,document、field。

建立索引的过程:

    1、定义一个语法分词器

    2、确定索引存储的位置

    3、创建IndexWriter,进行索引的写入

    4、内容提取,进行索引文件的写入

    5、关闭indexWriter

从索引库中搜索的过程:

    1、打开存储位置

    2、创建搜索器

    3、类似SQL进行查询

    4、处理结果

    5、关闭DirectoryReader

-----------------------------------------------------------------------------------------------------------------

文章实体类:

/**
 * @项目名称:lucene
 * @类名称:Article
 * @类描述:这是一个文章实体类
 * @创建人:YangChao
 * @创建时间:2016年8月30日 下午3:11:38
 * @version 1.0.0
 */
public class Article {
	private Integer id;
	private String title;
	private String content;
}
           

实体类和Document转换工具类:

/**
 * @项目名称:lucene
 * @类名称:DocumentUtils
 * @类描述:文章实体类和Document的转换工具
 * @创建人:YangChao
 * @创建时间:2016年8月31日 上午10:15:22
 * @version 1.0.0
 */
public class DocumentUtils {
	public static Document article2Document(Article article) {
		Document doc = new Document();
		doc.add(new Field("id", article.getId().toString(), TextField.TYPE_STORED));
		doc.add(new Field("title", article.getTitle(), TextField.TYPE_STORED));
		doc.add(new Field("content", article.getContent(), TextField.TYPE_STORED));
		return doc;
	}

	public static Article document2Ariticle(Document doc) {
		Article article = new Article();
		article.setId(Integer.parseInt(doc.get("id")));
		article.setTitle(doc.get("title"));
		article.setContent(doc.get("content"));
		return article;
	}
}
           
/**
 * @项目名称:lucene
 * @类名称:LuceneUtils
 * @类描述:获取分词器和索引位置
 * @创建人:YangChao
 * @创建时间:2016年8月31日 上午9:48:06
 * @version 1.0.0
 */
public class LuceneUtils {
	private static Logger logger = Logger.getLogger(LuceneUtils.class);
	private static Directory directory;
	private static Analyzer analyzer;
	static {
		try {
			directory = FSDirectory.open(Paths.get("./tmp/testindex"));
			// analyzer = new StandardAnalyzer();
			analyzer = new SmartChineseAnalyzer();
		} catch (Exception e) {
			logger.error("LuceneUtils error!", e);
		}
	}

	public static Directory getDirectory() {
		return directory;
	}

	public static Analyzer getAnalyzer() {
		return analyzer;
	}

	public static void closeIndexWriter(IndexWriter indexWriter) {
		if (indexWriter != null) {
			try {
				indexWriter.close();
			} catch (Exception e2) {
				logger.error("indexWriter.close error", e2);
			}
		}
	}

}
           
/**
 * @项目名称:lucene
 * @类名称:QueryResult
 * @类描述:结果集
 * @创建人:YangChao
 * @创建时间:2016年8月31日 下午4:56:24
 * @version 1.0.0
 */
public class QueryResult {
	private int count;
	private List list;

	public QueryResult() {
		super();
	}

	public QueryResult(int count, List list) {
		super();
		this.count = count;
		this.list = list;
	}
}
           
/**
 * @项目名称:lucene
 * @类名称:IndexDao
 * @类描述:
 * @创建人:YangChao
 * @创建时间:2016年8月31日 上午10:12:05
 * @version 1.0.0
 */
public class IndexDao {
	private static Logger logger = Logger.getLogger(IndexDao.class);

	public void save(Article article) {
		Document doc = DocumentUtils.article2Document(article);
		IndexWriter indexWriter = null;
		try {
			IndexWriterConfig config = new IndexWriterConfig(LuceneUtils.getAnalyzer());
			indexWriter = new IndexWriter(LuceneUtils.getDirectory(), config);
			indexWriter.addDocument(doc);
		} catch (Exception e) {
			logger.error("IndexDao.save error", e);
		} finally {
			LuceneUtils.closeIndexWriter(indexWriter);
		}
	}

	public void delete(String id) {
		IndexWriter indexWriter = null;
		try {
			Term term = new Term("id", id);
			IndexWriterConfig config = new IndexWriterConfig(LuceneUtils.getAnalyzer());
			indexWriter = new IndexWriter(LuceneUtils.getDirectory(), config);
			indexWriter.deleteDocuments(term);// 删除含有指定term的所有文档
		} catch (Exception e) {
			logger.error("IndexDao.save error", e);
		} finally {
			LuceneUtils.closeIndexWriter(indexWriter);
		}
	}

	public void update(Article article) {
		Document doc = DocumentUtils.article2Document(article);
		IndexWriter indexWriter = null;
		try {
			Term term = new Term("id", article.getId().toString());
			IndexWriterConfig config = new IndexWriterConfig(LuceneUtils.getAnalyzer());
			indexWriter = new IndexWriter(LuceneUtils.getDirectory(), config);
			indexWriter.updateDocument(term, doc);// 先删除,后创建。
		} catch (Exception e) {
			logger.error("IndexDao.save error", e);
		} finally {
			LuceneUtils.closeIndexWriter(indexWriter);
		}
	}

	public QueryResult search(String queryString, int firstResult, int maxResult) {
		List<Article> list = new ArrayList<Article>();
		try {
			DirectoryReader ireader = DirectoryReader.open(LuceneUtils.getDirectory());
			// 2、第二步,创建搜索器
			IndexSearcher isearcher = new IndexSearcher(ireader);

			// 3、第三步,类似SQL,进行关键字查询
			String[] fields = { "title", "content" };
			QueryParser parser = new MultiFieldQueryParser(fields, LuceneUtils.getAnalyzer());
			Query query = parser.parse("检索");

			TopDocs topDocs = isearcher.search(query, firstResult + maxResult);
			int count = topDocs.totalHits;// 总记录数
			System.out.println("总记录数为:" + topDocs.totalHits);// 总记录数
			ScoreDoc[] hits = topDocs.scoreDocs;// 第二个参数,指定最多返回前n条结果

			// 高亮
			Formatter formatter = new SimpleHTMLFormatter("<font color='red'>", "</font>");
			Scorer source = new QueryScorer(query);
			Highlighter highlighter = new Highlighter(formatter, source);

			// 摘要
//			Fragmenter fragmenter = new SimpleFragmenter(5);
//			highlighter.setTextFragmenter(fragmenter);

			// 处理结果
			int endIndex = Math.min(firstResult + maxResult, hits.length);
			for (int i = firstResult; i < endIndex; i++) {
				Document hitDoc = isearcher.doc(hits[i].doc);
				Article article = DocumentUtils.document2Ariticle(hitDoc);
				//
				String text = highlighter.getBestFragment(LuceneUtils.getAnalyzer(), "content", hitDoc.get("content"));
				if (text != null) {
					article.setContent(text);
				}
				list.add(article);
			}
			ireader.close();
			return new QueryResult(count, list);
		} catch (Exception e) {
			logger.error("IndexDao.search error", e);
		}
		return null;
	}
}
           

继续阅读