Hbase使用filter快速高效查询

 

  1. 本博客是hbase使用filter快速高效查询的方法,我会慢慢补齐  

几大Filters
1、Comparision Filters
     1.1  RowFilter
1.2 FamilyFilter
     1.3 QualifierFilter
     1.4 ValueFilter
     1.5 DependentColumnFilter
2、Dedicated Filters
     2.1 SingleColumnValueFilter
     2.2 SingleColumnValueExcludeFilter
     2.3 PrefixFilter
     2.4 PageFilter
     2.5 KeyOnlyFilter
     2.6 FirstKeyOnlyFilter
     2.7 TimestampsFilter
     2.8 RandomRowFilter
3、Decorating Filters
     3.1  SkipFilter
     3.2 WhileMatchFilters

 

一个简单的示例 SingleColumnValueFilter

 

[java] view plain copy
  1.   public   static   void  selectByFilter(String tablename,List<String> arr)  throws  IOException{    
  2.         HTable table=new  HTable(hbaseConfig,tablename);    
  3.         FilterList filterList = new  FilterList();    
  4.         Scan s1 = new  Scan();    
  5.         for (String v:arr){  // 各个条件之间是“与”的关系     
  6.             String [] s=v.split("," );    
  7.             filterList.addFilter(new  SingleColumnValueFilter(Bytes.toBytes(s[ 0 ]),    
  8.                                                              Bytes.toBytes(s[1 ]),    
  9.                                                              CompareOp.EQUAL,Bytes.toBytes(s[2 ])    
  10.                                                              )    
  11.             );    
  12.             // 添加下面这一行后,则只返回指定的cell,同一行中的其他cell不返回     
  13. //          s1.addColumn(Bytes.toBytes(s[0]), Bytes.toBytes(s[1]));     
  14.         }    
  15.         s1.setFilter(filterList);    
  16.         ResultScanner ResultScannerFilterList = table.getScanner(s1);    
  17.         for (Result rr=ResultScannerFilterList.next();rr!= null ;rr=ResultScannerFilterList.next()){    
  18.             for (KeyValue kv:rr.list()){    
  19.                 System.out.println("row : " + new  String(kv.getRow()));    
  20.                 System.out.println("column : " + new  String(kv.getColumn()));    
  21.                 System.out.println("value : " + new  String(kv.getValue()));    
  22.             }    
  23.         }    
  24.     }    


MultipleColumnPrefixFilter

api上介绍如下

[html] view plain copy
  1. This filter is used for selecting only those keys with columns that matches a particular prefix. For example, if prefix is 'an', it will pass keys will columns like 'and', 'anti' but not keys with columns like 'ball', 'act'.   

构造方法如下

[html] view plain copy
  1. public MultipleColumnPrefixFilter(byte[][] prefixes)  

传入多个prefix
源码里说明如下

[html] view plain copy
  1. public MultipleColumnPrefixFilter(final byte [][] prefixes) {  
  2.      if (prefixes != null) {  
  3.        for (int i  =  0 ; i  <   prefixes.length ; i++) {  
  4.          if (!sortedPrefixes.add(prefixes[i]))  
  5.            throw new IllegalArgumentException ("prefixes must be distinct");  
  6.        }  
  7.      }  
  8.    }  

示例代码如下:是我从网上找的,看了,没啥难理解的,

[html] view plain copy
  1. +public class TestMultipleColumnPrefixFilter {  
  2. +  
  3. +  private final static HBaseTestingUtility TEST_UTIL  =  new   
  4. +      HBaseTestingUtility();  
  5. +  
  6. +  @Test  
  7. +  public void testMultipleColumnPrefixFilter() throws IOException {  
  8. +    String family  =  "Family" ;  
  9. +    HTableDescriptor htd  =  new  HTableDescriptor("TestMultipleColumnPrefixFilter");  
  10. +    htd.addFamily(new HColumnDescriptor(family));  
  11. +    // HRegionInfo info  =  new  HRegionInfo(htd, null, null, false);  
  12. +    HRegionInfo info  =  new  HRegionInfo(htd.getName(), null, null, false);  
  13. +    HRegion region  =  HRegion .createHRegion(info, HBaseTestingUtility.  
  14. +        getTestDir(), TEST_UTIL.getConfiguration(), htd);  
  15. +  
  16. +    List< String >   rows  =  generateRandomWords (100, "row");  
  17. +    List< String >   columns  =  generateRandomWords (10000, "column");  
  18. +    long maxTimestamp  =  2 ;  
  19. +  
  20. +    List< KeyValue >   kvList  =  new  ArrayList < KeyValue > ();  
  21. +  
  22. +    Map< String , List < KeyValue > >   prefixMap  =  new  HashMap < String ,  
  23. +        List< KeyValue > > ();  
  24. +  
  25. +    prefixMap.put("p", new ArrayList< KeyValue > ());  
  26. +    prefixMap.put("q", new ArrayList< KeyValue > ());  
  27. +    prefixMap.put("s", new ArrayList< KeyValue > ());  
  28. +  
  29. +    String valueString  =  "ValueString" ;  
  30. +  
  31. +    for (String row: rows) {  
  32. +      Put p  =  new  Put(Bytes.toBytes(row));  
  33. +      for (String column: columns) {  
  34. +        for (long timestamp  =  1 ; timestamp  < = maxTimestamp; timestamp++) {  
  35. +          KeyValue kv  =  KeyValueTestUtil .create(row, family, column, timestamp,  
  36. +              valueString);  
  37. +          p.add(kv);  
  38. +          kvList.add(kv);  
  39. +          for (String s: prefixMap.keySet()) {  
  40. +            if (column.startsWith(s)) {  
  41. +              prefixMap.get(s).add(kv);  
  42. +            }  
  43. +          }  
  44. +        }  
  45. +      }  
  46. +      region.put(p);  
  47. +    }  
  48. +  
  49. +    MultipleColumnPrefixFilter filter;  
  50. +    Scan scan  =  new  Scan();  
  51. +    scan.setMaxVersions();  
  52. +    byte [][] filter_prefix  =  new  byte [2][];  
  53. +    filter_prefix[0] = new byte [] {'p'};  
  54. +    filter_prefix[1] = new byte [] {'q'};  
  55. +      
  56. +    filter  =  new  MultipleColumnPrefixFilter(filter_prefix);  
  57. +    scan.setFilter(filter);  
  58. +    List< KeyValue >   results  =  new  ArrayList < KeyValue > ();    
  59. +    InternalScanner scanner  =  region .getScanner(scan);  
  60. +    while(scanner.next(results));  
  61. +    assertEquals(prefixMap.get("p").size() + prefixMap.get("q").size(), results.size());  
  62. +  }  
  63. +  
  64. +  @Test  
  65. +  public void testMultipleColumnPrefixFilterWithManyFamilies() throws IOException {  
  66. +    String family1  =  "Family1" ;  
  67. +    String family2  =  "Family2" ;  
  68. +    HTableDescriptor htd  =  new  HTableDescriptor("TestMultipleColumnPrefixFilter");  
  69. +    htd.addFamily(new HColumnDescriptor(family1));  
  70. +    htd.addFamily(new HColumnDescriptor(family2));  
  71. +    HRegionInfo info  =  new  HRegionInfo(htd.getName(), null, null, false);  
  72. +    HRegion region  =  HRegion .createHRegion(info, HBaseTestingUtility.  
  73. +        getTestDir(), TEST_UTIL.getConfiguration(), htd);  
  74. +  
  75. +    List< String >   rows  =  generateRandomWords (100, "row");  
  76. +    List< String >   columns  =  generateRandomWords (10000, "column");  
  77. +    long maxTimestamp  =  3 ;  
  78. +  
  79. +    List< KeyValue >   kvList  =  new  ArrayList < KeyValue > ();  
  80. +  
  81. +    Map< String , List < KeyValue > >   prefixMap  =  new  HashMap < String ,  
  82. +        List< KeyValue > > ();  
  83. +  
  84. +    prefixMap.put("p", new ArrayList< KeyValue > ());  
  85. +    prefixMap.put("q", new ArrayList< KeyValue > ());  
  86. +    prefixMap.put("s", new ArrayList< KeyValue > ());  
  87. +  
  88. +    String valueString  =  "ValueString" ;  
  89. +  
  90. +    for (String row: rows) {  
  91. +      Put p  =  new  Put(Bytes.toBytes(row));  
  92. +      for (String column: columns) {  
  93. +        for (long timestamp  =  1 ; timestamp  < = maxTimestamp; timestamp++) {  
  94. +          double rand  =  Math .random();  
  95. +          KeyValue kv;  
  96. +          if (rand <   0.5 )   
  97. +            kv  =  KeyValueTestUtil .create(row, family1, column, timestamp,  
  98. +                valueString);  
  99. +          else   
  100. +            kv  =  KeyValueTestUtil .create(row, family2, column, timestamp,  
  101. +                valueString);  
  102. +          p.add(kv);  
  103. +          kvList.add(kv);  
  104. +          for (String s: prefixMap.keySet()) {  
  105. +            if (column.startsWith(s)) {  
  106. +              prefixMap.get(s).add(kv);  
  107. +            }  
  108. +          }  
  109. +        }  
  110. +      }  
  111. +      region.put(p);  
  112. +    }  
  113. +  
  114. +    MultipleColumnPrefixFilter filter;  
  115. +    Scan scan  =  new  Scan();  
  116. +    scan.setMaxVersions();  
  117. +    byte [][] filter_prefix  =  new  byte [2][];  
  118. +    filter_prefix[0] = new byte [] {'p'};  
  119. +    filter_prefix[1] = new byte [] {'q'};  
  120. +      
  121. +    filter  =  new  MultipleColumnPrefixFilter(filter_prefix);  
  122. +    scan.setFilter(filter);  
  123. +    List< KeyValue >   results  =  new  ArrayList < KeyValue > ();    
  124. +    InternalScanner scanner  =  region .getScanner(scan);  
  125. +    while(scanner.next(results));  
  126. +    assertEquals(prefixMap.get("p").size() + prefixMap.get("q").size(), results.size());  
  127. +  }  
  128. +    
  129. +  @Test  
  130. +  public void testMultipleColumnPrefixFilterWithColumnPrefixFilter() throws IOException {  
  131. +    String family  =  "Family" ;  
  132. +    HTableDescriptor htd  =  new  HTableDescriptor("TestMultipleColumnPrefixFilter");  
  133. +    htd.addFamily(new HColumnDescriptor(family));  
  134. +    HRegionInfo info  =  new  HRegionInfo(htd.getName(), null, null, false);  
  135. +    HRegion region  =  HRegion .createHRegion(info, HBaseTestingUtility.  
  136. +        getTestDir(), TEST_UTIL.getConfiguration(),htd);  
  137. +  
  138. +    List< String >   rows  =  generateRandomWords (100, "row");  
  139. +    List< String >   columns  =  generateRandomWords (10000, "column");  
  140. +    long maxTimestamp  =  2 ;  
  141. +  
  142. +    String valueString  =  "ValueString" ;  
  143. +  
  144. +    for (String row: rows) {  
  145. +      Put p  =  new  Put(Bytes.toBytes(row));  
  146. +      for (String column: columns) {  
  147. +        for (long timestamp  =  1 ; timestamp  < = maxTimestamp; timestamp++) {  
  148. +          KeyValue kv  =  KeyValueTestUtil .create(row, family, column, timestamp,  
  149. +              valueString);  
  150. +          p.add(kv);  
  151. +        }  
  152. +      }  
  153. +      region.put(p);  
  154. +    }  
  155. +  
  156. +    MultipleColumnPrefixFilter multiplePrefixFilter;  
  157. +    Scan scan1  =  new  Scan();  
  158. +    scan1.setMaxVersions();  
  159. +    byte [][] filter_prefix  =  new  byte [1][];  
  160. +    filter_prefix[0] = new byte [] {'p'};  
  161. +   
  162. +    multiplePrefixFilter  =  new  MultipleColumnPrefixFilter(filter_prefix);  
  163. +    scan1.setFilter(multiplePrefixFilter);  
  164. +    List< KeyValue >   results1  =  new  ArrayList < KeyValue > ();    
  165. +    InternalScanner scanner1  =  region .getScanner(scan1);  
  166. +    while(scanner1.next(results1));  
  167. +      
  168. +    ColumnPrefixFilter singlePrefixFilter;  
  169. +    Scan scan2  =  new  Scan();  
  170. +    scan2.setMaxVersions();  
  171. +    singlePrefixFilter  =  new  ColumnPrefixFilter(Bytes.toBytes("p"));  
  172. +   
  173. +    scan2.setFilter(singlePrefixFilter);  
  174. +    List< KeyValue >   results2  =  new  ArrayList < KeyValue > ();    
  175. +    InternalScanner scanner2  =  region .getScanner(scan1);  
  176. +    while(scanner2.next(results2));  
  177. +      
  178. +    assertEquals(results1.size(), results2.size());  
  179. +  }  
  180. +    
  181. +  List< String >  generateRandomWords(int numberOfWords, String suffix) {  
  182. +    Set< String >   wordSet  =  new  HashSet < String > ();  
  183. +    for (int i  =  0 ; i  <   numberOfWords ; i++) {  
  184. +      int lengthOfWords  = (int) (Math.random()*2) + 1;  
  185. +      char[] wordChar  =  new  char[lengthOfWords];  
  186. +      for (int j  =  0 ; j  <   wordChar.length ; j++) {  
  187. +        wordChar[j] = (char) (Math.random() * 26 + 97);  
  188. +      }  
  189. +      String word;  
  190. +      if (suffix  == null) {  
  191. +        word  =  new  String(wordChar);  
  192. +      } else {  
  193. +        word  =  new  String(wordChar) + suffix;  
  194. +      }  
  195. +      wordSet.add(word);  
  196. +    }  
  197. +    List< String >   wordList  =  new  ArrayList < String > (wordSet);  
  198. +    return wordList;  
  199. +  }  
  200. +}  
  201. +  
  202. .  


ColumnPrefixFilter

[html] view plain copy
  1. public class ColumnPrefixFilterextends FilterBaseThis filter is used for selecting only those keys with columns that matches a particular prefix. For example, if prefix is 'an', it will pass keys will columns like 'and', 'anti' but not keys with columns like 'ball', 'act'.   

上面是类的说明
只有一个有参构造 ColumnPrefixFilter (byte[] prefix)
这个类用法很简单,就是匹配前缀是prefix的rowkey,但是,不知道大家用了之后有什么感觉,我是用了,但是不起作用,有起作用的大牛告诉我下。

无奈之下,只好选择PrefixFilter

PrefixFilter

类说明 :

Pass results that have same row prefix.

同样的构造方法,跟ColumnPrefixFilter一模一样,用法也相同,

基本上几个Filter就是这些了,慢慢的我再更新这个文章

上段代码,我自己写的,使用中的代码

[java] view plain copy
  1. public   static  String getKeywordTableRowkeyUseFilter(String filterString1,String filterString2) {  
  2.     FilterList filterList = new  FilterList();  
  3.     String rowkeyValue = ""  ;  
  4.     Scan s1 = new  Scan();  
  5.         String [] sf1=filterString1.split("," );  
  6.         filterList.addFilter(new  SingleColumnValueFilter(Bytes.toBytes(sf1[ 0 ]),  
  7.                                                          Bytes.toBytes(sf1[1 ]),  
  8.                                                          CompareOp.EQUAL,Bytes.toBytes(sf1[2 ])  
  9.                                                          ));  
  10.         String [] sf2=filterString2.split("," );  
  11.         filterList.addFilter(new  SingleColumnValueFilter(Bytes.toBytes(sf2[ 0 ]),  
  12.                    Bytes.toBytes(sf2[1 ]),  
  13.                    CompareOp.EQUAL,Bytes.toBytes(sf2[2 ])  
  14.                    ));  
  15.         filterList.addFilter(new  ColumnPrefixFilter(Bytes.toBytes( "3274980668:" ))) ;  
  16.         filterList.addFilter(new  PrefixFilter(Bytes.toBytes( "3274980668:" ))) ;  
  17.   
  18.     s1.setFilter(filterList);  
  19.     ResultScanner ResultScannerFilterList;  
  20.     try  {  
  21.         ResultScannerFilterList = tableKeyword.getScanner(s1);  
  22.         for (Result rr=ResultScannerFilterList.next();rr!= null ;rr=ResultScannerFilterList.next()){  
  23.             String rowkeyValueTmp  = new  String(rr.getRow()) ;  
  24.               
  25.             rowkeyValue = rowkeyValue + "##"  + rowkeyValueTmp ;  
  26.               
  27.         }  
  28.     } catch  (IOException e) {  
  29.         // TODO Auto-generated catch block   
  30.         e.printStackTrace();  
  31.     }  
  32.     log.warn("rowkeyValue"  + rowkeyValue) ;  
  33.     return  rowkeyValue ;  
  34. }  


PrefixFilter和ColumnPrefixFilter的用法几乎一样,但是在开发中,建议使用PrefixFilter

你可能感兴趣的:(filter)