`

使用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文件夹。

分享到:
评论

相关推荐

    SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--dic

    SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--NewsWithSearch.part3 SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--NewsWithSearch.part2 SSH + Lucene + 分页 + 排序 + 高亮 ...

    SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--news.part2

    SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--NewsWithSearch.part3 SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--NewsWithSearch.part2 SSH + Lucene + 分页 + 排序 + 高亮 ...

    SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--NewsWithSearch.part1

    SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--NewsWithSearch.part3 SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--NewsWithSearch.part2 SSH + Lucene + 分页 + 排序 + 高亮 ...

    SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--NewsWithSearch.part2

    SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--NewsWithSearch.part3 SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--NewsWithSearch.part2 SSH + Lucene + 分页 + 排序 + 高亮 ...

    SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--NewsWithSearch.part3

    SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--NewsWithSearch.part3 SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--NewsWithSearch.part2 SSH + Lucene + 分页 + 排序 + 高亮 ...

    SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--news.part1

    SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--NewsWithSearch.part3 SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--NewsWithSearch.part2 SSH + Lucene + 分页 + 排序 + 高亮 ...

    SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--data

    综上所述,这个项目展示了如何利用SSH框架与Lucene搜索引擎技术,实现一个功能完备的新闻搜索系统,包括高效搜索、结果排序、分页展示以及关键词高亮等特性。这样的系统对于提升新闻网站的用户体验具有重要意义。

    Lucene4.7+IK Analyzer中文分词入门教程

    这里提供了一个简单的例子,包括一个`DataFactory`类,用于模拟存储药品信息,以及一个`LuceneIKUtil`类,用于实现Lucene索引和搜索功能。`DataFactory`包含了一个`List&lt;Medicine&gt;`,每个`Medicine`对象包含了药品ID...

    lucene4.7官方完整包

    《Lucene 4.7:官方完整包详解》 Lucene是一个开源的全文搜索引擎库,由Apache软件基金会开发并维护。作为Java平台上的一个高性能、可扩展的信息检索库,Lucene为开发者提供了强大的文本搜索功能。本文将深入探讨...

    Lucene4.7-Web 例子

    《Lucene4.7在Web应用中的实践:结合SpringMVC与MyBatis3》 在信息化时代,搜索引擎已经成为我们日常获取信息的重要工具。Apache Lucene作为一款强大的全文...希望这个实例能帮助你更好地理解和应用Lucene搜索引擎。

    ssh集成Lucene4.7demo

    总的来说,这个“ssh集成Lucene4.7demo”项目提供了一个完整的示例,展示了如何在SSH框架下整合Lucene进行全文搜索,以及如何利用IKAnalyzer处理中文分词,同时实现搜索结果的高亮显示。对于初学者或希望深入理解...

    lucene4.7 开发简单实例

    在本实例中,我们将深入探讨Lucene 4.7版本,涵盖索引的创建、修改、删除,以及查询时的排序、分页、优化和高亮显示等功能。此外,我们还将了解如何使用不同的分词器,以适应不同场景的需求。 首先,让我们从基础...

    Lucene 4.7 测试案例

    本测试案例将深入探讨Lucene 4.7的使用方法和关键功能。 首先,让我们了解Lucene的核心概念。Lucene的主要任务是索引文本数据,以便快速、高效地进行搜索。它将文档内容转化为一系列可搜索的项,这些项称为"术语"。...

    lucene4.7所需jar包

    1. **lucene-core-4.7.x.jar**:这是Lucene的核心库,包含了基本的索引和搜索功能。 2. **lucene-analyzers-common-4.7.x.jar**:提供了各种通用的分析器,包括英文和其他语言的分析器。 3. **lucene-queryparser-...

    apache Lucene4.7最全最新的jar包

    Apache Lucene 4.7是该库的一个版本,它提供了丰富的功能和改进,使得开发者能够轻松地在他们的应用中实现复杂的搜索功能。 首先,Lucene的核心功能包括分词、索引和搜索。分词是将输入的文本拆分成可搜索的单词或...

    lucene 学习实战系列(高亮+分页)

    本文将深入探讨如何在Lucene中实现高亮显示搜索结果和高效的分页功能,帮助开发者更好地理解和运用这个强大的工具。 一、Lucene简介 Lucene的核心功能是提供文本的索引和搜索,其内部实现了高效的倒排索引结构,...

    Lucene 4.7 常用jar集合

    7. **lucene-queries-4.7.0.jar**:包含各种高级查询类型的实现,如字段查询、范围查询、函数查询等,这些查询可以帮助开发者实现更复杂的搜索逻辑。 8. **paoding-analysis.jar**:这是 Paoding 分词器的 JAR 包,...

    lucene4.7相关jar包

    lucene4.7相关jar包 以及IKAnalyzer分词jar包

    lucene 4.7 jar

    这个"lucene 4.7 jar"文件是Lucene 4.7.0版本的归档包,包含了所有必要的类库,使得开发者可以直接在自己的项目中使用,而无需从头构建或理解复杂的搜索引擎实现细节。它在自然语言处理和搜索引擎领域有着广泛的应用...

Global site tag (gtag.js) - Google Analytics