使用Lucene4.7实现搜索功能,分页+高亮

不久前应公司需求写的搜索。下面记录一下,防止以后忘记。为什么使用4.7不是最新的版本?因为公司项目的JDK还是1.6的所以只能使用4.7。字典使用Jcseg。因为庖丁解牛以后很老了,所以使用Jcseg,效果还不错。本人把Lucene常用的代码封装成jar包了,在项目中直接使用jar包外加你自己的业务类就可以使用了。

接下来直接上代码。

字典类Jcseg:

public class Jcseg {
 public static Analyzer initAnalyzer(){
  Analyzer analyzer = new JcsegAnalyzer4X(JcsegTaskConfig.COMPLEX_MODE);
  JcsegAnalyzer4X jcseg=(JcsegAnalyzer4X)analyzer;
  JcsegTaskConfig config=jcseg.getTaskConfig();
  //追加同义词到分词结果中,需要在配置文件中修改jcseg.loadsyn=1
  config.setAppendCJKSyn(true);
  return analyzer;
 }
}

全站搜索实体类Golbal:

public class Golbal {
 private long id;
 private String code;
 private String name;
 private String content;
 private String secContent;
 private String url;
 private int type;//1.商品 2.采购单 3.帮助中心
 private int languageType;
 private String luceneOtherSearcher;
 private Date createDatetime;

//下面是一些get,set在此就不写出来了

}

用于搜索商品的类LuceneCommodity

public class LuceneCommodity extends Searcher<CCCommodity>{
 public LuceneCommodity(String path) {
  super(path);
 }
 @Override
 public CCCommodity filledCommodity(Document doc,String[] titles) {
  CCCommodity ccommodity=new CCCommodity();
  ccommodity.setId(Long.parseLong(doc.get("id")));
  ccommodity.setName(titles[0]!=null?titles[0]:doc.get("name"));
  ccommodity.setLuceneOrtherSearcher(titles[1]!=null?titles[1]:doc.get("luceneOrtherSearcher"));
  ccommodity.setInfo(titles[2]!=null?titles[2]:doc.get("info"));
  
  ccommodity.setSaleprice(Double.parseDouble(doc.get("saleprice")));
  ccommodity.setPurchasetimes(Integer.parseInt(doc.get("purchasetimes")));
  ccommodity.setSaleNum(Integer.parseInt(doc.get("saleNum")));
  Date d=new Date(Long.parseLong(doc.get("createDatetime")));
  ccommodity.setCreateDatetime(d);
  if(ccommodity.getCategory()==null) ccommodity.setCategory(new CCCategory());
  ccommodity.getCategory().setId(Long.parseLong(doc.get("categoryId")));
  ccommodity.setPicurl(doc.get("picurl"));
  ccommodity.setLanguageType(Integer.parseInt(doc.get("languageType")));
  ccommodity.setFalagecommodity(Integer.parseInt(doc.get("falagecommodity")));
  ccommodity.setAudit(Integer.parseInt(doc.get("audit")));
  ccommodity.setOrderunit(Integer.parseInt(doc.get("orderunit")));
  return ccommodity;
 }
 @Override
 public Document spliteDoc(CCCommodity commodity) {
  Document doc = new Document();
  if(commodity.getCategory()==null) commodity.setCategory(new CCCategory());
  doc.add(new TextField("id", commodity.getId()+"", Field.Store.YES));
  doc.add(new TextField("name", commodity.getName(), Field.Store.YES));
  doc.add(new TextField("luceneOrtherSearcher", commodity.getLuceneOrtherSearcher()==null?"":commodity.getLuceneOrtherSearcher(), Field.Store.YES));
  doc.add(new TextField("info", commodity.getInfo()==null?"":commodity.getInfo(), Field.Store.YES));
  
  doc.add(new StringField("saleprice", commodity.getSaleprice()+"",Field.Store.YES));
  doc.add(new StringField("purchasetimes", commodity.getPurchasetimes()==null?"0":commodity.getPurchasetimes()+"",Field.Store.YES));
  doc.add(new StringField("saleNum", commodity.getSaleNum()==null?"0":commodity.getSaleNum()+"",Field.Store.YES));
  doc.add(new LongField("createDatetime", commodity.getCreateDatetime().getTime(),Field.Store.YES));
  doc.add(new StringField("categoryId", commodity.getCategory().getId()+"",Field.Store.YES));
  doc.add(new StringField("picurl", commodity.getPicurl(),Field.Store.YES));
  doc.add(new StringField("languageType", commodity.getLanguageType()+"",Field.Store.YES));
  doc.add(new StringField("falagecommodity", commodity.getFalagecommodity()+"",Field.Store.YES));
  doc.add(new StringField("audit", commodity.getAudit()==null?"0":commodity.getAudit()+"",Field.Store.YES));
  doc.add(new StringField("orderunit", commodity.getOrderunit()==null?"0":commodity.getOrderunit()+"",Field.Store.YES));
  
  return doc;
 }
 @Override
 public CCCommodity doRed(String keyword, String[] fields, CCCommodity golbal) {
  // 这个方法是点击详细页面 关键字高亮
  return null;
 }
}

搜索全站的类LuceneGolbal

public class LuceneGolbal extends Searcher<Golbal>{
 public LuceneGolbal(String path) {
  super(path);
 }

 @Override
 public Golbal filledCommodity(Document doc, String[] titles) {
  Golbal golbal=new Golbal();
  golbal.setId(Integer.parseInt(doc.get("id")));
  golbal.setCode(doc.get("code"));
  golbal.setName(titles[0]!=null?titles[0]:doc.get("name"));
  golbal.setContent(titles[1]!=null?titles[1]:doc.get("content"));
  golbal.setSecContent(titles[2]!=null?titles[2]:doc.get("seccontent"));
  golbal.setLuceneOtherSearcher(titles[3]!=null?titles[3]:doc.get("luceneOtherSearcher"));
  golbal.setType(Integer.parseInt(doc.get("type")));
  golbal.setLanguageType(Integer.parseInt(doc.get("languageType")));
  golbal.setUrl(doc.get("url"));
  Date d=new Date(Long.parseLong(doc.get("createDatetime")));
  golbal.setCreateDatetime(d);
  return golbal;
 }

 @Override
 public Document spliteDoc(Golbal glbal) {
  Document doc = new Document();
  doc.add(new LongField("id", glbal.getId(), Field.Store.YES));
  doc.add(new StringField("code", glbal.getCode(), Field.Store.YES));
  doc.add(new TextField("name", glbal.getName(), Field.Store.YES));
  doc.add(new TextField("content", glbal.getContent()==null?"":glbal.getContent()+"", Field.Store.YES));
  doc.add(new TextField("seccontent", glbal.getSecContent()==null?"":glbal.getSecContent()+"", Field.Store.YES));
  doc.add(new TextField("luceneOtherSearcher", glbal.getLuceneOtherSearcher()==null?"":glbal.getLuceneOtherSearcher()+"", Field.Store.YES));
  doc.add(new StringField("type", glbal.getType()+"", Field.Store.YES));
  doc.add(new StringField("languageType", glbal.getLanguageType()+"", Field.Store.YES));
  doc.add(new StringField("url", glbal.getUrl(),Field.Store.YES));
  doc.add(new LongField("createDatetime", glbal.getCreateDatetime().getTime(),Field.Store.YES));
  return doc;
 }

 @Override
 public Golbal doRed(String keyword, String[] fields, Golbal golbal) {
  List<Golbal> result=new ArrayList<Golbal>();
  int pageSize=1;
  int curPage=1;
  BooleanQuery booleanQuery = new BooleanQuery();
  booleanQuery.add(new BooleanClause(new TermQuery(new Term("code",golbal.getCode())),Occur.MUST));
  Filter filter=new QueryWrapperFilter(booleanQuery);//过滤器
  this.queryPage(keyword, fields, pageSize, curPage, result, filter);
  if(result!=null && result.size()>0){
   Golbal temp=result.get(0);
   if(temp.getName()!=null) golbal.setName(temp.getName());
   if(temp.getContent()!=null) golbal.setContent(temp.getContent());
   if(temp.getSecContent()!=null) golbal.setSecContent(temp.getSecContent());
  }
  if(golbal.getName()==null)golbal.setName("");
  if(golbal.getContent()==null)golbal.setContent("");
  if(golbal.getSecContent()==null)golbal.setSecContent("");
  return golbal;
 }

}

管理类LuceneSearch:

public class LuceneSearch<T>{
 private Searcher searcher=null;
 public LuceneSearch(Searcher searcher){
  this.searcher=searcher;
 }
 public Searcher getSearcher() {
  return searcher;
 }
 public void index(List<T> list){
  searcher.index(list);
 }
 public int queryPage(String keyword,String[] fields,int pageSize,int curPage,List<T> result){
  return searcher.queryPage(keyword, fields, pageSize, curPage, result, null);
 }
 public int queryPage(String keyword,String[] fields,int pageSize,int curPage,List<T> result,Filter filter){
  return searcher.queryPage(keyword, fields, pageSize, curPage, result, filter);
 }
 public void addDoc(T t){
  searcher.addDoc(t);
 }
 public void updateDoc(T t,String fieldName,String fieldValue){
  searcher.updateDoc(t, fieldName, fieldValue);
 }
 public void deleteDoc(String fieldName,String fieldValue){
  searcher.deleteDoc(fieldName, fieldValue);
 }
 public void deleteDocs(){
  searcher.deleteDocs();
 }
 public void destroy(){
  searcher.destroy();
 }

public List<CCCommodity> getCCommond(){

//读取数据库把商品加载进来

}

private List<Golbal> initDate(){

//把需要建立索引的数据加载过来

}

}

接下来是action里面调用的方法

    //使用lucene查询,前提必须是已经构建了索引
    LuceneSearch searcher=new LuceneSearch(new LuceneCommodity(commodityIndexFilePath));
    searcher.getSearcher().setAnalyzer(analyzer);
    String[] fields = {"name","luceneOrtherSearcher","info"};
    Filter filter=null;
    BooleanQuery booleanQuery = new BooleanQuery();
    if(falage!=null){
     booleanQuery.add(new BooleanClause(new TermQuery(new Term("falagecommodity", falage+"")),Occur.MUST));
    }
    booleanQuery.add(new BooleanClause(new TermQuery(new Term("languageType", languageType+"")),Occur.MUST));
    //booleanQuery.add(new BooleanClause(new TermQuery(new Term("audit", "1")),Occur.MUST));
    filter=new QueryWrapperFilter(booleanQuery);//过滤器
    
    searcher.queryPage(keyword, fields, pageSize, pageIndex, pageList, filter);

然后在全局action里设置参数

private Analyzer analyzer=Jcseg.initAnalyzer();//获取解析器,写在全局。
 private ResourceBundle resourceBundle=ResourceBundle.getBundle("lucene");//把索引的位置写在配置文件里面
 private String commodityIndexFilePath=resourceBundle.getString("commodity_path"); //商品索引
 private String golbalIndexFilePath=resourceBundle.getString("golbal_path");//全局索引

 

最后需要注意的是使用Jcseg需要在WEB-INF下面放lexicon文件夹。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值