zoukankan      html  css  js  c++  java
  • 基于lucene的案例开发:查询语句创建PackQuery

    转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/44656141

    http://www.llwjy.com/blogdetail/162e5e70516d7ddfb6df8f77e6b13a2b.html

    个人博客站已经上线了,网址 www.llwjy.com ~欢迎各位吐槽

    -----------------------------------------------------------------------------------------------------------

          在之前的《基于lucene的案例开发:Query查询》这篇博客中对实际开发过程中比较常见的Query做了简单的介绍,这里就介绍下具体的代码实现。查看最新代码点击这里或访问 http://www.llwjy.com/source/com.lulei.lucene.query.PackQuery.html 

    1.  /**   
    2.  *@Description:  创建查询Query   
    3.  */   
    4. package com.lulei.lucene.query;    
    5.   
    6. import java.io.IOException;  
    7. import java.io.StringReader;  
    8. import java.util.ArrayList;  
    9.   
    10. import org.apache.lucene.analysis.Analyzer;  
    11. import org.apache.lucene.analysis.TokenStream;  
    12. import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;  
    13. import org.apache.lucene.index.Term;  
    14. import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;  
    15. import org.apache.lucene.queryparser.classic.ParseException;  
    16. import org.apache.lucene.queryparser.classic.QueryParser;  
    17. import org.apache.lucene.search.BooleanClause.Occur;  
    18. import org.apache.lucene.search.BooleanQuery;  
    19. import org.apache.lucene.search.NumericRangeQuery;  
    20. import org.apache.lucene.search.PhraseQuery;  
    21. import org.apache.lucene.search.PrefixQuery;  
    22. import org.apache.lucene.search.Query;  
    23. import org.apache.lucene.search.TermQuery;  
    24. import org.apache.lucene.search.TermRangeQuery;  
    25. import org.apache.lucene.search.WildcardQuery;  
    26. import org.apache.lucene.util.Version;  
    27.   
    28. import com.lulei.lucene.index.manager.IndexManager;  
    29.   
    30.   
    31. public class PackQuery {  
    32.     //分词器  
    33.     private Analyzer analyzer;  
    34.     //使用索引中的分词器  
    35.     public PackQuery(String indexName) {  
    36.         analyzer = IndexManager.getIndexManager(indexName).getAnalyzer();  
    37.     }  
    38.     //使用自定义分词器  
    39.     public PackQuery(Analyzer analyzer) {  
    40.         this.analyzer = analyzer;  
    41.     }  
    42.   
    43.     /** 
    44.      * @param key 
    45.      * @param fields 
    46.      * @return Query 
    47.      * @throws ParseException 
    48.      * @Author: lulei   
    49.      * @Description: 查询字符串匹配多个查询域 
    50.      */  
    51.     public Query getMultiFieldQuery(String key, String[] fields) throws ParseException{  
    52.         MultiFieldQueryParser parse = new MultiFieldQueryParser(Version.LUCENE_43, fields, analyzer);  
    53.         Query query = null;  
    54.         query = parse.parse(key);  
    55.         return query;  
    56.     }  
    57.       
    58.     /** 
    59.      * @param key 
    60.      * @param field 
    61.      * @return Query 
    62.      * @throws ParseException 
    63.      * @Author: lulei   
    64.      * @Description: 查询字符串匹配单个查询域 
    65.      */  
    66.     public Query getOneFieldQuery(String key, String field) throws ParseException{  
    67.         if (key == null || key.length() < 1){  
    68.             return null;  
    69.         }  
    70.         QueryParser parse = new QueryParser(Version.LUCENE_43, field, analyzer);  
    71.         Query query = null;  
    72.         query = parse.parse(key);  
    73.         return query;  
    74.     }  
    75.       
    76.     /** 
    77.      * @param key 
    78.      * @param fields 
    79.      * @param occur 
    80.      * @return Query 
    81.      * @throws IOException 
    82.      * @Author: lulei   
    83.      * @Description: 查询字符串、多个查询域以及查询域在查询语句中的关系 
    84.      */  
    85.     public Query getBooleanQuery(String key, String[] fields, Occur[] occur) throws IOException{  
    86.         if (fields.length != occur.length){  
    87.             System.out.println("fields.length isn't equals occur.length, please check params!");  
    88.             return null;  
    89.         }  
    90.         BooleanQuery query = new BooleanQuery();  
    91.         TokenStream tokenStream = analyzer.tokenStream("", new StringReader(key));  
    92.         ArrayList<String> analyzerKeys = new ArrayList<String>();  
    93.         while(tokenStream.incrementToken()){  
    94.             CharTermAttribute term = tokenStream.getAttribute(CharTermAttribute.class);  
    95.             analyzerKeys.add(term.toString());  
    96.         }  
    97.         for(int i = 0; i < fields.length; i++){  
    98.             BooleanQuery queryField = new BooleanQuery();  
    99.             for(String analyzerKey : analyzerKeys){  
    100.                 TermQuery termQuery = new TermQuery(new Term(fields[i], analyzerKey));  
    101.                 queryField.add(termQuery, Occur.SHOULD);  
    102.             }  
    103.             query.add(queryField, occur[i]);  
    104.         }  
    105.         return query;  
    106.     }  
    107.       
    108.     /** 
    109.      * @param querys 
    110.      * @param occur 
    111.      * @return Query 
    112.      * @Author: lulei   
    113.      * @Description: 组合多个查询,之间的关系由occur确定 
    114.      */  
    115.     public Query getBooleanQuery(ArrayList<Query> querys, ArrayList<Occur> occurs){  
    116.         if (querys.size() != occurs.size()){  
    117.             System.out.println("querys.size() isn't equals occurs.size(), please check params!");  
    118.             return null;  
    119.         }  
    120.         BooleanQuery query = new BooleanQuery();  
    121.         for (int i = 0; i < querys.size(); i++){  
    122.             query.add(querys.get(i), occurs.get(i));  
    123.         }  
    124.         return query;  
    125.     }  
    126.       
    127.     /** 
    128.      * @param fieldName 
    129.      * @param value 
    130.      * @return 
    131.      * @Author: lulei   
    132.      * @Description: StringField属性的搜索 
    133.      */  
    134.     public Query getStringFieldQuery(String value, String fieldName){  
    135.         Query query = null;  
    136.         query = new TermQuery(new Term(fieldName, value));  
    137.         return query;  
    138.     }  
    139.       
    140.     /** 
    141.      * @param fields 
    142.      * @param values 
    143.      * @return 
    144.      * @Author: lulei   
    145.      * @Description: 多个StringField属性的搜索 
    146.      */  
    147.     public Query getStringFieldQuery(String[] values, String[] fields, Occur occur){  
    148.         if (fields == null || values == null || fields.length != values.length){  
    149.             return null;  
    150.         }  
    151.         ArrayList<Query> querys = new ArrayList<Query>();  
    152.         ArrayList<Occur> occurs = new ArrayList<Occur>();  
    153.         for (int i = 0; i < fields.length; i++){  
    154.             querys.add(getStringFieldQuery(values[i], fields[i]));  
    155.             occurs.add(occur);  
    156.         }  
    157.         return getBooleanQuery(querys, occurs);  
    158.     }  
    159.       
    160.     /** 
    161.      * @param key 
    162.      * @param field 
    163.      * @param lucene43 
    164.      * @return 
    165.      * @throws ParseException 
    166.      * @Author: lulei   
    167.      * @Description: 查询字符串和单个查询域 QueryParser是否使用4.3 
    168.      */  
    169.     public Query getOneFieldQuery(String key, String field, boolean lucene43) throws ParseException{  
    170.         if (key == null || key.length() < 1){  
    171.             return null;  
    172.         }  
    173.         if (lucene43){  
    174.             return getOneFieldQuery(key, field);  
    175.         }  
    176.         @SuppressWarnings("deprecation")  
    177.         QueryParser parse = new QueryParser(Version.LUCENE_30, field, analyzer);  
    178.         Query query = null;  
    179.         query = parse.parse(key);  
    180.         return query;  
    181.     }  
    182.       
    183.     /** 
    184.      * @param key 
    185.      * @param field 
    186.      * @Author: lulei   
    187.      * @Description: key开头的查询字符串,和单个域匹配 
    188.      */  
    189.     public Query getStartQuery(String key, String field) {  
    190.         if (key == null || key.length() < 1){  
    191.             return null;  
    192.         }  
    193.         Query query = new PrefixQuery(new Term(field, key));  
    194.         return  query;  
    195.     }  
    196.       
    197.     /** 
    198.      * @param key 
    199.      * @param fields 
    200.      * @param occur 
    201.      * @Author: lulei   
    202.      * @Description: key开头的查询字符串,和多个域匹配,每个域之间的关系由occur确定 
    203.      */  
    204.     public Query getStartQuery(String key, String []fields, Occur occur){  
    205.         if (key == null || key.length() < 1){  
    206.             return null;  
    207.         }  
    208.         ArrayList<Query> querys = new ArrayList<Query>();  
    209.         ArrayList<Occur> occurs = new ArrayList<Occur>();   
    210.         for (String field : fields) {  
    211.             querys.add(getStartQuery(key, field));  
    212.             occurs.add(occur);  
    213.         }  
    214.         return getBooleanQuery(querys, occurs);  
    215.     }  
    216.       
    217.     /** 
    218.      * @param key 
    219.      * @param fields 
    220.      * @Author: lulei   
    221.      * @Description: key开头的查询字符串,和多个域匹配,每个域之间的关系Occur.SHOULD 
    222.      */  
    223.     public Query getStartQuery(String key, String []fields) {  
    224.         return getStartQuery(key, fields, Occur.SHOULD);  
    225.     }  
    226.       
    227.     /** 
    228.      * @param key 
    229.      * @param field 
    230.      * @param slop 
    231.      * @return 
    232.      * @Author:lulei   
    233.      * @Description: 自定每个词元之间的最大距离 
    234.      */  
    235.     public Query getPhraseQuery(String key, String field, int slop) {  
    236.         if (key == null || key.length() < 1){  
    237.             return null;  
    238.         }  
    239.         StringReader reader = new StringReader(key);  
    240.         PhraseQuery query = new PhraseQuery();  
    241.         query.setSlop(slop);  
    242.         try {  
    243.             TokenStream  tokenStream  = this.analyzer.tokenStream(field, reader);  
    244.             tokenStream.reset();  
    245.             CharTermAttribute  term = tokenStream.getAttribute(CharTermAttribute.class);  
    246.             while(tokenStream.incrementToken()){    
    247.                 query.add(new Term(field, term.toString()));  
    248.             }   
    249.             reader.close();   
    250.         } catch (IOException e) {  
    251.             e.printStackTrace();  
    252.             return null;  
    253.         }  
    254.         return query;  
    255.     }  
    256.       
    257.     /** 
    258.      * @param key 
    259.      * @param fields 
    260.      * @param slop 
    261.      * @param occur 
    262.      * @return 
    263.      * @Author:lulei   
    264.      * @Description: 自定每个词元之间的最大距离,查询多个域,每个域之间的关系由occur确定 
    265.      */  
    266.     public Query getPhraseQuery(String key, String[] fields, int slop, Occur occur) {  
    267.         if (key == null || key.length() < 1){  
    268.             return null;  
    269.         }  
    270.         ArrayList<Query> querys = new ArrayList<Query>();  
    271.         ArrayList<Occur> occurs = new ArrayList<Occur>();   
    272.         for (String field : fields) {  
    273.             querys.add(getPhraseQuery(key, field, slop));  
    274.             occurs.add(occur);  
    275.         }  
    276.         return getBooleanQuery(querys, occurs);  
    277.     }  
    278.       
    279.     /** 
    280.      * @param key 
    281.      * @param fields 
    282.      * @param slop 
    283.      * @return 
    284.      * @Author:lulei   
    285.      * @Description:  自定每个词元之间的最大距离,查询多个域,每个域之间的关系是Occur.SHOULD 
    286.      */  
    287.     public Query getPhraseQuery(String key, String[] fields, int slop) {  
    288.         return getPhraseQuery(key, fields, slop, Occur.SHOULD);  
    289.     }  
    290.       
    291.     /** 
    292.      * @param key 
    293.      * @param field 
    294.      * @return 
    295.      * @Author:lulei   
    296.      * @Description: 通配符检索 eg:getWildcardQuery("a*thor", "field") 
    297.      */  
    298.     public Query getWildcardQuery(String key, String field) {  
    299.         if (key == null || key.length() < 1){  
    300.             return null;  
    301.         }  
    302.         return new WildcardQuery(new Term(field, key));  
    303.     }  
    304.       
    305.     /** 
    306.      * @param key 
    307.      * @param fields 
    308.      * @param occur 
    309.      * @return 
    310.      * @Author:lulei   
    311.      * @Description: 通配符检索,域之间的关系为occur 
    312.      */  
    313.     public Query getWildcardQuery(String key, String[] fields, Occur occur) {  
    314.         if (key == null || key.length() < 1){  
    315.             return null;  
    316.         }  
    317.         ArrayList<Query> querys = new ArrayList<Query>();  
    318.         ArrayList<Occur> occurs = new ArrayList<Occur>();   
    319.         for (String field : fields) {  
    320.             querys.add(getWildcardQuery(key, field));  
    321.             occurs.add(occur);  
    322.         }  
    323.         return getBooleanQuery(querys, occurs);  
    324.     }  
    325.       
    326.     /** 
    327.      * @param key 
    328.      * @param fields 
    329.      * @return 
    330.      * @Author:lulei   
    331.      * @Description: 通配符检索,域之间的关系为Occur.SHOULD 
    332.      */  
    333.     public Query getWildcardQuery(String key, String[] fields) {  
    334.         return getWildcardQuery(key, fields, Occur.SHOULD);  
    335.     }  
    336.       
    337.     /** 
    338.      * @param keyStart 
    339.      * @param keyEnd 
    340.      * @param field 
    341.      * @param includeStart 
    342.      * @param includeEnd 
    343.      * @return 
    344.      * @Author:lulei   
    345.      * @Description: 范围搜索 
    346.      */  
    347.     public Query getRangeQuery (String keyStart, String keyEnd, String field, boolean includeStart, boolean includeEnd) {  
    348.         return TermRangeQuery.newStringRange(field, keyStart, keyEnd, includeStart, includeEnd);  
    349.     }  
    350.       
    351.     /** 
    352.      * @param min 
    353.      * @param max 
    354.      * @param field 
    355.      * @param includeMin 
    356.      * @param includeMax 
    357.      * @return 
    358.      * @Author:lulei   
    359.      * @Description: 范围搜索 
    360.      */  
    361.     public Query getRangeQuery (int min, int max, String field, boolean includeMin, boolean includeMax) {  
    362.         return NumericRangeQuery.newIntRange(field, min, max, includeMin, includeMax);  
    363.     }  
    364.       
    365.     /** 
    366.      * @param min 
    367.      * @param max 
    368.      * @param field 
    369.      * @param includeMin 
    370.      * @param includeMax 
    371.      * @return 
    372.      * @Author:lulei   
    373.      * @Description: 范围搜索 
    374.      */  
    375.     public Query getRangeQuery (float min, float max, String field, boolean includeMin, boolean includeMax) {  
    376.         return NumericRangeQuery.newFloatRange(field, min, max, includeMin, includeMax);  
    377.     }  
    378.       
    379.     /** 
    380.      * @param min 
    381.      * @param max 
    382.      * @param field 
    383.      * @param includeMin 
    384.      * @param includeMax 
    385.      * @return 
    386.      * @Author:lulei   
    387.      * @Description: 范围搜索 
    388.      */  
    389.     public Query getRangeQuery (double min, double max, String field, boolean includeMin, boolean includeMax) {  
    390.         return NumericRangeQuery.newDoubleRange(field, min, max, includeMin, includeMax);  
    391.     }  
    392.       
    393.     public static void main(String[] args) throws IOException {  
    394.     }  
    395. }  

          PackQuery类的构造方法,可以手动指定分词器也可以使用索引的分词器。个人建议,在项目中使用索引中的分词器,这样就不会因为分词器的不同造成不知名的错误。


    ----------------------------------------------------------------------------------------------------

    ps:最近发现其他网站可能会对博客转载,上面并没有源链接,如想查看更多关于 基于lucene的案例开发点击这里。或访问网址http://blog.csdn.net/xiaojimanman/article/category/2841877

  • 相关阅读:
    [翻译]关于堆和堆栈
    sql 字符+数值 混合排序 lcs
    证明DataReader分页的可行性 lcs
    谈谈我对小公司、大公司及个人成长的见解 lcs
    sina 通用js代码说明 lcs
    Linux系统下生成证书 https证书
    【转】51单片机外部中断的C51编程
    【转】如何建立个人网站
    【转】关于C51的中断编程[原创]
    【转】毫不费力:破解加密PDF文档就使用这两三招
  • 原文地址:https://www.cnblogs.com/jiangyang/p/4643032.html
Copyright © 2011-2022 走看看