上一篇介绍了JAVA_WEB项目之Lucene使用中文分词器IKAnalyzer3.2.8,接下来对上一篇的代码实现排序的效果和关键字在索引库中多字段查询结果进行高亮显示。
首先是排序的效果:
Goods类,LuceneUtil类,ConfigureLucene类,测试类等的代码和上一篇的一样,只有HelloWordLucene里面的查询代码不一样。
/**
* 根据指定的条件查询,
* @param name 指定的关键字
* @return 封装了goods对象的list集合
*/
public List queryGoods(String name){
List goodsList=new ArrayList();
//创建查询对象
IndexSearcher searcher=null;
try {
searcher=LuceneUtil.getIndexSearcher();
// 指定查询的关键字到索引库查询
Query query=IKQueryParser.parse("name", name);
/**
* 根据给定的关键字查询,与索引库Term去匹配,5代表: 期望返回的结果数
* 第一次查询: indexSearcher.search 只能获取文档的索引号和匹配的数量
* 返回的结果是TopDoc类型
* totalHits: 命中数, 数组的长度,后面用来做分页
* ScoreDoc[]: 存储匹配的文档编号的数组
* Score: 文档的积分,按照命中率自动算出来
* Doc:当前文档的编号
*/
//增加排序的效果
/*对象查询的结果进行排序: Lucene排序有两种: 命中率排序, 根据字段排序
*注意 这两种排序方式不互斥的,如果选择按字段排序命中率是不会被计算出来, 但是字段排序本身可以支持多字段
*被排序的字段,和被删除更新一样 字段必须创建索引
* true代表的是降序
*/
Sort sort=new Sort(new SortField("id",SortField.INT, true),new SortField("price", SortField.DOUBLE,true));
TopDocs topDocs= searcher.search(query, null, 5, sort);
// 此变量/每页显示的记录数就是总页数
System.out.println("真正命中的结果数:" + topDocs.totalHits);
// 返回的是符合条件的文档编号,并不是文档本事
ScoreDoc scoreDocs[]= topDocs.scoreDocs;
for(int i=0;i
商品编号:13,商品名称:IBM Computer12 ,商品价格:3333.9,商品的详细信息:null
商品编号:12,商品名称:IBM Computer12 ,商品价格:2333.9,商品的详细信息:null
商品编号:11,商品名称:IBM Computer12 ,商品价格:2333.9,商品的详细信息:null
商品编号:11,商品名称:IBM是全球知名的电脑厂商,现在已经专门做服务的,已经把生产版权转给联想了,商品价格:2333.9,商品的详细信息:null
接下来实现关键字查询高亮的效果的代码:
首先我们写一个高亮的工具类HighlighterUtil:
package com.shop.demo2;
import java.io.IOException;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.highlight.Formatter;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.Scorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
public class HighlighterUtil {
private HighlighterUtil(){}
private static Formatter formatter=null;
static{
formatter=new SimpleHTMLFormatter("", "");
}
public static String setHighlighterText(Query query,String iniData,int length){
String result=null;
try {
// query对象中有查询的关键字,字段匹配关键字的内容将会高亮
Scorer scorer=new QueryScorer(query);
// 实现高亮的工具类
Highlighter highlighter=new Highlighter(formatter, scorer);
// 设置高亮后的字符长度
highlighter.setTextFragmenter(new SimpleFragmenter(length));
//给指定字段进行高亮效果
result= highlighter.getBestFragment(ConfigureLucene.getAna(), null,iniData);
if(result==null){
if(iniData.length()>length){
result=iniData.substring(0, length);
}else{
result=iniData;
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
}
package com.shop.demo2;
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;
public class DocumentUtil {
private DocumentUtil(){}
/**
* 把goods对象转为document对象
*/
public static Document goodsToDocument(Goods goods){
//把goods对象转为document
Document doc=new Document();
doc.add(new Field("id", goods.getId().toString(), Store.YES, Index.NOT_ANALYZED));
doc.add(new Field("name", goods.getName(), Store.YES, Index.ANALYZED));
doc.add(new Field("price", goods.getPrice().toString(), Store.YES, Index.NOT_ANALYZED));
doc.add(new Field("remark", goods.getRemark(), Store.YES, Index.ANALYZED));
return doc;
}
/**
* 把document对象转为goods对象
*/
public static Goods documentToGoods(Document doc){
Goods goods=new Goods();
goods.setId(Integer.parseInt(doc.get("id")));
goods.setName(doc.get("name"));
goods.setPrice(Double.parseDouble(doc.get("price")));
goods.setRemark(doc.get("remark"));
return goods;
}
}
/**
* 根据指定的条件查询,
* @param keyword 指定的关键字
* @return 封装了goods对象的list集合
*/
public List queryGoods(String keyword){
List goodsList=new ArrayList();
//创建查询对象
IndexSearcher searcher=null;
try {
searcher=LuceneUtil.getIndexSearcher();
// 指定查询的关键字到索引库查询
Query query=IKQueryParser.parseMultiField(new String[]{"name","remark"}, keyword);
/**
* 根据给定的关键字查询,与索引库Term去匹配,5代表: 期望返回的结果数
* 第一次查询: indexSearcher.search 只能获取文档的索引号和匹配的数量
* 返回的结果是TopDoc类型
* totalHits: 命中数, 数组的长度,后面用来做分页
* ScoreDoc[]: 存储匹配的文档编号的数组
* Score: 文档的积分,按照命中率自动算出来
* Doc:当前文档的编号
*/
//增加排序的效果
/*对象查询的结果进行排序: Lucene排序有两种: 命中率排序, 根据字段排序
*注意 这两种排序方式不互斥的,如果选择按字段排序命中率是不会被计算出来, 但是字段排序本身可以支持多字段
*被排序的字段,和被删除更新一样 字段必须创建索引
* true代表的是降序
*/
Sort sort=new Sort(new SortField("id",SortField.INT, true),new SortField("price", SortField.DOUBLE,true));
TopDocs topDocs= searcher.search(query, null, 5, sort);
// 此变量/每页显示的记录数就是总页数
System.out.println("真正命中的结果数:" + topDocs.totalHits);
// 返回的是符合条件的文档编号,并不是文档本事
ScoreDoc scoreDocs[]= topDocs.scoreDocs;
for(int i=0;i
@Test
public void testquery() {
List list= hellowod.queryGoods("ibm");
for(Goods good:list){
System.out.println("商品编号:"+good.getId()+",商品名称:"+good.getName()+
",商品价格:"+good.getPrice()+",商品的详细信息:"+good.getRemark()
);
}
}
商品编号:12,商品名称:IBM,商品价格:4333.9,商品的详细信息:IBM Computer
商品编号:11,商品名称:IBM,商品价格:3333.9,商品的详细信息:IBM Computer
商品编号:11,商品名称:IBM是全球知名的,商品价格:2333.9,商品的详细信息:IBM有质量保证,耐用