`
suichangkele
  • 浏览: 197835 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

实现得分的PrefixQuery

阅读更多

(先声明一下,我使用的lucene的版本是lucene4.7.2)

在lucene中,有一种类型的query叫做MultiTermQuery,故名思议,他是要涉及到很多个term的query,比如我们常用的WildcardQuery、FuzzyQuery、PrefixQuery、TermRangeQuery、NumericRangeQuery等,他们都是需要按照一个或者多个term按照一定的逻辑找到多个term,然后再重写由找到的这些term形成的TermQuery进入一个新的Query(比如BooleanQuery、或者ConstantScoreQuery),但是有个一指的注意的地方是:有些MultiTermQuery是不得分的,也就是在返回的时候不会按照得分排序,比如PrefixQuery,的不得分是由每个MultiTermQuery使用的rewriteMethod指定,也就是由重写规则指定。本文的目的不在于讨论重写规则,而是想实现一个可以得分的PrefixQuery(业务场景是我们要使用PrefixQuery做搜索框中提示词的排序,所以必须实现得分)。

 

实现原理很简单,在指定重写规则的时候将重写规则指定为得分的规则(当然这里涉及到重写规则的实现,这里本文不讨论),在org.apache.lucene.search.MultiTermQuery类中含有SCORING_BOOLEAN_QUERY_REWRITE这个重写规则从他的名字中就可以理解是封装为一个BooleanQuery,并且计算分数。他的逻辑很简单,将搜索到的多个termQuery封装成一个booleanQuery,每一个termQuery都是optional的,也就是对多个termQuery取并集。但是Booleanquery有个需要注意的地方,他不能有太多的clause,不然会报错,默认是1024个,所以我们需要修改这个值,做到这里就算是完成了。我的代码如下:

/**
 * 由于solr自带的PrefixQuery是不得分的,不能满足提示词的排序要求,所以重写这个query.
 */
public class ScoredPrefixQuery extends PrefixQuery {

	//从词典表中得到的term的限制,用于做测试的,实际中不用
	private int limit = -1; 
	
	static{
		BooleanQuery.setMaxClauseCount(Integer.MAX_VALUE);//设置BooleanQuery的最多的子query的个数为Integer.MAX_VALUE。
	}
	
	public ScoredPrefixQuery(Term prefix) {
		super(prefix);
		//重置重写规则,使用得分的booleanQuery,此处存在的问题是可能会发生BooleanQuery.TooManyClauses,所以要在得到term的时候需要做限制
		setRewriteMethod(org.apache.lucene.search.MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE);
	}
	/**
         * 从词典表中得到前缀匹配的term的方法
         */
	@Override
	public TermsEnum getTermsEnum(Terms terms, AttributeSource atts) throws IOException {
		 TermsEnum tenum = terms.iterator(null);
		 if (getPrefix().bytes().length == 0) {
		      // no prefix -- match all terms for this field:
		     return tenum;
		 }
		 return new PrefixTermsEnum(tenum, getPrefix().bytes()) {
			 int already = 0;
			 final int termLimit =  limit==-1?BooleanQuery.getMaxClauseCount():limit;//设置limit只是用于做测试的。
			 
			 @Override
			public BytesRef next() throws IOException {
				
				BytesRef ref = super.next();//先调用父类方法,即从词典表中读取,
				if(ref == null){//如果真的读完了,就返回null。
					return null;
				}else{//没有读取完,则判断是否已经读取了太多的term
					//最多的BooleanClause的个数
					if(already++ < termLimit){//一个前缀最多从词典表中得到booleanquery的MaxClause个,这样就不会报错了。
						return ref;
					}
					return null;
				}
			}
		 };
	}
	
	public int getLimit() {
		return limit;
	}
	
	//做测试用的
	public void setLimit(int limit) {
		this.limit = limit;
	}
	
//这个测试的前提是我们在索引中仅仅保存了只有id域的100个document,id为从0-99,省略了建立索引的代码。
	public static void main(String[] args) throws IOException {
		
		IndexReader reader = DirectoryReader.open(getDirectory());
		
		IndexSearcher search = new IndexSearcher(reader);
		ScoredPrefixQuery q = new ScoredPrefixQuery(new Term("id","1"));//这一行和下面的PrefixQuery q 这一行是区分的,如果使用这一行则只会搜到3个,并且得分不是1.0f,也就是是得分的。
		q.setLimit(3);//设置最多为3个。
		
//		PrefixQuery q = new PrefixQuery(new Term("id", "1"));//如果使用lucene中默认使用的PrefixQuery则会搜到11个,并且得分都是1.0f,也就是没有得分。
		
		TopDocs td = search.search(q, 100);
		for(ScoreDoc sd:td.scoreDocs){
			System.out.println(sd.score);
		}
		System.out.println(td.scoreDocs.length);
		
	}	
}

 

这样就完成了得分的前缀匹配的query,如果要在solr中使用,还需要自己定义queryparser的插件,这个留在以后再写博客。

 

 

 

分享到:
评论

相关推荐

    Lucene实现全文检索

    2. **模糊搜索**:通过使用PrefixQuery、WildcardQuery或FuzzyQuery,可以实现模糊匹配和通配符查询。 3. **近似搜索**:通过使用SpanNearQuery或PhraseQuery,可以查找接近的词序。 4. **过滤器(Filter)**:...

    google suggest 的实现

    - 构建查询对象(例如使用 `PrefixQuery`),并进行搜索操作。 - 获取搜索结果,并将结果转换为 XML 格式返回给前端。 3. **示例代码片段**: ```java public class LuceneSearch extends HttpServlet { ...

    Lucene 搜索方法(前缀搜索)

    总结来说,Lucene的前缀搜索功能通过`PrefixQuery`类实现,结合适当的查询解析器和分析器,为用户提供了一种快速、灵活的方式,来查找与输入前缀相关的所有文档。这在诸如在线商店、知识库、搜索引擎等应用中具有很...

    PreFixFilterQuery.java

    ilter:所有的过滤器都在服务端生效,以保证被过滤掉的数据不会被传送到客户端 •过滤器是在HBase服务器端上执行判断操作 •过滤器可以应用到行键(RowFilter),列限定符(QualifierFilter)或者数据值...

    lucene例子

    3. **PrefixQuery**、**WildcardQuery** 和 **RegexQuery**:这些查询类支持模糊匹配,如前缀查询、通配符查询和正则表达式查询,适用于对多个字段进行灵活的文本匹配。 4. **DisjunctionMaxQuery**:用于在多个...

    lucene-搜索过程源码解析-1-Weight生成.txt

    本文将深入分析 `Weight` 对象的生成过程,并通过代码示例来具体说明 Lucene 如何实现这一过程。 #### 二、Weight 生成流程 ##### 1. IndexSearcher 的 search 方法 当调用 `IndexSearcher` 的 `search` 方法时,...

    Lucene教程

    1. **Query**: Lucene支持多种查询类型,如TermQuery(单个词查询)、BooleanQuery(布尔组合查询)、PrefixQuery(前缀查询)和WildcardQuery(通配符查询)。 2. **Score**: 搜索结果中的每个文档都有一个得分,...

    lucene学习笔记

    3. `PrefixQuery`:前缀搜索,自动在字段值的末尾添加`*`,实现前缀匹配。 4. `RangeQuery`:范围搜索,适用于数值型字段,在指定范围内查找文档。 5. `FilteredQuery`:带有过滤条件的搜索,结合`Query`和`Filter`...

    lucene创建修改删除组合条件查询

    **类似MySQL的LIKE条件**在Lucene中,可以通过`WildcardQuery`或`PrefixQuery`实现。例如,如果要查询以"abc"开头的单词,可以创建一个`PrefixQuery`并传入"abc*"作为参数。 **类似MySQL的IN条件**可以使用`...

    lucene3.0.2jar包

    4. 高级查询API:包括TermQuery、PhraseQuery、WildcardQuery、PrefixQuery等,满足不同类型的搜索需求。 5. 倒排索引:Lucene采用倒排索引机制,允许快速定位到包含特定关键词的文档,极大提高了搜索效率。 二、...

    lucene高级智能查询小案例

    在高级查询中,我们可能会利用FuzzyQuery进行模糊匹配,或者使用PrefixQuery进行前缀搜索,这些都能极大地提高用户查询的灵活性。 在智能查询中,更常见的功能是短语查询和近似查询。SpanQuery类族提供了一种精确...

    【分享:lucene学习资料】---<下载不扣分,回帖加1分,欢迎下载,童叟无欺>

    2&gt; 全文检索的实现机制 【1】lucene学习笔记的目录如下 1. 概述 3 2. lucene 的包结构 3 3. 索引文件格式 3 4. lucene中主要的类 4 4.1. Document文档类 4 4.1.1. 常用方法 4 4.1.2. 示例 4 4.2. Field字段类 4 ...

    Fuzzy-Information-Retrieval-Search:基于模糊信息检索的搜索引擎,在查询中包含拼写错误。 它已在 Java 和 Lucene 中实现

    此外,还可以使用 `PrefixQuery` 或 `WildcardQuery` 来处理部分匹配和通配符查询。 项目“Fuzzy-Information-Retrieval-Search-master”很可能包含以下组件和步骤: 1. **索引构建**:使用 Lucene 将大量文本数据...

    lucene.zip

    Apache Lucene是一个开源的全文搜索引擎库,它为开发者提供了在Java应用程序中实现高级搜索功能的基础。在这个简单的入门程序中,我们将探讨如何利用Lucene进行索引创建、多种查询方式的运用以及索引的删除、新增和...

    Luncene学习资料

    此外,还可以使用`BooleanQuery`、`PrefixQuery`、`WildcardQuery`等高级查询类型进行更复杂的多条件搜索。 【Lucene 索引与搜索】Lucene的核心功能之一是建立索引,这是为了提高搜索效率。索引过程包括分析(分词...

    lucene高级搜索进阶项目_02

    除了基本的单词查询,Lucene还支持更复杂的查询类型,如PrefixQuery(前缀查询)、WildcardQuery(通配符查询)、FuzzyQuery(模糊查询)、RegexQuery(正则表达式查询)等。这些查询类型极大地扩展了搜索能力,允许...

    Lucene全文搜索 分组,精确查找,模糊查找

    3. **PrefixQuery**:在需要精确查找的词前添加星号`*`,如`new PrefixQuery(new Term("field", "keyword*"))`,可以匹配以"keyword"开头的所有词。 三、Lucene模糊查找 模糊查找则允许用户输入可能存在拼写错误或...

    Ajax+Lucene 打造搜索引擎

    此外,还可以添加自动补全功能,利用Lucene的PrefixQuery或Suggester模块,当用户输入查询时提供可能的匹配项。 在实际开发中,还需要考虑一些额外的细节,如错误处理、性能优化(如使用缓存、分页等)、安全性和可...

    lucenelucene-core-3.5.0_jar

    - **新特性**:引入了新的查询类型和功能,如PrefixQuery和WildcardQuery。 - **错误修复**:修复了前一版本中的一些已知问题,提高了系统的稳定性和可靠性。 4. **使用示例**: - 创建索引:首先实例化Analyzer...

    C#+Lucene.Net开发完成的一个自定义WEB搜索引擎

    例如,使用PrefixQuery、WildcardQuery或FuzzyQuery等,可以匹配部分关键词或近似关键词。 **五、Lucene.Net的索引机制** Lucene.Net通过建立倒排索引来实现快速搜索。索引过程包括分析文本、创建Term(词项)、...

Global site tag (gtag.js) - Google Analytics