首页 > 代码库 > Lucene实践之Query
Lucene实践之Query
检索过程中可能会面临各种各样的复杂条件检索,今天学习一下lucene各种Query,并通过多个Query的合并使用实现多条件的检索。
Game Starts
参考文档
1) Package org.apache.lucene.search Description
2) Lucene整理4-各种Query(转)
依赖的jar包
1)lucene-core.jar
2)lucene-analyzer-common
3)lucene-queryParser
主要的类
1)Term
Term表示的就是一个词,这里的词并不是我们生活中所谓的词语,而是lucene创建索引时所做的分词,使用的分词器不同这里对词的划分也就不同。例如‘爸爸去哪儿’,我使用IKAnalyzer分词后为‘爸爸’‘去哪儿’,这里我用‘爸爸’‘去哪儿’匹配都可以匹配,但是用‘爸爸去哪儿’‘爸爸去’‘爸’等都是无法匹配的。Term有三种构造方法。常用的有两种1、public Term(String fld, BytesRef bytes); 2、public Term(String fld, String text); 注意的是参数不要为空,BytesRef String都是传递的引用,所以应用的对象在后面不要发生改变,话说回来,让String引用的对象发生改变还是挺费劲的。
2)TermQuery
TermQuery是最简单最常用的一个Query的实现。TermQuery匹配包含指定的Term的Document。
简单的构造方法TermQuery tq = new TermQuery(new Term("fieldName", "term"));
匹配分filedName中包含term的,注意是包含,不是完全匹配,想要完全匹配怎么办?构建索引的是对这个field不分词就行了,还是要记住什么是Term.
3)BooleanQuery
当将多个TermQuery合并到一起时,可以使用BooleanQuery,通过BooleanClause参数决定TermQuery之间的合并关系.
BooleanClause有三个值 1、MUST 该TermQuery必须满足 2、SHOULD 多个TermQuery至少满足一个 3、MUST_NOT TermQuery必须不满足当然BooleanQuery并不局限于TermQuery的合并,和可以和其他的Query合作。
4)PhrasesQuery
PhrasesQuery 是另一个常用的Query。匹配多个Term,通过坡度(slop)来指定任意两个指定的Term之间最多可以像个几个Term。
MultiPhraseQuery 是一个更常见的PhraseQuery的形式,可以实现更为复杂的Term排列。具体例子【Always Be Coding】会给出。
5)TermRangeQuery
TermRangeQuery,很明显是按Term的范围来匹配。当然指定的field是可以比较的。特别说明数值类的不可以用这个Query,使用数值类特有的NumericRangeQuery。
6)NumericRangeQuery
NumericRangeQuery 匹配数值范围。要想使得NumericRangeQuery起作用,构建索引是也要使用数值域(IntField, LongField, FloatField, or DoubleField)
7)QueryParser
QueryParser是使用特定分词器解析query。将query分成若干个Term,然后去和Document匹配。
多个Term之间的关系有点类似于BoolenQuery的 BooleanClause.SHOULD,但是匹配的term数会影响到结果的排序
8)MultiFieldQueryParser
MultiFieldQueryParser,很明显是同时对多个域进行分析。MultiFieldQueryParser.parse(Version matchVersion, String[] queries, String[] fields, Analyzer analyzer)MultiFieldQueryParser.parse(Version matchVersion, String[] queries, String[] fields, BooleanClause.Occur[] flags, Analyzer analyzer)MultiFieldQueryParser.parse(Version matchVersion, String query, String[] fields, BooleanClause.Occur[] flags, Analyzer analyzer)其中数组的长度一定要对应好
Always Be Coding
1 package lucene; 2 3 import java.io.File; 4 import java.io.IOException; 5 6 import org.apache.lucene.analysis.Analyzer; 7 import org.apache.lucene.document.Document; 8 import org.apache.lucene.index.DirectoryReader; 9 import org.apache.lucene.index.IndexReader;10 import org.apache.lucene.index.Term;11 import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;12 import org.apache.lucene.queryparser.classic.ParseException;13 import org.apache.lucene.queryparser.classic.QueryParser;14 import org.apache.lucene.search.BooleanClause;15 import org.apache.lucene.search.BooleanClause.Occur;16 import org.apache.lucene.search.BooleanQuery;17 import org.apache.lucene.search.IndexSearcher;18 import org.apache.lucene.search.MultiPhraseQuery;19 import org.apache.lucene.search.NumericRangeQuery;20 import org.apache.lucene.search.PhraseQuery;21 import org.apache.lucene.search.Query;22 import org.apache.lucene.search.ScoreDoc;23 import org.apache.lucene.search.TermQuery;24 import org.apache.lucene.search.TermRangeQuery;25 import org.apache.lucene.search.TopDocs;26 import org.apache.lucene.store.FSDirectory;27 import org.apache.lucene.util.BytesRef;28 import org.apache.lucene.util.Version;29 import org.wltea.analyzer.lucene.IKAnalyzer;30 31 public class Searcher {32 public static void main(String[] args) throws IOException, ParseException {33 IndexSearcher indexSearcher;34 Analyzer anlyzer = new IKAnalyzer(true);;35 long start = System.currentTimeMillis();36 IndexReader indexReader = DirectoryReader.open(FSDirectory.open(new File("/home/erbin/Documents/data/index")));37 indexSearcher = new IndexSearcher(indexReader);38 BooleanQuery booleanQuery = new BooleanQuery();39 QueryParser parser = new QueryParser(Version.LUCENE_46, "title", anlyzer);40 Query query = parser.parse("爸爸");41 booleanQuery.add(query, Occur.MUST);42 TermQuery termQuery = new TermQuery(new Term("city","北京"));43 booleanQuery.add(termQuery, Occur.MUST);44 PhraseQuery phraseQuery = new PhraseQuery();45 phraseQuery.setSlop(1);46 phraseQuery.add(new Term("name","爸爸"));47 phraseQuery.add(new Term("name","妈妈"));48 booleanQuery.add(phraseQuery, Occur.MUST_NOT);49 MultiPhraseQuery multiPhrasequery = new MultiPhraseQuery();50 multiPhrasequery.add(new Term("name","爸爸"));//前缀51 Term t1 = new Term("name", "去哪儿");//爸爸去哪儿 或者 爸爸ni52 Term t2 = new Term("name", "到哪儿");53 multiPhrasequery.add(new Term[]{t1, t2});//组成:爸爸去哪儿,爸爸到哪儿54 booleanQuery.add(multiPhrasequery, Occur.SHOULD);55 Query numericRangeQuery = NumericRangeQuery.newIntRange("name", 0, 4, false, false);56 booleanQuery.add(numericRangeQuery, Occur.SHOULD);57 Query termRangeQuery = new TermRangeQuery("name", new BytesRef("20100101"), new BytesRef("20101231"), false, false);58 booleanQuery.add(termRangeQuery, Occur.SHOULD);59 Query multiFieldQueryParser = MultiFieldQueryParser.parse(Version.LUCENE_46,
"爸爸",
new String[]{"name","content"},
new BooleanClause.Occur[]{Occur.MUST,Occur.MUST_NOT} ,
anlyzer);60 booleanQuery.add(multiFieldQueryParser, Occur.SHOULD);61 TopDocs results = indexSearcher.search(booleanQuery, 10);62 ScoreDoc[] hits = results.scoreDocs;63 int totalHits = results.totalHits;64 for(int i = 0; i < totalHits; i++) {65 Document doc = indexSearcher.doc(hits[i].doc);66 System.out.println("["+doc.get("title")+"]");67 }68 long end = System.currentTimeMillis();69 System.out.println(end - start);70 }71 }
TO BE CONTINUED……
Lucene实践之Query
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。