不久前应公司需求写的搜索。下面记录一下,防止以后忘记。为什么使用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文件夹。