你的位置:首页 > Java教程

[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 

view plaincopy to clipboardprint?

  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