- 浏览: 2183950 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (682)
- 软件思想 (7)
- Lucene(修真篇) (17)
- Lucene(仙界篇) (20)
- Lucene(神界篇) (11)
- Solr (48)
- Hadoop (77)
- Spark (38)
- Hbase (26)
- Hive (19)
- Pig (25)
- ELK (64)
- Zookeeper (12)
- JAVA (119)
- Linux (59)
- 多线程 (8)
- Nutch (5)
- JAVA EE (21)
- Oracle (7)
- Python (32)
- Xml (5)
- Gson (1)
- Cygwin (1)
- JavaScript (4)
- MySQL (9)
- Lucene/Solr(转) (5)
- 缓存 (2)
- Github/Git (1)
- 开源爬虫 (1)
- Hadoop运维 (7)
- shell命令 (9)
- 生活感悟 (42)
- shell编程 (23)
- Scala (11)
- MongoDB (3)
- docker (2)
- Nodejs (3)
- Neo4j (5)
- storm (3)
- opencv (1)
最新评论
-
qindongliang1922:
粟谷_sugu 写道不太理解“分词字段存储docvalue是没 ...
浅谈Lucene中的DocValues -
粟谷_sugu:
不太理解“分词字段存储docvalue是没有意义的”,这句话, ...
浅谈Lucene中的DocValues -
yin_bp:
高性能elasticsearch ORM开发库使用文档http ...
为什么说Elasticsearch搜索是近实时的? -
hackWang:
请问博主,有用solr做电商的搜索项目?
Solr中Group和Facet的用法 -
章司nana:
遇到的问题同楼上 为什么会返回null
Lucene4.3开发之第八步之渡劫初期(八)
转载请务必注明,原创地址,谢谢配合!
http://qindongliang1922.iteye.com/blog/2008672
接着上篇,散仙介绍的Lucene的几种评分方式,大部分的时候都能满足我们的大多数业务场景,但有些场合下可能我们使用另外一种评分策略,会更加灵活一点,上次介绍的评分主要是围绕着DefaultSimilarity这个类来介绍的,其实这个类控制评分的方式更加倾向于底层控制,而散仙下文要介绍的CustomScoreQuery这个类,则更加倾向于应用层面的控制。
为什么,有时候我们需要借助这个类来完成评分呢?
可能有时候我们会遇到如下类似的需求:
在一份论坛的索引里面有帖子的标题和帖子发布的日期(为了简化程序,假设按年来记录的),这个时候有如下需求,要求我们检索标题时,不仅要检索出与关键词最相关的帖子,而且还得是年份距现在相距不远的帖子,进行提拔加权,综上所述,这里面有2个关键因素,第一内容相关,
第二,近期时间的日期拥有的更高的加权。可以看出那么这个文档的评分是要结合这两个因素来完成最后的总的评分。
到这里可能有些人就会有疑问,为什么不对检索完的内容,按时间排序降序排序呢,这里可能会出现一个问题,如果是硬性的按时间降序排序,可能会破坏评分机制,因为默认的排序是按照评分降序排的,如果按照时间排序可能就会破坏原有的顺序,所以这个时候就需要我们统一下方式,要么用评分的方式来解决问题,那么用排序的问题来解决,显然统一评分的方式会更加适合这个场景。
测试的数据如下:
没采用自定义评分的时候检索结果:
我们可以采取两种方式,来完成这个方式,下面看第一种方式:基于CustomScoreProvider的方式, 我们统一对2010年的帖子加权为2,默认是与原来的评分是相乘的关系,代码如下:
然后我们继承CustomScoreQuery,引用上文,我们定义的评分提供者,代码如下:
最后,在检索的时候,使用我们自定义的的评分query,代码如下:
此时的检索结果和我们预期的一样:
下面散仙,介绍第二种方式基于FunctionQuery的方式,这种方式需要我们自己重写ValueSource,来完成,代码如下:
然后,在检索时,就可以构造我们自己的自定义评分了,
核心代码如下:
基于上次同样的检索条件,打印输出结果如下:
除了,得分方式的不一样,我们发现对结果的排序都是一样的,由此,我们可以灵活选择我们所需要的方式,来完成我们的业务。
转载请务必注明,原创地址,谢谢配合!
http://qindongliang1922.iteye.com/blog/2008672
http://qindongliang1922.iteye.com/blog/2008672
接着上篇,散仙介绍的Lucene的几种评分方式,大部分的时候都能满足我们的大多数业务场景,但有些场合下可能我们使用另外一种评分策略,会更加灵活一点,上次介绍的评分主要是围绕着DefaultSimilarity这个类来介绍的,其实这个类控制评分的方式更加倾向于底层控制,而散仙下文要介绍的CustomScoreQuery这个类,则更加倾向于应用层面的控制。
为什么,有时候我们需要借助这个类来完成评分呢?
可能有时候我们会遇到如下类似的需求:
在一份论坛的索引里面有帖子的标题和帖子发布的日期(为了简化程序,假设按年来记录的),这个时候有如下需求,要求我们检索标题时,不仅要检索出与关键词最相关的帖子,而且还得是年份距现在相距不远的帖子,进行提拔加权,综上所述,这里面有2个关键因素,第一内容相关,
第二,近期时间的日期拥有的更高的加权。可以看出那么这个文档的评分是要结合这两个因素来完成最后的总的评分。
到这里可能有些人就会有疑问,为什么不对检索完的内容,按时间排序降序排序呢,这里可能会出现一个问题,如果是硬性的按时间降序排序,可能会破坏评分机制,因为默认的排序是按照评分降序排的,如果按照时间排序可能就会破坏原有的顺序,所以这个时候就需要我们统一下方式,要么用评分的方式来解决问题,那么用排序的问题来解决,显然统一评分的方式会更加适合这个场景。
测试的数据如下:
Document doc=new Document(); doc.add(new StringField("id", "1", Store.YES)); doc.add(new TextField("name", "中国是一个多民族国家", Store.YES)); doc.add(new IntField("date", 2012, Store.NO)); writer.addDocument(doc); doc=new Document(); doc.add(new StringField("id", "2", Store.YES)); doc.add(new TextField("name", "伟大的人啊", Store.YES)); doc.add(new IntField("date", 2013, Store.NO)); writer.addDocument(doc); doc=new Document(); doc.add(new StringField("id", "3", Store.YES)); doc.add(new TextField("name", "伟大的祖国", Store.YES)); doc.add(new IntField("date", 2010, Store.NO)); writer.addDocument(doc);
没采用自定义评分的时候检索结果:
2 伟大的人啊 0.5 3 伟大的祖国 0.5
我们可以采取两种方式,来完成这个方式,下面看第一种方式:基于CustomScoreProvider的方式, 我们统一对2010年的帖子加权为2,默认是与原来的评分是相乘的关系,代码如下:
package com.qin.lucene20140123; import java.io.IOException; import org.apache.lucene.index.AtomicReaderContext; import org.apache.lucene.queries.CustomScoreProvider; import org.apache.lucene.search.FieldCache; import org.apache.lucene.search.FieldCache.Ints; import org.apache.lucene.search.similarities.DefaultSimilarity; /** * @author 秦东亮 * Lucene技术交流群:324714439 * 实现评分提供的方式 * **/ public class MyScoreProvider extends CustomScoreProvider { AtomicReaderContext reader=null; public MyScoreProvider(AtomicReaderContext context) { super(context); reader=context; // TODO Auto-generated constructor stub } @Override public float customScore(int doc, float subQueryScore, float valSrcScore) throws IOException { //FieldCache.DEFAULT.getTerms(reader.reader(), "date"); //从域缓存里面加载索引字段的信息 Ints ints=FieldCache.DEFAULT.getInts(reader.reader(), "date", false); int date=ints.get(doc); float ss=1;//判断加权 if(date==2010){ ss=2; } /* * 通过得分相乘放大分数 * 此处可以控制与原有得分结合的方式,加减乘除都可以 * **/ return subQueryScore*valSrcScore*ss; } }
然后我们继承CustomScoreQuery,引用上文,我们定义的评分提供者,代码如下:
package com.qin.lucene20140123; import java.io.IOException; import org.apache.lucene.index.AtomicReaderContext; import org.apache.lucene.queries.CustomScoreProvider; import org.apache.lucene.queries.CustomScoreQuery; import org.apache.lucene.search.Query; /** * 重写CustomScoreQuery * 的CustomScoreProvider方法 * 引用我们自己的Provider * * **/ public class MyQuery extends CustomScoreQuery { public MyQuery(Query subQuery) { super(subQuery); // TODO Auto-generated constructor stub } @Override protected CustomScoreProvider getCustomScoreProvider( AtomicReaderContext context) throws IOException { /** * 自定义的评分provider * * **/ return new MyScoreProvider(context); } }
最后,在检索的时候,使用我们自定义的的评分query,代码如下:
QueryParser p=new QueryParser(Version.LUCENE_44, "name", new IKAnalyzer(true)); Query query=p.parse(temp); MyQuery myq=new MyQuery(query); TopDocs top=searcher.search(myq, 10);
此时的检索结果和我们预期的一样:
3 伟大的祖国 1.0 2 伟大的人啊 0.5
下面散仙,介绍第二种方式基于FunctionQuery的方式,这种方式需要我们自己重写ValueSource,来完成,代码如下:
package com.qin.lucene20140123; import java.io.IOException; import java.util.Map; import org.apache.lucene.index.AtomicReaderContext; import org.apache.lucene.queries.function.FunctionValues; import org.apache.lucene.queries.function.ValueSource; import org.apache.lucene.queries.function.docvalues.FloatDocValues; import org.apache.lucene.search.FieldCache; import org.apache.lucene.search.FieldCache.Ints; /** * * @author 秦东亮 * * 重写ValueSource * 返回外部的加权方式 * * * **/ public class ScoreFunction extends ValueSource { @Override public FunctionValues getValues(Map arg0, final AtomicReaderContext arg1) throws IOException { return new FloatDocValues(this) { @Override public float floatVal(int doc) { float s=1; try { /** * 从域缓存里面 * 读取所需数据 * * */ Ints ints=FieldCache.DEFAULT.getInts(arg1.reader(),"date", false); int a=ints.get(doc); /** * 对2010加权 * * */ if(a==2010){ s=2; } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return s; } }; } @Override public int hashCode() { // TODO Auto-generated method stub return 0; } @Override public String description() { // TODO Auto-generated method stub return null; } @Override public boolean equals(Object arg0) { // TODO Auto-generated method stub return false; } }
然后,在检索时,就可以构造我们自己的自定义评分了,
核心代码如下:
QueryParser p=new QueryParser(Version.LUCENE_44, "name", new IKAnalyzer(true)); Query query=p.parse(temp); /* * * 引用自己的 * 评分query * **/ CustomScoreQuery csq=new CustomScoreQuery(query,new FunctionQuery(new ScoreFunction())); TopDocs top=searcher.search(csq, 10);
基于上次同样的检索条件,打印输出结果如下:
3 伟大的祖国 0.49999997 2 伟大的人啊 0.24999999
除了,得分方式的不一样,我们发现对结果的排序都是一样的,由此,我们可以灵活选择我们所需要的方式,来完成我们的业务。
转载请务必注明,原创地址,谢谢配合!
http://qindongliang1922.iteye.com/blog/2008672
发表评论
-
如何使用Spark大规模并行构建索引
2016-02-01 12:54 2715使用Spark构建索引非常简单,因为spark提供了更高级的 ... -
Lucene4.3进阶开发之纯阳无极(十九)
2014-12-09 16:37 2731原创不易,转载请务必注明,原创地址,谢谢配合! http:/ ... -
Lucene4.3进阶开发之神游北冥(十八)
2014-03-13 18:21 2418原创不易,转载请务必 ... -
Lucene4.3进阶开发之潇湘夜雨(十七)
2014-02-13 23:14 2805转载请务必注明,原创 ... -
Lucene4.3进阶开发之高山流水(十六)
2014-02-12 22:22 3642转载请务必注明,原创地址,谢谢配合! http://qind ... -
Lucene4.3进阶开发之溪山行旅(十五)
2014-02-11 00:24 3623转载请务必注明,原创地址,谢谢配合! http://qind ... -
Lucene4.3进阶开发之礼敬如来(十三)
2014-01-23 00:40 3902转载请务必注明,原创地址,谢谢配合! http://qind ... -
Lucene4.3进阶开发之千象奔鸣(十二)
2014-01-18 23:30 3232转载请务必注明,原创地址,谢谢配合! http://qind ... -
Lucene4.3进阶开发之气定六合(十一)
2014-01-18 22:13 1626转载请务必注明,原创地址,谢谢配合! http://qind ... -
Lucene4.3进阶开发之见龙在田(十)
2014-01-18 00:11 1592转载请务必注明,原创 ... -
Lucene4.3进阶开发之亢龙有悔( 九)
2014-01-17 00:00 1542转载请务必注明,原创 ... -
Lucene4.3进阶开发之李代桃僵( 八)
2014-01-15 18:54 1600转载请务必注明,原创地址,谢谢配合! http://qind ... -
Lucene4.3进阶开发之潜龙勿用( 七)
2014-01-14 20:38 1682转载请务必注明,原创地址,谢谢配合! http://qind ... -
Lucene4.3进阶开发之柳暗花明( 六)
2014-01-05 15:33 3903转载请务必注明,原创地址,谢谢配合! http://qind ... -
Lucene4.3进阶开发之二渡天劫( 五)
2014-01-03 01:58 3265转载请务必注明,原创 ... -
Lucene4.3进阶开发之漫漫修行( 四)
2013-12-31 01:50 3020转载请务必注明,原创地址,谢谢配合! http://qind ... -
Lucene4.3进阶开发之入乡随俗(三)
2013-12-25 15:20 4604转载请务必注明,原创地址,谢谢配合! http://qind ... -
Lucene4.3进阶开发之乱世丛生(二)
2013-12-17 01:10 3776转载请务必注明,原创地址,谢谢配合! http://qind ... -
Lucene4.3进阶开发之初入仙界(一)
2013-11-25 15:40 5560转载请务必注明,原创地址,谢谢配合! http://qind ...
相关推荐
在"lucene4.3 按坐标距离排序"这个主题中,我们将探讨如何在Lucene 4.3版本中利用地理位置信息进行文档排序,特别是在处理地理空间搜索时的应用。 首先,Lucene 4.3引入了对地理空间搜索的支持,这允许我们根据地理...
Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件基金会...
lucene4.3增删改查的的一个工具类,对新手来说是一份不可多得的入门资料。
全文检索lucene 4.3 所用到的3个jar包,包含lucene-queryparser-4.3.0.jar、 lucene-core-4.3.0.jar、lucene-analyzers-common-4.3.0.jar。
《Lucene高级搜索进阶项目_04》 在深入探讨Lucene的高级搜索进阶项目时,我们首先需要理解Lucene的核心概念及其在信息检索中的应用。Lucene是一个高性能、全文本搜索库,它提供了丰富的搜索功能,包括布尔运算、...
lucene4.3源代码 censed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information ...
本课程由浅入深的介绍了Lucene4的发展历史,开发环境搭建,分析lucene4的中文分词原理,深入讲了lucenne4的系统架构,分析lucene4索引实现原理及性能优化,了解关于lucene4的搜索算法优化及利用java结合lucene4实现...
Lucene是一个开源的全文搜索引擎库,由Apache软件基金会开发并维护。在Java编程环境中,它为开发者提供了强大的文本检索功能,使得在海量数据中快速查找相关信息变得简单易行。本篇文章将详细探讨Lucene 4.3.1版本的...
共13页07.Lucene搜索实战1 共4页08.Lucene搜索实战2 共5页09.Lucene搜索深入实战1 共5页10.Lucene搜索深入实战2 共11页11....Lucene高级进阶1 共23页16.Lucene高级进阶2 共4页17.Lucene高级进阶3 共4页18.Lucene排序...
结合笔者的实际开发经验,总结了一些新的开发技巧和开发思路,并对网上流传的一些错误...本书既可为零起点的Lucene初学者提供系统全面的学习指导,也可帮助有相关经验的开发者解决在开发过程中遇到的一些难题和疑惑。
在本课程中,我们主要探讨了Lucene 4.x版本的高级进阶应用,特别是针对大规模文档搜索引擎的构建。Lucene作为一个开源全文搜索引擎库,它提供了高效、灵活的索引和搜索功能,是构建高性能搜索系统的基石。在这个部分...
1.XunTa是在lucene4.3上创建的通过“知识点”来找人的搜人引擎。 输入一个关键词(或组合),XunTa返回一个排名列表,排在前面的人是与该关键词(组合)最相关的“达人”。 可访问 http://www.xunta.so立即体验...
在高级进阶部分,我们将重点探讨Lucene在索引、搜索、排序、过滤以及分词器等方面的高级用法,旨在帮助开发者掌握Lucene的精髓,打造高效、精确的搜索体验。 1. **Document与索引更新**: 在Lucene中,`Document`...
Lucene是Java开发的开源库,它提供了文本分析、索引和搜索功能,使得开发者能够轻松地在应用程序中实现复杂的搜索功能。这个项目的重点在于提升对Lucene高级特性和优化技巧的理解。 首先,我们要了解Lucene的核心...
【Lucene4.X实战类baidu搜索的大型文档海量搜索系统】课程主要涵盖了Lucene搜索引擎的各个方面,包括基础和高级进阶。以下是课程的主要知识点: 1. **Lucene入门与系统架构**:介绍Lucene的基本概念,以及其系统...
共13页07.Lucene搜索实战1 共4页08.Lucene搜索实战2 共5页09.Lucene搜索深入实战1 共5页10.Lucene搜索深入实战2 共11页11....Lucene高级进阶1 共23页16.Lucene高级进阶2 共4页17.Lucene高级进阶3 共4页18.Lucene排序...
共13页07.Lucene搜索实战1 共4页08.Lucene搜索实战2 共5页09.Lucene搜索深入实战1 共5页10.Lucene搜索深入实战2 共11页11....Lucene高级进阶1 共23页16.Lucene高级进阶2 共4页17.Lucene高级进阶3 共4页18.Lucene排序...
共13页07.Lucene搜索实战1 共4页08.Lucene搜索实战2 共5页09.Lucene搜索深入实战1 共5页10.Lucene搜索深入实战2 共11页11....Lucene高级进阶1 共23页16.Lucene高级进阶2 共4页17.Lucene高级进阶3 共4页18.Lucene排序...
共13页07.Lucene搜索实战1 共4页08.Lucene搜索实战2 共5页09.Lucene搜索深入实战1 共5页10.Lucene搜索深入实战2 共11页11....Lucene高级进阶1 共23页16.Lucene高级进阶2 共4页17.Lucene高级进阶3 共4页18.Lucene排序...
共13页07.Lucene搜索实战1 共4页08.Lucene搜索实战2 共5页09.Lucene搜索深入实战1 共5页10.Lucene搜索深入实战2 共11页11....Lucene高级进阶1 共23页16.Lucene高级进阶2 共4页17.Lucene高级进阶3 共4页18.Lucene排序...