搜索引擎之全文搜索算法功能实现(基于Lucene)
之前做去转盘网的时候,我已经公开了非全文搜索的代码,需要的朋友希望能够前去阅读我的博客。本文主要讨论如何进行全文搜索,由于本人花了很长时间设计了新作:观点,观点对全文搜索的要求还是很高的,所以我又花了不少时间研究全文搜索,你可以先体验下:点我搜索。废话也不多说了,直接上代码:
public Map<String,Object> articleSearchAlgorithms(SearchCondition condition,IndexSearcher searcher) throws ParseException, IOException{ Map<String,Object> map =new HashMap<String,Object>();
String[] filedsList=condition.getFiledsList();
String keyWord=condition.getKeyWord();
int currentPage=condition.getCurrentPage();
int pageSize=condition.getPageSize();
String sortField=condition.getSortField();
boolean isASC=condition.isDESC();
String sDate=condition.getsDate();
String eDate=condition.geteDate();
String classify=condition.getClassify(); //过滤终结字符
keyWord=escapeExprSpecialWord(keyWord); BooleanQuery q1 = new BooleanQuery();
BooleanQuery q2 = new BooleanQuery();
BooleanQuery booleanQuery = new BooleanQuery(); //boolean查询 if(classify!=null&&(classify.equals("guanzhi")||classify.equals("opinion")||classify.equals("write"))){
String typeId="1";//默认言论
if(classify.equals("guanzhi")){
typeId="2";
}
if(classify.equals("opinion")){
typeId="3";
}
Query termQuery = new TermQuery(new Term("typeId",typeId));
q1.add(termQuery,BooleanClause.Occur.MUST);
} if(sDate!=null&&eDate!=null){//是否范围查询由这两个参数决定
Query rangeQuery = new TermRangeQuery("writingTime", new BytesRef(sDate), new BytesRef(eDate),true, true);
q1.add(rangeQuery,BooleanClause.Occur.MUST);
} Sort sort = new Sort(); // 排序
sort.setSort(SortField.FIELD_SCORE);
if(sortField!=null){
sort.setSort(new SortField(sortField, SortField.Type.STRING, isASC));
} int start = (currentPage - 1) * pageSize;
int hm = start + pageSize; TopFieldCollector res = TopFieldCollector.create(sort,hm,false, false, false, false); //完全匹配查询
Term t0=new Term(filedsList[1],keyWord);
TermQuery termQuery = new TermQuery(t0);//两种高度匹配的查询
q2.add(termQuery,BooleanClause.Occur.SHOULD); //前缀匹配
Term t1=new Term(filedsList[1],keyWord);
PrefixQuery prefixQuery=new PrefixQuery(t1);
q2.add(prefixQuery,BooleanClause.Occur.SHOULD); //短语,相似度匹配,适用于分词的内容
for(int i=0;i<filedsList.length;i++){ //多字段term查询算法
if(i!=1){
PhraseQuery phraseQuery=new PhraseQuery();
Term ts0=new Term(filedsList[i],keyWord);
phraseQuery.add(ts0); FuzzyQuery fQuery=new FuzzyQuery(new Term(filedsList[i],keyWord),2);//最后相似度查询 q2.add(phraseQuery,BooleanClause.Occur.SHOULD);
q2.add(fQuery,BooleanClause.Occur.SHOULD);//后缀相似的拿出来
}
} MultiFieldQueryParser queryParser = new MultiFieldQueryParser(Version.LUCENE_47,filedsList,analyzer);
queryParser.setDefaultOperator(QueryParser.AND_OPERATOR);
Query query = queryParser.parse(keyWord); q2.add(query,BooleanClause.Occur.SHOULD); //必须加逻辑判断,否则结果是不同的
if(q1!=null && q1.toString().length()>0){
booleanQuery.add(q1,BooleanClause.Occur.MUST);
}
if(q2!=null && q2.toString().length()>0){
booleanQuery.add(q2,BooleanClause.Occur.MUST);
} searcher.search(booleanQuery, res);
long amount = res.getTotalHits();
TopDocs tds = res.topDocs(start, pageSize);
map.put("amount",amount);
map.put("tds",tds);
map.put("query",booleanQuery);
return map;
}
注意下:上面代码的搜索条件(SearchCondition )是观点网的具体需求,您可以按照您自己的搜索条件做改动,这里也很难适配所有读者。
public Map<String, Object> searchArticle(SearchCondition condition) throws Exception{ Map<String,Object> map =new HashMap<String,Object>();
List<Write> list=new ArrayList<Write>(); DirectoryReader reader=condition.getReader();
String URL=condition.getURL();
boolean isHighligth=condition.isHighlight();
String keyWord=condition.getKeyWord();
IndexSearcher searcher=getSearcher(reader,URL); try{
Map<String,Object> output=articleSearchAlgorithms(condition,searcher);
if(output==null){
map.put("amount",0L);
map.put("source",null);
return map;
} map.put("amount", output.get("amount"));
TopDocs tds = (TopDocs) output.get("tds");
ScoreDoc[] sd = tds.scoreDocs;
Query query =(Query) output.get("query"); for (int i = 0; i < sd.length; i++) { Document doc = searcher.doc(sd[i].doc); String id = doc.get("id");
/**********************start*************************需要处理的放一块儿********************/
String temp=doc.get("title");
String title =temp; //默认不高亮
if(isHighligth){
//高亮文章标题
Highlighter highlighterTitle = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));
highlighterTitle.setTextFragmenter(new SimpleFragmenter(40)); // 字长度
TokenStream ts = analyzer.tokenStream("title", new StringReader(temp));
title= highlighterTitle.getBestFragment(ts,temp);
if(title==null){
title=temp.replace(keyWord,"<span style='color:red'>"+keyWord+"</span>");//高亮处理插件bug,加这句话避免
}
} String temp1=HtmlEnDecode.htmlEncode(doc.get("content"));
String content=temp1;//使用自己封装的方法来转义 if(isHighligth){
//做高亮处理,content
Highlighter highlighterContent = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));
highlighterContent.setTextFragmenter(new SimpleFragmenter(Constant.HIGHLIGHT_CONTENT_LENGTH)); // 字长度
//temp1=StringEscapeUtils.escapeHtml(temp1);//将汉字转义导致高亮失效
TokenStream ts1 = analyzer.tokenStream("content", new StringReader(temp1));
content = highlighterContent.getBestFragment(ts1,temp1); if(content==null){
content=temp1.replace(keyWord,"<span style='color:red'>"+keyWord+"</span>");//高亮处理插件bug,加这句话避免 //假设遇上这种情况做处理,其他的高亮器会自动截图
content=subContent(content);//截取处理
content=HtmlEnDecode.htmldecode(content);//html解码
content=SubStringHTML.sub(content,Constant.HIGHLIGHT_CONTENT_LENGTH);
}
}
/*---------------------------------------不断变动的数据放一块儿----------------------------*/ Write write=writeDao.getArticle(Long.parseLong(id));
if(write!=null){
write.setTitle(title);
write.setContent(content); Date writingTime=write.getWritingTime();
String timeGap=DateUtil.dateGap(writingTime);//timeGap
write.setTimeGap(timeGap); list.add(write);
}
} }catch(Exception e){
e.printStackTrace();
}
map.put("source",list);
return map;
}
注意上面,这是具体的搜索代码,不同的应用场景有不同的需求,请您按照自己的需求封装对象,查询数据库等,代码毫无保留,绝对可用。
如果有什么疑问可以加qq群:284205104 如果群满了就麻烦去趟去转盘找下最新的群加了即可,谢谢您的阅读。
搜索引擎之全文搜索算法功能实现(基于Lucene)的更多相关文章
- 8 个基于 Lucene 的开源搜索引擎推荐
Lucene是一种功能强大且被广泛使用的搜索引擎,以下列出了8种基于Lucene的搜索引擎,你可以想象它们有多么强大. 1. Apache Solr Solr 是一个高性能,采用Java5开发,基于L ...
- Apache Solr采用Java开发、基于Lucene的全文搜索服务器
http://docs.spring.io/spring-data/solr/ 首先介绍一下solr: Apache Solr (读音: SOLer) 是一个开源.高性能.采用Java开发.基于Luc ...
- 通通WPF随笔(1)——基于lucene.NET让ComboBox拥有强大的下拉联想功能
原文:通通WPF随笔(1)--基于lucene.NET让ComboBox拥有强大的下拉联想功能 我一直很疑惑百度.谷哥搜索框的下拉联想功能是怎么实现的?是不断地查询数据库吗?其实到现在我也不知道,他们 ...
- Lucene5.5.4入门以及基于Lucene实现博客搜索功能
前言 一直以来个人博客的搜索功能很蹩脚,只是自己简单用数据库的like %keyword%来实现的,所以导致经常搜不到想要找的内容,而且高亮显示.摘要截取等也不好实现,所以决定采用Lucene改写博客 ...
- 聊聊基于Lucene的搜索引擎核心技术实践
最近公司用到了ES搜索引擎,由于ES是基于Lucene的企业搜索引擎,无意间在“聊聊架构”微信公众号里发现了这篇文章,分享给大家. 请点击链接:聊聊基于Lucene的搜索引擎核心技术实践
- C#编写了一个基于Lucene.Net的搜索引擎查询通用工具类:SearchEngineUtil
最近由于工作原因,一直忙于公司的各种项目(大部份都是基于spring cloud的微服务项目),故有一段时间没有与大家分享总结最近的技术研究成果的,其实最近我一直在不断的深入研究学习Spring.Sp ...
- Postgres全文搜索功能
当构建一个Web应用时,经常被要求加上搜索功能.其实有时候我们也不知道我要搜索个啥,反正就是要有这个功能.搜索确实很重要的特性,这也是为什么像Elasticsearch和Solr这样基于Lucene的 ...
- 为什么要用全文搜索引擎:全文搜索引擎 VS 数据库管理系统
正文一:Full Text Search Engines vs. DBMS 发表于2009年 正文二:Elasticsearch - A High-Performance Full-Text Sea ...
- WebGIS中兴趣点简单查询、基于Lucene分词查询的设计和实现
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.前言 兴趣点查询是指:输入框中输入地名.人名等查询信息后,地图上可 ...
随机推荐
- Git版本控制器的使用
首先介绍一下什么是Git:git是目前最流行的版本控制系统,属于分布式版本控制器. 使用Git前先要在GitHub创建代码仓库,或者获取你要应用的GitHub的链接地址. 创建GitHub仓库这里就不 ...
- maven的安装配置以及在IDEA中配置
一.下载maven: 1.maven官网:http://maven.apache.org/download.cgi 二.安装配置 1.下载后解压到本地目录,如图 2.配置环境变量:我的电脑右键-> ...
- MySQL安装出现的1045问题以及解决方法
MySQL安装出现1045的问题解决办法: 1045.的原因是已经装过了MySQL再次装的时候报的错误,那么该怎么处理那??? 首先卸载程序,从windows里找到mysql右击卸载,然后就是在dos ...
- python 爬取国家粮食局东北地区玉米收购价格监测信息
#!/usr/bin/python# -*- coding: UTF-8 -*-import reimport sysimport timeimport urllibimport urllib.req ...
- ListView与Adapter笔记:ZrcListView
怕自己说的不清不楚,先来一个郭神的文章镇楼:http://blog.csdn.net/guolin_blog/article/details/44996879 github:https://githu ...
- 10_Eclipse中演示Git冲突的解决
1 在user1中的readme.txt文件里先改动,而且commitand push 选中user1,右击team->Commit-à watermark/2/text/aHR0cDov ...
- recover all files with git
leon@DGLIRUAN2 /F/linux/android/leon/workspace/AngoWidget (master) $ git log commit 2f847e3a858ecb2f ...
- redmine工作流程总结
1.需求调研员和測试员新建问题,问题跟踪为支持,指派给产品经理 2.产品经理对收到的问题进行分类处理,功能类型的,改动跟踪状态为功能,指派给自己.是bug类型的,将跟踪类型改动错误类型,指派给技术经理 ...
- 使用milang出错:LookupError: unknown encoding: idna
今天同事安装了milang,结果发现例如以下出错: Traceback (most recent call last): File "F:\vmid.py", line 11, i ...
- redis的sort命令
1.简单描述 sort命令可以对list.set和sorted set的元素进行排序,然后显示排序的结果,不影响这些类型里面存储的数据的排序.就是说sort可以对list的元素排序,但是执行lrang ...