Solr权威指南:下卷.html.pdf

上传人:紫竹语嫣 文档编号:5514648 上传时间:2020-05-27 格式:PDF 页数:139 大小:6.99MB
返回 下载 相关 举报
Solr权威指南:下卷.html.pdf_第1页
第1页 / 共139页
Solr权威指南:下卷.html.pdf_第2页
第2页 / 共139页
Solr权威指南:下卷.html.pdf_第3页
第3页 / 共139页
Solr权威指南:下卷.html.pdf_第4页
第4页 / 共139页
Solr权威指南:下卷.html.pdf_第5页
第5页 / 共139页
点击查看更多>>
资源描述

《Solr权威指南:下卷.html.pdf》由会员分享,可在线阅读,更多相关《Solr权威指南:下卷.html.pdf(139页珍藏版)》请在三一文库上搜索。

1、序言 Apache Solr是使用最广泛的全文检索解决方案,大部分网站都在使用Solr来实现搜索功能。然而国内关于Solr的资料太少,无奈我只能一点点地啃Solr官方提供的User Guide PDF文档、Solr Wiki以及一些 纯英文的技术书籍,希望能够借由本书将我学习积累的所有经验倾情传授给那些由于学习Solr曲线太陡峭而束手无策的同学们。本书致力于帮助Java开发人员更简单、深入地学习Solr。同时本书还提供了随 书源码,其中包含大量可运行的示例代码。本书与随书源码搭配在一起学习会事半功倍!由于目前大数据、云计算的发展如火如荼,各种大数据生态框架如雨后春笋般涌现,给人一种无形的压力。

2、为此, 本书也介绍了Solr与大数据框架的集成,如果你正好有这方面的需求,希望本书能够给你带来帮助。 为什么写这本书 转眼间,我已经跌跌撞撞走过了5个年头,由起初的那个Java迷途小书童变身为程序员届的一根老油条,不由感慨万千。由于深谙一个非高校毕业的“正规军”一路走来有多么的艰辛,因此我一直秉持 爱开源、爱分享的个性。这么多年来帮助过的程序员太多太多,本着一颗乐于助人的心,我不想大家重走我的弯路。从2015年3月中旬开始,我在ITEye技术社区发布与Lucene和Solr相关的技术博客,深受大 家喜爱。每天联系、咨询我问题的网友越来越多。疲于应付的我,开始意识到仅靠一个人这样一对一地指导是行

3、不通的。而且刚好Solr这方面的中文技术书籍在中国还是一片空白,于是萌生了写一本Solr中 文书籍的想法,希望能够帮助更多的Solr技术爱好者。 2015年8月我联系到了华章的杨福川,向他提出了写这本书的想法,得到了他的大力支持。我深知自己过往没有显赫耀眼的工作经历,在一些前辈面前还只是一个晚辈。因此,在创作本书的过程中,查 阅了Solr官网提供的Apache-Solr-Ref-Guide、Solr Wiki,并通读了Solr in actionApache Solr 4CookbookApache Solr EssentialsApache Solr High Performance等英文技

4、术书籍。为了能够编写Solr与大 数据集成相关章节,我又耗费了大量时间通读了Apache Flume Distributed Log Collection for HadoopHadoop in ActionHBase in ActionLearning Spark等大数据相关的英文技术书籍。写作本书的过 程也成为本人学习提升的过程,为此我花费了整整1年的时间。资历尚浅仍可以通过自身努力来弥补,所以我时时刻刻以严谨缜密的态度对待写进书里的每一段文字,除了怀揣着对技术的一种敬畏之情,我 知道我还必须为读者负责。 然而造化弄人,在2016年的2月份,我的颈部莫名其妙长了一个肿瘤,这严重影响了我的身

5、心健康。由于辗转于北京协和医院、解放军总医院等地投医救治,所以这本书的编写工作不得不临时中断。还 好我没有放弃,于是在修养了半年之后,又进入了“挑灯夜战”的状态,开始以夜继日地赶稿子。因为已经立下了写书的豪言壮志,所以再苦再累我也是要写完的!由于生病,当初所在的公司要求我立即 停薪修养,在看尽了世态炎凉之后,我毅然选择了辞职,打算专职将这本书写好,给读者一个交代。没有了经济来源,只靠自己多年来的积蓄维持生活。我顶着巨大的压力,在大病初愈的情况下,决定倾 注全部精力打造这本书。很庆幸我坚持下来了。每天叫醒我的不是闹钟不是鸡汤,也不是其他竞争对手,而是我的决心,因为父母已两鬓白发,快要三十的我还孑

6、然一身。所以我不能虚度光阴,需要为了 我爱的人和爱我的人努力奋斗,从而改善他们的生活。这本书也算是给自己30岁生日提前备下的一份礼物,并借以纪念不悔的青春岁月。我知道和我有着类似经历的同学太多太多,因此希望这本书能够为 学习Solr的你们带来帮助和鼓励:定好一个Target,就永远不要放弃! 准备工作 随书提供了大量的示例代码(本书随书示例源码下载地址:https:/ 仅限于Solr,所以对于Java初学者而言会有一定压力。尽管书中提供了部分大数据框架的集群搭建步骤,但是由于篇幅的限制不可能面面俱到,你还是需要另外查阅其他相关书籍或资料来补充大数据这方面 的知识。由于随书源码是基于Maven构

7、建的,因此你还需要掌握Maven的基本使用方法。为了尽最大努力满足大部分用户的需求,所以从第14章开始我将以Solr 6.2.1版本为例进行讲解,而Solr6.x是要求JDK 1.8+版本的,那么在学习本书之前,你需要提前安装好JDK 1.7和JDK 1.8。如果你有将Solr部署在Tomcat下的需求,那么你还应安装Tomcat环境。对于企业而言,SolrCloud集群通常会部署在Linux环境下,因 此本书SolrCloud部分是以CentOS 6.5为例进行讲解的,或许你还需要掌握Linux操作系统的基础知识以及一些Linux的常用命令。另外,由于Solr是基于Lucene构建的,因此你

8、最好拥有一定的Lucene基础再来学 习本书内容会感觉更轻松。因为本书自始至终是以由浅入深的原则进行编写的,尽量细致入微地讲解每一步。当然,Solr源码是使用Java编写的,这也要求你能够熟练掌握Java编程语言的知识,并拥有良好 的编码基本功以及编程悟性。而Solr中的数据往往来自于关系型数据库,因此你最好是对关系型数据库有一定的了解。 如何阅读本书 全书分为上下两卷,总共16章,涵盖了Solr各个方面的知识点。本书从前到后按内容的难易程度以循序渐进的方式呈现出来。因此你只需要拥有足够的毅力将它阅读完,当然最好是能够边读边上机实 践,就可以掌握Solr。此外每章之间都是相互独立的,如果你对于

9、某章的内容已经非常熟悉,那么可以直接跳过选择感兴趣的章节进行学习。当然还是建议大家能够通读本书,系统学习Solr,这样才会对 Solr有一个更完整的理解,为你日后从事Solr相关的开发工作打下夯实的基础。本书每章开头部分都列举了该章的主要知识点,可以让你快速了解本章能够学习到的内容。虽然本书中演示的示例代码在随书 源码中都可以找到,但是我还是建议大家能够实际动手去敲一遍,毕竟只有亲手实践过,才能将遇到的各种问题真正悟透并彻底解决。这个过程虽是艰辛的,但也是深刻的,因为解决问题对于程序员来说 就是积累经验的机会。 面向的读者 Java开发工程师; 架构师; Solr技术爱好者; 各大高校或IT培

10、训机构的学弟学妹们。 勘误与反馈 在编写本书的过程中,尽管我倾注了大量时间与精力,但是由于水平有限,书中难免会存在不足与疏漏之处,还请大家多多批评指正。如果你在阅读本书过程中有任何疑问或者建议需要向我反馈,可 直接发送E-mail至或者添加个人微信(13476669029)联系我。 致谢 不知道你拿到这本书的时间是哪一年哪一个季节,但是对我来说,这都是我在自己30岁之前完成的一个最大的心愿。这是国内真真正正全面介绍Solr技术的第一本中文书籍,很开心我做到了。 想感谢的人很多,首先要谢谢爸妈,在我生病期间无微不至地照顾我,并无条件地支持我。 谢谢一路以来理解并鼓励我的朋友和粉丝们,是你们让我不

11、断坚持前行。 谢谢机械工业出版社华章公司的杨福川、高婧雅、李艺在这一年当中对我写作的信任与帮助,没有你们辛勤的付出,就不可能有这本书的面市。非常开心和幸运能够与你们共同完成这样一本书籍。 谢谢我的Java启蒙老师习晨龙,是您带我进入了Java世界,从此我在汲取知识的路上甘之如饴。 谢谢在这么多年的工作中所有帮助过我的同事,我会一直记得你们。 最后需要感谢的还是我自己,感谢曾经的年少轻狂,感谢一直都存在的梦想,对于梦想我从来没有也永远不会放弃。所以如果你还有梦想,为了你爱的人,为了你自己,请永远不要放弃! 第11章 Solr高级查询 通过第11章,你将可以学习到以下内容: 掌握如何使用Funct

12、ion Query以及如何自定义Function Query; 掌握如何使用Geospatial Query; 掌握如何使用Pivot Facet和Subfacet; 掌握如何使用JSON Facet API来实现复杂的数据统计查询; 掌握如何使用Solr中的其他查询组件,比如Elevation(竞价排名组件); 掌握如何使用Solr中的Result Clustering组件实现自动结果集聚类分组。 Solr作为一个强大的文本搜索平台,能够根据输入关键字查询并返回索引文档,你可能也已经了解到了Solr的一些核心功能,比如文本分词、关键字高亮、结果集分组等。尽管对于大多数搜索程序来 说,将那些与

13、用户查询最佳匹配的索引文档返回给用户是非常重要的,但是Solr还有另外一个比较常见的使用场景:聚集结果集用于数据统计分析。Solr的Pivot Facet支持叠加统计多个Facet(维度),它 能够在单个查询中对任意的聚合分类进行计算统计,这使得Solr在提供数据分析报告方面变得很有用并且还十分高效。Solr另一个核心功能就是在查询时能够对数据执行一个Function(函数)进行动态计 算,函数计算后的结果可以被用于Filter Query、文档的相关性评分、文档的排序、作为文档的“伪域”被返回。Solr还提供了强大的Geospatial(地理空间)查询功能,Geospatial查询允许你根据

14、一个点 或者一个区域进行多边形查询,或以经纬度为圆心在指定半径的圆内进行查询,实现附近的位置查询(比如查询当前用户所处位置附近的酒店或饭店)。有时候,你期望在返回的索引文档的域中引用外部 数据源,Solr提供了这个功能。Solr还支持在同一个Solr实例内跨Core在一个外键域上执行Join操作,这类似于SQL里的两个表根据外键进行多表连接查询。上述每个复杂的功能都会在本章中进行讲解。 11.1 Solr函数查询 Solr中的Function Query(函数查询)允许你为每个索引文档执行一个函数进行动态计算值。Function Query是一个比较特殊的查询,函数动态计算后得到的值可以作为一

15、个关键字添加到查询中,也 可以作为文档的评分,就像是一个普通的关键字查询同时还能生成相关性评分。通过使用Function Query,函数动态计算值可以被用于修改索引文档的相关性评分,以及查询结果集排序,而且函数动态计 算值还可以作为一个“伪域”被动态添加到每个匹配的索引文档中并返回给用户。Function Query还支持嵌套,意思就是一个Function的输出可以作为另一个Function的输入,Function支持任意深度的 嵌套。 11.1.1 Function语法 Solr中标准的Function语法是先指定一个Function名称,后面紧跟着一对小括号,小括号内可以传入零个或多个输

16、入参数,语法使用示例如下: functionName() functionName(input1) functionName(input1, input2) functionName(input1, input2, http:/ inputN) Function的输入参数可以是以下任意一种形式: 一个常量值(数字或者字符串),语法: 100, 1.45, “hello world“ 一个域名称,语法: fieldName, field(fieldName) 另外一个Function,语法: functionName(http:/ 一个变量,语法: q=!funcmin($f1,$f2) pro

17、tected final ValueSource valueSource2; protected final String delimiter; public ConcatenateFunction(ValueSource valueSource1, ValueSource valueSource2, String delimiter) if (valueSource1 = null | valueSource2 = null) throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, “One or more inputs m

18、issing for concatenate function“ ); this.valueSource1 = valueSource1; this.valueSource2 = valueSource2; if (delimiter != null) this.delimiter = delimiter; else this.delimiter = “; public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException final FunctionValues fi

19、rstValues = valueSource1.getValues( context, readerContext); final FunctionValues secondValues = valueSource2.getValues( context, readerContext); return new StrDocValues(this) Override public String strVal(int doc) return firstValues.strVal(doc) .concat(delimiter) .concat(secondValues.strVal(doc); O

20、verride public String toString(int doc) StringBuilder sb = new StringBuilder(); sb.append(“concatenate(“); sb.append(“ + firstValues.toString(doc) + “) .append(,) .append(“ + secondValues.toString(doc) + “) .append(,) .append(“ + delimiter + “); sb.append(); return sb.toString(); ; Override public b

21、oolean equals(Object o) if (this.getClass() != o.getClass() return false; ConcatenateFunction other = (ConcatenateFunction) o; return this.valueSource1.equals(other.valueSource1) Override public int hashCode() long combinedHashes; combinedHashes = (this.valueSource1.hashCode() + this.valueSource2.ha

22、shCode() + this.delimiter.hashCode(); return (int) (combinedHashes (combinedHashes 32); Override public String description() return “Concatenates two values together with an optional delimiter“; 关于ConcatenateFunction类有两个关键点:输入参数和getValues方法的返回值。Concatenate Function类的输入参数由两个ValueSource对象表示,Concatenat

23、eFunction类会将两个 ValueSource对象包含的值使用连接符c进行拼接。回顾我们之前讲解的知识,一个Function的输入参数可以是另一个函数的返回值,通过定义两个ValueSource对象而不是定义两个String字符串,你的函 数可以接收任意输入。尽管将输入参数统统采用ValueSource类型来定义带来了很大的灵活性,但ConcatenateFunction类的构造函数的第3个参数delimiter是一个String类型,它也可以定义为 ValueSource类型,它还可以是从其他域或者其他函数计算后返回的值,在我们这里,我们假设我们的delimiter参数是显式的在请求中

24、传递的。为了能够理解ConcatenateFunction类的输出,你需要查看 getValues方法,这个方法返回一个FunctionValues对象,并且getValues方法必须返回FunctionValues类型,因为我们的concatenation函数的返回值是一个字符串,我们在内部使用StrDocValues类表 包含这个返回值。StrDocValues类是FunctionValues类的一个实现类,它能够将Integer、Boolean等类型数据返回成一个String。FunctionValues类有很多子类实现,有些实现可能会使用到特定的缓 存,因此如果你需要这方面的优化,那么

25、你需要检出Solr的源码进行验证确认。StrDocValues对象内部包含了一个strVal(docid)方法,当Function被执行时,它会针对每个索引文档调用一次,正因为如 此,所以对于一些执行开销比较大的复杂查询,你需要确保strVal方法能够尽快执行。 现在你已经知道了Function是如何计算并返回计算值的,下一步就是理解请求参数是如何传入ConcatenateFunction对象的。以下代码演示了如何解析输入参数并传入我们的自定义Function: public class ConcatenateFunctionParser extends ValueSourceParser p

26、ublic ValueSource parse(FunctionQParser parser) throws SyntaxError ValueSource value1 = parser.parseValueSource(); ValueSource value2 = parser.parseValueSource(); String delimiter = null; if (parser.hasMoreArguments() delimiter = parser.parseArg(); return new ConcatenateFunction(value1, value2, deli

27、miter); 以上代码演示了如何使用FunctionQParser对象将输入参数进行解析并传入我们自定义的函数中。FunctionQParser按照标准的函数语法进行解析,比如functionName(input1,input2,),根 据请求的函数名称查找合适的ValueSourceParser实现类。可以通过调用FunctionQParser内部的parseValueSource()、parseArg()、parseFloat()等方法来获取传递给我们Function的输入参 数。在ConcatenateFunctionParser示例中,我们期望获取两个ValueSource对象(可以

28、是一个域,可以是用户输入的任意字符串或者其他函数的返回值)以及一个delimiter字符串参数,在从请求中读取 到这些输入参数之后,我们创建了一个ConcatenateFunction对象并传入输入参数到其构造函数中。 实现自定义concatenation函数需要把创建的类都完成,剩下就是在solrconfig.xml中的元素下进行注册,让Solr知道我们自定义的新函数。 上面的name属性表示注册的函数名称,函数名称怎么定义完全由我们决定。class表示我们自定义的FunctionParser实现类完整包路径。下面是我们自定义的concat函数的几个使用示例: concat(“hello“,

29、“world“, “-“) / 返回“hello-world“ concat(“hello“,“world“, “,“) / 返回“hello,world“ concat(123,456, “.“) / 返回“123.456“ concat(“no“, “delimiter“) / 返回“nodelimiter“ concat(“hello“,“world“, “field1“) / 返回“hellofield1world“ 如果想要在查询中使用我们刚刚自定义的concat函数,那么可以这样使用: http:/localhost:8080/solr/yourcore/select?q=*:*

30、params.add(“json.facet“, “这里是json字符串。“); params.set(“wt“, wt); params.set(“indent“,“true“); QueryRequest query = new QueryRequest(params); query.setResponseParser(new XXXXXXResponseParser(“json“); NamedList rsp = solrClient.request(query); String raw = (String)rsp.get(“response“); 通过上面的示例,我想你已经感觉到了S

31、ubfacet的强大,Subfacet支持对域、任意查询,任意区间进行统计,同时还支持Facet任意深度的嵌套,但是,Facet嵌套是Pivot Facet的问题所在。 Subfacet还支持对统计结果进行多种排序,比如sum(sales)desc对指定域求和然后从高到低排序,然而普通Facet仅仅支持index和count两种排序方式,而且还不支持反转排序。总而言之,Subfacet的 出现彻底打破了这种僵局。 11.5 Solr Facet Function 传统的Facet查询解决了基于某个Facet约束条件来统计查询结果集问题,Solr中扩展传统Facet的Facet Function

32、支持对Document的域进行聚合操作。将Facet Function与Subfacet功能结合,两者 可以提供强大的实时分析统计能力,具体请看后续章节的JSON Facet API部分。 11.5.1 聚合函数 Subfacet将主体信息划分为多个Facet Bucket,每个Bucket又可以嵌套多个Subfacet,最终会返回每个Bucket的详细信息。Solr提供了Aggregation Function(聚合函数)用于Subfacet的查询统 计,如表11-8所示。 表11-8 聚合函数 数值聚合函数,比如sum、avg,可以作用于数字域或者另外一个函数,也就是说聚合函数也是可以嵌套

33、使用的。不监测计算所有唯一值想要实现100%精确度的数据统计几乎是不可能的,但是通常有 很多种方法可以用来预算估计。 Facet Function中的“unique”是Solr中用来计算唯一值总数的最快实现。对于单个Solr节点,unique函数总是能够提供确切的数值,对于分布式查询模式下,当每个Solr节点上的每个数值不超过 100,那么也可以能够提供确切的数值。当任意给定分片上的唯一值数量超过100时,那么统计时会使用下列算法: 每个分片发送Top 100结果集以及每个分片的确切的unique函数计算的唯一值数量; totalSeen就是我们能够从所有分片看到的实际结果集数量; uniqu

34、eSeen就是我们能够从所有分片看到的实际唯一值的数量; notSeen就是所有分片未发送的结果集中的唯一值数量(因为每个分片我们只发送前100条结果); factor=uniqueSeen/totalSeen; 最后估算公式:estimate=uniqueSeen+(notSeen*factor)。 11.5.2 聚合函数与Subfacet结合 Facet查询统计首先会按照q参数构建的主查询和Filter Query来过滤索引文档,然后我们就可以在剩下的整个索引文档基础之上执行数据统计和分析操作。请看下面这个查询示例: http:/localhost:8080/solr/select?q=*

35、:* 创建一个SortField需要实现自己的FieldComparatorSource,因此我们自定义了RankFieldComparatorSource,而FieldComparatorSource又需要返回一个FieldComparator用来比较大小,排序的 时候会根据这个类决定域值在结果集中的排列顺序,下面是RankFieldComparatorSource和FieldComparator的部分实现代码: public class RankFieldComparatorSource extends FieldComparatorSource public FieldComparato

36、r newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException return new RankFieldComparator(numHits); public static final class RankFieldComparator extends FieldComparator implements LeafFieldComparator private final int docIDs; private int docBase; private int bo

37、ttom; private int topValue; RankFieldComparator(int numHits) docIDs = new intnumHits; public int compare(int slot1, int slot2) return getRank(docIDsslot1) - getRank(docIDsslot2); private Integer getRank(int docId) return RankUpdateListener.getRank(docId); 通过RankUpdateListener监听器监听IndexSearcher创建事件,当

38、IndexSearcher被创建时,通过JDBC连接数据库查询数据,按照自定义的计算公式计算评分,然后返回给RankFieldComparator, 这样RankFieldComparator才能根据在compare方法中根据评分去比较大小决定索引文档的顺序。最后你需要自定义RankExtractComponent查询组件,并在Request Handler中应用该查询组件,从而 使其生效。关于这部分的完整实现,请直接查阅随书源码,因为源码太长,不便一一贴出。 RankUpdateListener创建好之后,需要在solrconfig.xml中注册这个监听器,配置示例如下所示: 同时,还需要在

39、solrconfig.xml中注册我们自定义的RankExtractComponent查询组件,配置示例如下所示: none json true text rank-extract 在自定义RankExtractComponent查询组件中,我们通过RankUpdateListener监听器获取点赞数、点踩数以及最终计算得到的文档评分rank,并将它们作为3个域添加到查询结果集中的每个索引文档 中,注意:是往查询时返回的结果集中的每个索引文档追加域,我们在创建索引时并没有创建这3个域,但是创建域前提是该域在schema.xml中存在,因此还需要在schema.xml中额外追加3个域,配置示 例

40、如下所示: 此时你可以重新加载Core,然后执行如下查询示例进行测试: http:/localhost:8080/solr/weibo/select?q=*:* private static final int maxBootsIndex = boosts.length - 1; public PayloadSimilarity() Override public float scorePayload(int doc, int start, int end, BytesRef payload) int length = Utils.bytes2Int(payload.bytes); / 根据掺

41、入的Payload数据设置不同的权重值 return boostsMath.min(length, maxBootsIndex); Override public String toString() return “PayloadSimilarity“; 12.5 Solr NRT近实时查询 所谓Near Real Time(简称NRT,翻译过来就是近实时的意思)查询,就是当索引文档被索引后能几乎立即被查询到。当索引提交正在处理进行过程中,索引的更新删除操作并不会被阻塞,也不会等 待后台的索引合并工作完成之后才为索引打开一个新的IndexSearcher实例并返回。使用NRT查询,你可以将一个

42、索引提交命令更改为软提交(Soft Commit),软提交能够避免标准提交的巨大代价。有 时候可能确实想要使用标准提交来确保索引数据正确无误地写入存储介质中,但是软提交能够让你在索引提交期间就能够近乎实时地看到新添加的索引数据。但是你需要特殊注意缓存和Autowarn(自动 预热)的配置,它们会严重影响NRT查询的性能。 一个索引提交操作使得索引更新能够对新的查询请求可见,一个硬提交使用事务日志来获取最新的Document ID,同时对索引文件调用fsync方法确保索引数据写入到硬盘,并且保证即便在断电的极 端情况下也不会造成数据丢失。 索引软提交之所以比较快速,是因为它只是使得更新的索引数据

43、能够对查询请求可见,但是并没有刷新硬盘上的索引文件或者在硬盘上创建任何索引文件。如果JVM崩溃了或者服务器断电了,那么上 一次硬提交之后的所有索引更新数据将会被丢失。如果你的查询要求索引更新在之后能够快速地被查询到,此时你需要开启索引软提交。软提交可以频繁执行但是硬提交不行。软提交在耗时方面开销较 小,但是并不是毫无代价的,因为它会降低你的索引吞吐量。 硬提交(Hard Commit)它会要求所有的段文件必须立即合并为一个段文件,并重写整个索引,这个操作执行开销很大,不能执行太频繁。段文件合并应该合理配置合并策略,并定期执行索引优化, 提升查询性能。 为了达到灵活提交目的,Solr为硬提交和软

44、提交设计了自动提交策略,自动提交主要靠maxDocs和maxTime两个参数控制,maxTime参数表示每间隔多少毫秒就触发一次索引提交,maxDocs表示当 队列中累积了多少个索引文档就触发一起索引提交。你可以在solrconfig.xml中配置自动提交策略,配置示例如下所示: 15000 1000 false 其中openSearcher表示当执行一次硬提交之后是否立即打开一个新的IndexSearcher实例。同理还有配置,maxTime和maxDocs参数同样适用于软提交。 但是对于软提交配置maxTime更合理,尤其是当索引大量的索引文档时。当批量索引时,如果仅仅只是为了追求索引吞吐

45、量,并不要求索引数据能立即被查询到,那么你可以关闭软提交。通常来说,对于 硬提交一般建议是每间隔1-10分钟执行一次,对于软提交一般建议是每间隔1秒钟执行一次。通过这样配置,保证了新添加的索引文档能够秒级被查询到,同时假如突然断电了,除非硬提交没来得及写完 新更新的索引数据,否则软提交并不会丢失数据。 在Solr中除了可以通过开启软提交来实现近实时查询,还可以通过传递指令的方式实现近实时查询。我们知道,在索引文档时,XML文件中可以通过、元素来指示Solr是 添加还是删除索引文档,还可以通过添加元素来指示Solr执行一次硬提交,同理还有用于指示Solr执行一次索引优化。关于这部分内容,在2.2

46、.2章节有做介绍。索引优化其实可以 看作一种特殊的索引Commit操作,它除了需要做索引Coomit之外,还会执行索引合并,所以它的执行开销比硬提交还大。 当你在待索引的XML文件中添加元素,或者直接Http请求发送指令,或者直接通过请求参数显式指示Solr是硬提交还是软提交时,默认是执行硬提交。和 元素都支持以下3个参数: waitFlush表示会阻塞提交请求,直到索引写入硬盘之后才会返回。默认为true。不过此参与已经不建议使用了。 waitSearcher表示直到一个新的IndexSearcher实例创建并注册完成之后才返回,否则一直阻塞提交请求。 softCommit表示是否使用软提交

47、方式提交索引,通过此设置,可以开启近实时搜索,但是不能保证索引真正写入硬盘。 元素还有一个独有的expungeDeletes参数,表示清除被标记为删除的索引文档并合并段文件,默认值false。元素也有一个独有的maxSegments参数,表示段文件合并后的 段文件最大个数,默认值“1“。以下是配置示例,如下所示: 你可以通过在请求URL中添加softCommit参数并设置为true来开启索引软提交模式,从而开启Solr的近实时搜索,示例如下所示: http:/localhost:8080/solr/update?optimize=false HttpSolrClient client = ne

48、w HttpSolrClient(SOLRPEDIA_INSTANT_CORE); client.setRequestWriter(new BinaryRequestWriter(); UpdateRequest request = new UpdateRequest(); / 这个用于设置硬提交 / request.setAction(UpdateRequest.ACTION.COMMIT, true, true); / 设置在2万秒之后,自动触发一次软提交,commitWith默认是软提交, / 软提交方式默认的查询方式是获取不到最新的索引数据的 request.setCommitWithin(20000000); SolrInputDocument doc = new SolrInput

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/环境 > 建筑资料


经营许可证编号:宁ICP备18001539号-1