开场白:
我看过几本书说关于lucene中的BooleanQuery查询条件的参数
Boolean.Clause.MUST,Boolean.Clause.MUST_NOT,Boolean.Clause.SHOULD之关的关系,其实就好象是集合中的交集并集等关系.这里不重复书的例子,说一点我平时在工作中的应用吧.
书基本都是说,当MUST与SHOULD关联使用的时候,跟MUST使用是一样的,那天我做一个关系搜索结果按相关排序,这里简单说一下需求,这是说用户输入关键字后,应该把所有的付费会员商品按相关度从高到低排序来推荐给用户.现在已经一批付费会员的编号了,同时知道会员用户的产品名称与产品介绍。那应该如何去按照输入的关键字来排序呢?要知道,关键字有可能与付费会员的产品完全不相关,当然,这些不相关产品会排在最后边。
现在贴出相关的代码
package com.lucene.test;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.IndexWriter.MaxFieldLength;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopFieldDocs;
/**
*
* @author kernaling.wong
* 本类只是演示should对结果的出现是没有影响的,但是影响结果的相关度,可以利用之来进度某些相关的排序搜索
*/
public class LuceneTest {
private static String INDEX_PATH = "./Index/";
public static void main(String[] args) {
if(false){ //做索引的时候就把 true;
IndexWriter writer = null;
try{
writer = new IndexWriter(INDEX_PATH,new StandardAnalyzer(),MaxFieldLength.LIMITED);
Document doc = new Document();
Field fieldCode = new Field("Code","1",Field.Store.YES,Field.Index.ANALYZED);
Field fieldName = new Field("Name","电热炉",Field.Store.YES,Field.Index.ANALYZED);
Field fieldInfo = new Field("Info","这是一个电热
炉",Field.Store.YES,Field.Index.ANALYZED);
doc.add(fieldCode);
doc.add(fieldName);
doc.add(fieldInfo);
writer.addDocument(doc);
doc = new Document();
fieldCode = new Field("Code","2",Field.Store.YES,Field.Index.ANALYZED);
fieldName = new Field("Name","电水壶",Field.Store.YES,Field.Index.ANALYZED);
fieldInfo = new Field("Info","解放牌电水壶",Field.Store.YES,Field.Index.ANALYZED);
doc.add(fieldCode);
doc.add(fieldName);
doc.add(fieldInfo);
writer.addDocument(doc);
doc = new Document();
fieldCode = new Field("Code","3",Field.Store.YES,Field.Index.ANALYZED);
fieldName = new Field("Name","水杯",Field.Store.YES,Field.Index.ANALYZED);
fieldInfo = new Field("Info","钢化水杯",Field.Store.YES,Field.Index.ANALYZED);
doc.add(fieldCode);
doc.add(fieldName);
doc.add(fieldInfo);
writer.addDocument(doc);
doc = new Document();
fieldCode = new Field("Code","4",Field.Store.YES,Field.Index.ANALYZED);
fieldName = new Field("Name","碟子",Field.Store.YES,Field.Index.ANALYZED);
fieldInfo = new Field("Info","质量很好",Field.Store.YES,Field.Index.ANALYZED);
doc.add(fieldCode);
doc.add(fieldName);
doc.add(fieldInfo);
writer.addDocument(doc);
System.out.println("索引建立完成!");
}catch(Exception ex){
ex.printStackTrace();
}finally{
if(writer != null){
try{
writer.close();
}catch(Exception ex){
ex.printStackTrace();
}
}
}
}else{
IndexSearcher search = null;
IndexReader ir = null;
try{
search = new IndexSearcher(INDEX_PATH);
String keyword = "水"; //用户输入了需要搜索的关键字
BooleanQuery bq = new BooleanQuery();
/**
* 以下上查询条件,因为无论用户输入的关键字如何都需要全部显示付费会员商品,相关度从高
到低
*/
BooleanQuery tmpBQ = new BooleanQuery(); //这是一个
tmpBQ.add(new TermQuery((new Term("Code","1"))),BooleanClause.Occur.MUST);
tmpBQ.add(new TermQuery((new Term("Name",keyword))),BooleanClause.Occur.SHOULD);
tmpBQ.add(new TermQuery((new Term("Info",keyword))),BooleanClause.Occur.SHOULD);
bq.add(tmpBQ,BooleanClause.Occur.SHOULD);
tmpBQ = new BooleanQuery();
tmpBQ.add(new TermQuery((new Term("Code","2"))),BooleanClause.Occur.MUST);
tmpBQ.add(new TermQuery((new Term("Name",keyword))),BooleanClause.Occur.SHOULD);
tmpBQ.add(new TermQuery((new Term("Info",keyword))),BooleanClause.Occur.SHOULD);
bq.add(tmpBQ,BooleanClause.Occur.SHOULD);
tmpBQ = new BooleanQuery();
tmpBQ.add(new TermQuery((new Term("Code","3"))),BooleanClause.Occur.MUST);
tmpBQ.add(new TermQuery((new Term("Name",keyword))),BooleanClause.Occur.SHOULD);
tmpBQ.add(new TermQuery((new Term("Info",keyword))),BooleanClause.Occur.SHOULD);
bq.add(tmpBQ,BooleanClause.Occur.SHOULD);
tmpBQ = new BooleanQuery();
tmpBQ.add(new TermQuery((new Term("Code","4"))),BooleanClause.Occur.MUST);
tmpBQ.add(new TermQuery((new Term("Name",keyword))),BooleanClause.Occur.SHOULD);
tmpBQ.add(new TermQuery((new Term("Info",keyword))),BooleanClause.Occur.SHOULD);
bq.add(tmpBQ,BooleanClause.Occur.SHOULD);
Sort sort = new Sort(SortField.FIELD_SCORE); //按相关度来排序
TopFieldDocs tdocs = search.search(bq,null,4,sort);
ScoreDoc scoreDocs[] = tdocs.scoreDocs;
ir = search.getIndexReader();
for(int i=0;i<scoreDocs.length;i++){
Document tmpDoc = ir.document(scoreDocs[i].doc);
System.out.println("文档得分:"+scoreDocs[i].score+"\t产品编号:"+tmpDoc.get
("Code")+"\t产品名称:"+tmpDoc.get("Name")+"\t产品说明:"+tmpDoc.get("Info"));
}
}catch(Exception ex){
ex.printStackTrace();
}finally{
try{
if(search != null){
search.close();
}
if(ir != null){
ir.close();
}
}catch(Exception ex){
ex.printStackTrace();
}
}
}
}
}
测试环境是 windowsXP + jdk1.6 与 lucene2.4.
实现后排序的结果应该是这样
后记
以上那种方面需要说明的是,如果出现了大量的付费会员的时候,即,需要BooleanClause.Occur.SHOULD很多用户编号的时候,建议不要再用些方法了,同时BooleanQuery条件中会限制BooleanQuery.add的条件数量,默认是1024个,当然也可以手动设置它的最大上限,通过setMaxClauseCount(int maxCount),因为按我以上那种方法,当注册用户数很多,比如10W或者以上的时候,搜索时性能就会成为瓶颈了。这个时候,我现在想出的方法就是更改Lucene索引的字段,不要再指定付费用户去SHOULD每一个付费用户了,改为增加一个字段去表示是否注册用户.然后再用上边类似方法就可以比较高效率地实现这个功能了,最原先那个种方法是头脑发热的时候想出来的,那时付费的用户并不多,所以就算这样实现起来都没有问题,不过现在也已经改为到第二种方法了,在暂时无法改变lucene源代码实现与算法的时候,那只能改变自己的方法了.
- 大小: 37.8 KB
分享到:
相关推荐
第一个是 FSDirectory,它表示一个存储在文件系统中的索引的位置。 第二个是 RAMDirectory,它表示一个存储在内存当中的索引的位置。 public void add(Query query, BooleanClause.Occur occur) BooleanClause...
lucene.NET 中文分词 高亮 lucene.NET 中文分词 高亮 lucene.NET 中文分词 高亮 lucene.NET 中文分词 高亮
lucene 3.0 API中文帮助,学习的人懂得的
lucene实例lucene实例lucene实例lucene实例lucene实例lucene实例lucene实例lucene实例lucene实例
You should see the Lucene JAR file in the core/ directory you created when you extracted the archive -- it should be named something like lucene-core-{version}.jar. You should also see files called ...
Lucene关于几种中文分词的总结
来自“猎图网 www.richmap.cn”基于IKAnalyzer分词算法的准商业化Lucene中文分词器。 1. 正向全切分算法,42万汉字字符/每秒的处理能力(IBM ThinkPad 酷睿I 1.6G 1G内存 WinXP) 2. 对数量词、地名、路名的...
本文设计实现了一个中文分词模块,其主要研究目的在于寻找更为有效的中文词汇 处理方法,提高全文检索系统的中文处理能力.整个模块基于当前最流行的搜索引擎架构 Lucene,实现了带有歧义消除功能的正向最大匹配算法...
比较全面的一个入门 比较全面的一个入门 比较全面的一个入门 比较全面的一lucene个入门 比较全面的一个入门
Lucene 与中文分词的结合
描述了Lucene中如何使用FST算法构建term的内存索引,使用了很多图,直观的展现了FST图的构建流程,能够对想了解lucene内部实现机制原理的同学有帮助。
lucene工作原理.docxlucene工作原理.docxlucene工作原理.docx
lucene的一个例子,放在这里方便大家学习,本人会不断分享我的个人资源
赠送jar包:lucene-core-7.2.1.jar; 赠送原API文档:lucene-core-7.2.1-javadoc.jar; 赠送源代码:lucene-core-7.2.1-sources.jar; 赠送Maven依赖信息文件:lucene-core-7.2.1.pom; 包含翻译后的API文档:lucene...
lucene3.0 lucene3.0 lucene3.0 lucene3.0 lucene3.0
Lucene中文分词器组件,不错的。
lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习...
Lucene是一个全文搜索框架,而不是应用产品。因此它并不像www.baidu.com 或者google Desktop那么拿来就能用,它只是提供了一种工具让你能实现这些产品。 2 lucene的工作方式 lucene提供的服务实际包含两部分:一...
我做的一个Lucene的毕业设计,例子比较简单,但是能学到Lucene的大概的使用过程。
Lucene在web项目中的应用,孔浩老师讲的,从建立索引-搜索-分词,到在留言项目中的应用,适合搜索初学者代码练习...