您的位置:首页 > 其它

Lucene系列:(7)搜索关键字高亮

2016-09-14 22:38 399 查看
在搜索结果中,将与关健字相同的字符用红色显示
TestHighlighter.java
package com.rk.lucene.d_highlighter;

import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.Formatter;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.Scorer;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.junit.Test;

import com.rk.lucene.entity.Article;
import com.rk.lucene.utils.LuceneUtils;

public class TestHighlighter {
@Test
public void testAdd() throws Exception{
Article article = new Article(1,"你好","世界你好,Hello World");
Document document = LuceneUtils.javabean2document(article);
IndexWriter indexWriter = new IndexWriter(LuceneUtils.getDirectory()	,LuceneUtils.getAnalyzer(),LuceneUtils.getMaxFieldLength());
indexWriter.addDocument(document);
indexWriter.close();
}

@Test
public void testSearch() throws Exception{
List<Article> list = new ArrayList<Article>();
String keyword = "你好";
QueryParser queryParser = new QueryParser(LuceneUtils.getVersion(), "content", LuceneUtils.getAnalyzer());
Query query = queryParser.parse(keyword);

IndexSearcher indexSearcher = new IndexSearcher(LuceneUtils.getDirectory());
TopDocs topDocs = indexSearcher.search(query, 10);

//以下代码对内容中含有关键字的字符串高亮显示

//格式对象
Formatter formatter = new SimpleHTMLFormatter("<font color='red'>", "</font>");
//关键字对象
Scorer scorer = new QueryScorer(query);
//高亮对象
Highlighter highlighter = new Highlighter(formatter, scorer);

for(int i=0;i<topDocs.scoreDocs.length;i++){
ScoreDoc scoreDoc = topDocs.scoreDocs[i];
int docIndex = scoreDoc.doc;

//关键字没有高亮
Document document = indexSearcher.doc(docIndex);

//关键字高亮
String titleHighlighter = highlighter.getBestFragment(LuceneUtils.getAnalyzer(), "title", document.get("title"));
String contentHighlighter = highlighter.getBestFragment(LuceneUtils.getAnalyzer(), "content", document.get("content"));

//将高亮后的结果再次封装到document对象中
document.getField("title").setValue(titleHighlighter);
document.getField("content").setValue(contentHighlighter);

Article article = LuceneUtils.document2javabean(document, Article.class);
list.add(article);
}

for(Article article : list){
System.out.println(article);
}
}
}


LuceneUtils.java
package com.rk.lucene.utils;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.IndexWriter.MaxFieldLength;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

import com.rk.lucene.entity.Page;

public class LuceneUtils {
private static Directory directory;
private static Version version;
private static Analyzer analyzer;
private static MaxFieldLength maxFieldLength;
private static final String LUCENE_DIRECTORY= "D:/rk/indexDB";

static{
try {
directory = FSDirectory.open(new File(LUCENE_DIRECTORY));
version = Version.LUCENE_30;
analyzer = new StandardAnalyzer(version);
maxFieldLength = MaxFieldLength.LIMITED;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}

//不让外部new当前帮助类的对象
private LuceneUtils(){}

public static <T> void pagination(Page<T> page,String field,String keyword,Class<T> clazz) throws Exception{
QueryParser queryParser = new QueryParser(getVersion(), field, getAnalyzer());
Query query = queryParser.parse(keyword);

IndexSearcher indexSearcher = new IndexSearcher(getDirectory());
TopDocs topDocs = indexSearcher.search(query, 200);
int totalHits = topDocs.totalHits;
int curPage = page.getCurPage();
int pageSize = page.getPageSize();
int quotient = totalHits / pageSize;
int remainder = totalHits % pageSize;
int totalPages = remainder==0 ? quotient : quotient+1;
int startIndex = (curPage-1) * pageSize;
int stopIndex = Math.min(startIndex + pageSize, totalHits);
List<T> list = page.getItems();
if(list == null){
list = new ArrayList<T>();
page.setItems(list);
}
list.clear();
for(int i=startIndex;i<stopIndex;i++){
ScoreDoc scoreDoc = topDocs.scoreDocs[i];
int docIndex = scoreDoc.doc;
Document document = indexSearcher.doc(docIndex);
T t = document2javabean(document, clazz);
list.add(t);
}

page.setTotalPages(totalPages);
page.setTotalItems(totalHits);
indexSearcher.close();
}

public static <T> void add(T t) throws Exception{
Document document = javabean2document(t);
IndexWriter indexWriter = new IndexWriter(getDirectory(), getAnalyzer(), getMaxFieldLength());
indexWriter.addDocument(document);
indexWriter.close();
}

public static <T> void addAll(List<T> list) throws Exception{
IndexWriter indexWriter = new IndexWriter(getDirectory(), getAnalyzer(), getMaxFieldLength());
for(T t : list){
Document doc = javabean2document(t);
indexWriter.addDocument(doc);
}
indexWriter.close();
}

public static <T> void update(String field,String value,T t) throws Exception{
Document document = javabean2document(t);
IndexWriter indexWriter = new IndexWriter(getDirectory(), getAnalyzer(), getMaxFieldLength());
indexWriter.updateDocument(new Term(field,value), document);
indexWriter.close();
}

public static <T> void delete(String field,String value) throws Exception{
IndexWriter indexWriter = new IndexWriter(getDirectory(), getAnalyzer(), getMaxFieldLength());
indexWriter.deleteDocuments(new Term(field,value));
indexWriter.close();
}

/**
* 删除所有记录
*/
public static void deleteAll() throws Exception {
IndexWriter indexWriter = new IndexWriter(getDirectory(), getAnalyzer(), getMaxFieldLength());
indexWriter.deleteAll();
indexWriter.close();
}

/**
* 根据关键字进行搜索
*/
public static <T> List<T> search(String field,String keyword,int topN,Class<T> clazz) throws Exception{
List<T> list = new ArrayList<T>();

QueryParser queryParser = new QueryParser(getVersion(), field, getAnalyzer());
Query query = queryParser.parse(keyword);

IndexSearcher indexSearcher = new IndexSearcher(getDirectory());
TopDocs topDocs = indexSearcher.search(query, topN);

for(int i=0;i<topDocs.scoreDocs.length;i++){
ScoreDoc scoreDoc = topDocs.scoreDocs[i];
int docIndex = scoreDoc.doc;
System.out.println("文档索引号" + docIndex + ",文档得分:" + scoreDoc.score);
Document document = indexSearcher.doc(docIndex);
T entity = (T) document2javabean(document, clazz);
list.add(entity);
}
indexSearcher.close();
return list;
}

/**
* 打印List
*/
public static <T> void printList(List<T> list){
if(list != null && list.size()>0){
for(T t : list){
System.out.println(t);
}
}
}

//将JavaBean转成Document对象
public static Document javabean2document(Object obj) throws Exception{
//创建Document对象
Document document = new Document();
//获取obj引用的对象字节码
Class clazz = obj.getClass();
//通过对象字节码获取私有的属性
java.lang.reflect.Field[] reflectFields = clazz.getDeclaredFields();
//迭代
for(java.lang.reflect.Field reflectField : reflectFields){
//反射
reflectField.setAccessible(true);
//获取字段名
String name = reflectField.getName();
//获取字段值
String value = reflectField.get(obj).toString();
//加入到Document对象中去,这时javabean的属性与document对象的属性相同
document.add(new Field(name, value, Store.YES, Index.ANALYZED));
}
//返回document对象
return document;
}

//将Document对象转换成JavaBean对象
public static <T> T document2javabean(Document document,Class<T> clazz) throws Exception{
T obj = clazz.newInstance();
java.lang.reflect.Field[] reflectFields = clazz.getDeclaredFields();
for(java.lang.reflect.Field reflectField : reflectFields){
reflectField.setAccessible(true);
String name = reflectField.getName();
String value = document.get(name);
BeanUtils.setProperty(obj, name, value);
}
return obj;
}

public static Directory getDirectory() {
return directory;
}

public static void setDirectory(Directory directory) {
LuceneUtils.directory = directory;
}

public static Version getVersion() {
return version;
}

public static void setVersion(Version version) {
LuceneUtils.version = version;
}

public static Analyzer getAnalyzer() {
return analyzer;
}

public static void setAnalyzer(Analyzer analyzer) {
LuceneUtils.analyzer = analyzer;
}

public static MaxFieldLength getMaxFieldLength() {
return maxFieldLength;
}

public static void setMaxFieldLength(MaxFieldLength maxFieldLength) {
LuceneUtils.maxFieldLength = maxFieldLength;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  lucene