一:功能背景



近期要做个高亮的搜索需求,曾经也搞过。所以没啥难度。仅仅只是原来用的是Lucene,如今要换成Solr而已,在Lucene4.x的时候,散仙在曾经的文章中也分析过怎样在搜索的时候实现高亮,主要有三种方式。详细内容,请參考散仙曾经的2篇文章:

第一:在Lucene4.3中实现高亮的方式

http://qindongliang.iteye.com/blog/1953409

第二:在Solr4.3中服务端高亮的方式

http://qindongliang.iteye.com/blog/2034270







二:方案探究



从总体来讲。主要有2种实现方式,第一就是前台展示数据时使用js高亮,第二就是服务端高亮后返回给前台



后端高亮的流程:







前端高亮的流程:









三:优劣分析



后端高亮:

性能:并发量大的情况下,可能对server的性能造成一定影响。

可靠性:高,在浏览器禁用js脚本情况下,仍能够正常显示

前端高亮:

性能:由client渲染,相对性能稍高

可靠性:低,在浏览器禁用js脚本情况下,高亮失效



四:注意事项



前台高亮时,须要把句子分词后的词组。返回给前台js,便于正则替换,关于把句子分词,能够用lucene也能够用solr,方式分别例如以下:

在Lucene中:

  1. /***
  2. *
  3. * @param analyzer 分词器
  4. * @param text  分词句子
  5. * @throws Exception
  6. */
  7. public static void analyzer(Analyzer analyzer,String text)throws Exception{
  8. TokenStream ts = analyzer.tokenStream("name",text);
  9. CharTermAttribute term=ts.addAttribute(CharTermAttribute.class);
  10. ts.reset();
  11. while(ts.incrementToken()){
  12. System.out.println(term.toString());
  13. }
  14. ts.end();
  15. ts.close();
  16. }
/***
*
* @param analyzer 分词器
* @param text 分词句子
* @throws Exception
*/
public static void analyzer(Analyzer analyzer,String text)throws Exception{
TokenStream ts = analyzer.tokenStream("name",text);
CharTermAttribute term=ts.addAttribute(CharTermAttribute.class);
ts.reset();
while(ts.incrementToken()){
System.out.println(term.toString());
}
ts.end();
ts.close();
}

在solr中,方式1:

  1. /***
  2. * 依据字段类型分词并打印分词结果
  3. * @param text
  4. */
  5. public static void showAnalysisType(String text)throws Exception{
  6. String fieldType="ik";//分词类型
  7. //调用服务
  8. FieldAnalysisRequest request = new FieldAnalysisRequest("/analysis/field");
  9. //设置类型
  10. request.addFieldType(fieldType);
  11. //设置待分词的句子
  12. request.setFieldValue(text);
  13. //sc=private static HttpSolrClient sc=new HttpSolrClient("http://localhost:8983/solr/one");
  14. //得到结果
  15. FieldAnalysisResponse response =request.process(sc);
  16. //得到相应的Analysis
  17. Analysis as = response.getFieldTypeAnalysis(fieldType);
  18. List<String> results = new ArrayList<String>();
  19. //使用guava的库,将iteratro对象转换为List对象
  20. List<AnalysisPhase> list=Lists.newArrayList(as.getIndexPhases().iterator());
  21. //取某一个fitler的分词结果,由于一个fieldtype非常有可能配置了多个filter。每一步经过
  22. //filter的结果都不一样,所以此处。要指定一个获取分词结果的filter。跟由于有关
  23. //所以散仙这里就写list.size-1了。注意此处的值,并非固定的
  24. for(TokenInfo token:list.get(list.size()-1).getTokens()){
  25. //得到分词数据结果
  26. results.add(token.getText());
  27. }
  28. }
	/***
* 依据字段类型分词并打印分词结果
* @param text
*/
public static void showAnalysisType(String text)throws Exception{ String fieldType="ik";//分词类型
//调用服务
FieldAnalysisRequest request = new FieldAnalysisRequest("/analysis/field");
//设置类型
request.addFieldType(fieldType);
//设置待分词的句子
request.setFieldValue(text);
//sc=private static HttpSolrClient sc=new HttpSolrClient("http://localhost:8983/solr/one");
//得到结果
FieldAnalysisResponse response =request.process(sc);
//得到相应的Analysis
Analysis as = response.getFieldTypeAnalysis(fieldType);
List<String> results = new ArrayList<String>();
//使用guava的库。将iteratro对象转换为List对象
List<AnalysisPhase> list=Lists.newArrayList(as.getIndexPhases().iterator());
//取某一个fitler的分词结果,由于一个fieldtype非常有可能配置了多个filter,每一步经过
//filter的结果都不一样,所以此处。要指定一个获取分词结果的filter,跟由于有关
//所以散仙这里就写list.size-1了,注意此处的值,并非固定的
for(TokenInfo token:list.get(list.size()-1).getTokens()){
//得到分词数据结果
results.add(token.getText());
} }

在solr中,方式2:

  1. /***
  2. * 依据字段名分词并打印分词结果
  3. * @param text
  4. */
  5. public static void showAnalysis(String text)throws Exception{
  6. //此处是字段名
  7. String fieldName="cpyName";
  8. //固定写法
  9. FieldAnalysisRequest request = new FieldAnalysisRequest("/analysis/field");
  10. //加入field
  11. request.addFieldName(fieldName);
  12. //设置须要分词的句子
  13. request.setFieldValue(text);
  14. //请求solr服务得到结果
  15. FieldAnalysisResponse response =request.process(sc);
  16. //封装结果,返回,可能供其兴许调用的业务处理
  17. List<String> results = new ArrayList<String>();
  18. //依据字段名获取结果
  19. Analysis as=response.getFieldNameAnalysis(fieldName);
  20. //使用guava工具包,转iterator为List
  21. List<AnalysisPhase> list=Lists.newArrayList(as.getIndexPhases().iterator());
  22. //打印分词结果
  23. for(TokenInfo token:list.get(list.size()-1).getTokens()){
  24. System.out.println(token.getText());
  25. }
  26. }
/***
* 依据字段名分词并打印分词结果
* @param text
*/
public static void showAnalysis(String text)throws Exception{
//此处是字段名
String fieldName="cpyName";
//固定写法
FieldAnalysisRequest request = new FieldAnalysisRequest("/analysis/field");
//加入field
request.addFieldName(fieldName);
//设置须要分词的句子
request.setFieldValue(text);
//请求solr服务得到结果
FieldAnalysisResponse response =request.process(sc);
//封装结果,返回。可能供其兴许调用的业务处理
List<String> results = new ArrayList<String>();
//依据字段名获取结果
Analysis as=response.getFieldNameAnalysis(fieldName);
//使用guava工具包。转iterator为List
List<AnalysisPhase> list=Lists.newArrayList(as.getIndexPhases().iterator());
//打印分词结果
for(TokenInfo token:list.get(list.size()-1).getTokens()){
System.out.println(token.getText());
} }



最后欢迎大家扫码关注微信公众号:我是攻城师(woshigcs)。我们一起学习,进步和交流!(woshigcs)

本公众号的内容是有关搜索和大数据技术和互联网等方面内容的分享。也是一个温馨的技术互动交流的小家园,有什么问题随时都能够留言,欢迎大家来訪!



在Lucene或Solr中实现高亮的策略的更多相关文章

  1. lucene、solr中的日期衰减方法-------function query --尚未测试在solr4.8

    经常有一种情景是这样的:我们索引了N年的文章,而查询时候无论直接用相关度.或者用时间排序,都是比较鲁莽的:我们想要一种既要相关度比较高,又要时间上比较新的文章. 这时候的解决办法就是,自定义日期衰减的 ...

  2. 使用 Apache Lucene 和 Solr 4 实现下一代搜索和分析

    使用 Apache Lucene 和 Solr 4 实现下一代搜索和分析 使用搜索引擎计数构建快速.高效和可扩展的数据驱动应用程序 Apache Lucene™ 和 Solr™ 是强大的开源搜索技术, ...

  3. Solr 中的 docValues=true

    前言:  在Lucene4.x之后,出现一个重大的特性,就是索引支持DocValues,这对于广大的solr和elasticsearch用户,无疑来说是一个福音,这玩意的出现通过牺牲一定的磁盘空间带来 ...

  4. 在Solr中配置和使用ansj分词

    在上一节[编译Ansj之Solr插件]中介绍如何编译ansj分词在solr(lucene)环境中使用的接口,本章将介绍如何在solr中使用ansj,其步骤主要包括:下载或者编译ansj和nlp-lan ...

  5. Solr分页与高亮(使用SolrNet实现)

    Solr分页与高亮(使用SolrNet实现) 本节我们使用Asp.net MVC实现Solr客户端查询,建议使用SolrNet这个客户端,开源地址在:https://github.com/mausch ...

  6. Solr 08 - 在Solr Web管理页面中查询索引数据 (Solr中各类查询参数的使用方法)

    目录 1 Solr管理页面的查询入口 2 Solr查询输入框简介 3 Solr管理页面的查询方案 1 Solr管理页面的查询入口 选中需要查询的SolrCore, 然后在菜单栏选择[Query]: 2 ...

  7. Solr 06 - Solr中配置使用IK分词器 (配置schema.xml)

    目录 1 配置中文分词器 1.1 准备IK中文分词器 1.2 配置schema.xml文件 1.3 重启Tomcat并测试 2 配置业务域 2.1 准备商品数据 2.2 配置商品业务域 2.3 配置s ...

  8. solr中Cache综述

    一.概述 Solr查询的核心类就是SolrIndexSearcher,每个core通常在同一时刻只由当前的SolrIndexSearcher供上层的handler使用(当切换SolrIndexSear ...

  9. 开源搜素引擎:Lucene、Solr、Elasticsearch、Sphinx优劣势比较

    https://blog.csdn.net/belalds/article/details/82667692 开源搜索引擎分类 1.Lucene系搜索引擎,java开发,包括: Lucene Solr ...

随机推荐

  1. 最短路-Bellmanford

    简介: 给定一个图和一个源点,求源点到其余点的最短路径,图中有可能存在负权边. 算法步骤 1.初始化:将除源点外的所有顶点的最短距离估计值 dist[v] ← +∞, dist[s] ←0; 2.迭代 ...

  2. 2017广西邀请赛 Query on A Tree (可持续化字典树)

    Query on A Tree 时间限制: 8 Sec  内存限制: 512 MB提交: 15  解决: 3[提交][状态][讨论版] 题目描述 Monkey A lives on a tree. H ...

  3. VMware Workstation的三种网络连接方式

    桥接模式(Bridged).NAT模式(地址转换模式).仅主机模式(Host-Only) 桥接模式就是将主机网卡与虚拟机的网卡利用虚拟网桥进行通信.在桥接的作用下,类似于把物理主机虚拟为一个交换机,所 ...

  4. Spring的远程调用

    Spring远程支持是由普通(Spring)POJO实现的,这使得开发具有远程访问功能的服务变得相当容易 四种远程调用技术: ◆ 远程方法调用(RMI) ◆ Caucho的Hessian和Burlap ...

  5. [BZOJ1563][NOI2009]诗人小G(决策单调性优化DP)

    模板题. 每个决策点都有一个作用区间,后来的决策点可能会比先前的优.于是对于每个决策点二分到它会比谁在什么时候更优,得到新的决策点集合与区间. #include<cstdio> #incl ...

  6. 【虚树】hdu6161 Big binary tree

    题意:一棵n个结点的完全二叉树,初始i号结点的权值为i.有两种操作:单点修改:询问经过某个结点的路径中,权值和最大的路径的权值和是多少. 修改的时候,暴力修改到根节点的路径上的点的f(x)即可. 跟虚 ...

  7. 【动态规划技巧题】POJ2229-Sumsets

    [题目大意] 把一个数n分成2的指数幂相加的形式,问有几种情况. [思路] 如果当前i为奇数,则必定有至少一个1,可以看作i-1的情形再加上一个1.即f[i]=f[i-1]. 如果当前i为偶数,假设没 ...

  8. Perl中的数组&哈希应用

    哈希和数组是Perl中较为常用的结构,本文则重点讨论数组和哈希的一些基本用法,供广大喜爱Perl的同学们交流学习. 哈希 Perl中的哈希表类似于Python中的字典结构,由(键=>值)对构成, ...

  9. fastjson生成json时Null属性不显示的解决方法

    举个例子 Map < String , Object > jsonMap = new HashMap< String , Object>(); jsonMap.put(&quo ...

  10. [转]OpenSessionInView模式

    OpenSessionInView模式解决的问题:   * hibernate事物边界问题   * 因session关闭导致hibernate延迟加载例外的问题 事物边界:     一个事物的完成应该 ...