zoukankan      html  css  js  c++  java
  • 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 在没有MUST的BooleanQuery中至少要满足最低数目的SHOULD,最低数目可设置   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", "去哪儿");//爸爸去哪儿 或者 爸爸ni
    52         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……

  • 相关阅读:
    Qt Qaction和触发函数建立连接的方法
    Qt QChart缩放后坐标轴间隔取整
    Qt 编译时报错“退出,退出代码2”的原因
    Qt Qchart 中清空绘图
    Qt QChartView 如何放入widget
    Qt QChart之曲线图,饼状图,条形图使用
    Qt 实现控件不响应鼠标点击事件
    Qt css样式大全(整理版)
    Qt 加载qss文件
    Qt 如何处理密集型耗时的事情(频繁调用QApplication::processEvents)
  • 原文地址:https://www.cnblogs.com/erbin/p/3928281.html
Copyright © 2011-2022 走看看