base过滤器的比较操作符:
LESS <
LESS_OR_EQUAL <=
EQUAL =
NOT_EQUAL <>
GREATER_OR_EQUAL >=
GREATER >
NO_OP no operation
比较器:
BinaryComparator 按字节索引顺序比较指定字节数组,采用Bytes.compareTo(byte[])
BinaryPrefixComparator 跟前面相同,只是比较左端的数据是否相同
NullComparator 判断给定的是否为空
BitComparator 按位比较 a BitwiseOp class 做异或,与,并操作
RegexStringComparator 提供一个正则的比较器,仅支持 EQUAL 和非EQUAL
SubstringComparator 判断提供的子串是否出现在table的value中。
比较过滤器
1、Comparision Filters
1.1 RowFilter
构造函数
1. public RowFilter(org.apache.hadoop.hbase.filter.CompareFilter.CompareOp rowCompareOp, org.apache.hadoop.hbase.filter.WritableByteArrayComparable rowComparator) {}
1. public class RowFilterExample {
2.
3. public static void main(String[] args) throws IOException {
4. Configuration conf = HBaseConfiguration.create();
5.
6. HBaseHelper helper = HBaseHelper.getHelper(conf);
7. "testtable");
8. "testtable", "colfam1", "colfam2");
9. "Adding rows to table...");
10. "testtable", 1, 100, 100, "colfam1", "colfam2");
11.
12. new HTable(conf, "testtable");
13.
14. // vv RowFilterExample
15. new Scan();
16. "colfam1"), Bytes.toBytes("col-0"));
17.
18. new RowFilter(CompareFilter.CompareOp.LESS_OR_EQUAL, // co RowFilterExample-1-Filter1 Create filter, while specifying the comparison operator and comparator. Here an exact match is needed.
19. new BinaryComparator(Bytes.toBytes("row-22")));
20. scan.setFilter(filter1);
21. ResultScanner scanner1 = table.getScanner(scan);
22. // ^^ RowFilterExample
23. "Scanning table #1...");
24. // vv RowFilterExample
25. for (Result res : scanner1) {
26. System.out.println(res);
27. }
28. scanner1.close();
29.
30. new RowFilter(CompareFilter.CompareOp.EQUAL, // co RowFilterExample-2-Filter2 Another filter, this time using a regular expression to match the row keys.
31. new RegexStringComparator(".*-.5"));
32. scan.setFilter(filter2);
33. ResultScanner scanner2 = table.getScanner(scan);
34. // ^^ RowFilterExample
35. "Scanning table #2...");
36. // vv RowFilterExample
37. for (Result res : scanner2) {
38. System.out.println(res);
39. }
40. scanner2.close();
41.
42. new RowFilter(CompareFilter.CompareOp.EQUAL, // co RowFilterExample-3-Filter3 The third filter uses a substring match approach.
43. new SubstringComparator("-5"));
44. scan.setFilter(filter3);
45. ResultScanner scanner3 = table.getScanner(scan);
46. // ^^ RowFilterExample
47. "Scanning table #3...");
48. // vv RowFilterExample
49. for (Result res : scanner3) {
50. System.out.println(res);
51. }
52. scanner3.close();
53. // ^^ RowFilterExample
54. }
55. }
构造函数
1. public FamilyFilter(CompareOp familyCompareOp, WritableByteArrayComparable familyComparator) {}
通过和列簇比较得到,返回结果为真的数据,示例:
1. public class FamilyFilterExample {
2.
3. public static void main(String[] args) throws IOException {
4. Configuration conf = HBaseConfiguration.create();
5.
6. HBaseHelper helper = HBaseHelper.getHelper(conf);
7. "testtable");
8. "testtable", "colfam1", "colfam2", "colfam3", "colfam4");
9. "Adding rows to table...");
10. "testtable", 1, 10, 2, "colfam1", "colfam2", "colfam3", "colfam4");
11.
12. new HTable(conf, "testtable");
13.
14. // vv FamilyFilterExample
15. new FamilyFilter(CompareFilter.CompareOp.LESS, // co FamilyFilterExample-1-Filter Create filter, while specifying the comparison operator and comparator.
16. new BinaryComparator(Bytes.toBytes("colfam3")));
17.
18. new Scan();
19. scan.setFilter(filter1);
20. // co FamilyFilterExample-2-Scan Scan over table while applying the filter.
21. // ^^ FamilyFilterExample
22. "Scanning table... ");
23. // vv FamilyFilterExample
24. for (Result result : scanner) {
25. System.out.println(result);
26. }
27. scanner.close();
28.
29. new Get(Bytes.toBytes("row-5"));
30. get1.setFilter(filter1);
31. // co FamilyFilterExample-3-Get Get a row while applying the same filter.
32. "Result of get(): " + result1);
33.
34. new FamilyFilter(CompareFilter.CompareOp.EQUAL,
35. new BinaryComparator(Bytes.toBytes("colfam3")));
36. new Get(Bytes.toBytes("row-5")); // co FamilyFilterExample-4-Mismatch Create a filter on one column family while trying to retrieve another.
37. "colfam1"));
38. get2.setFilter(filter2);
39. // co FamilyFilterExample-5-Get2 Get the same row while applying the new filter, this will return "NONE".
40. "Result of get(): " + result2);
41. // ^^ FamilyFilterExample
42. }
43. }
1.3 QualifierFilter
构造函数
1. public QualifierFilter(CompareOp qualifierCompareOp, WritableByteArrayComparable qualifierComparator) { }
1. // vv QualifierFilterExample
2. new QualifierFilter(CompareFilter.CompareOp.LESS_OR_EQUAL,
3. new BinaryComparator(Bytes.toBytes("col-2")));
4.
5. new Scan();
6. scan.setFilter(filter);
7. ResultScanner scanner = table.getScanner(scan);
8. // ^^ QualifierFilterExample
9. "Scanning table... ");
10. // vv QualifierFilterExample
11. for (Result result : scanner) {
12. System.out.println(result);
13. }
14. scanner.close();
15.
16. new Get(Bytes.toBytes("row-5"));
17. get.setFilter(filter);
18. Result result = table.get(get);
19. "Result of get(): " + result);
构造函数
1. <pre name="code" class="java" style="color: rgb(88, 89, 93); font-size: 14px; line-
1. height: 25px;">public ValueFilter(CompareOp valueCompareOp, WritableByteArrayComparable valueComparator) {}</pre>
2. <pre></pre>
3. 通过和列名比较,返回为真的数据,示例:
4. <pre></pre>
5. <pre></pre>
6. <pre></pre>
7. <pre></pre>
1. Filter filter = new ValueFilter(CompareFilter.CompareOp.EQUAL, // co ValueFilterExample-1-Filter Create filter, while specifying the comparison operator and comparator.
2. new SubstringComparator(".4") );
3.
4. new Scan();
5. // co ValueFilterExample-2-SetFilter Set filter for the scan.
6. ResultScanner scanner = table.getScanner(scan);
7. // ^^ ValueFilterExample
8. "Results of scan:");
9. // vv ValueFilterExample
10. for (Result result : scanner) {
11. for (KeyValue kv : result.raw()) {
12. "KV: " + kv + ", Value: " + // co ValueFilterExample-3-Print1 Print out value to check that filter works.
13. Bytes.toString(kv.getValue()));
14. }
15. }
16. scanner.close();
17.
18. new Get(Bytes.toBytes("row-5"));
19. // co ValueFilterExample-4-SetFilter2 Assign same filter to Get instance.
20. Result result = table.get(get);
21. // ^^ ValueFilterExample
22. "Result of get: ");
23. // vv ValueFilterExample
24. for (KeyValue kv : result.raw()) {
25. "KV: " + kv + ", Value: " +
26. Bytes.toString(kv.getValue()));
27. }
1.5 DependentColumnFilter
该过滤器有两个参数 —— 列族和列修饰。 尝试找到该列所在的每一行,并返回该行具有相同时间戳的全部键值对。如果某一行不包含指定的列,则该行的任何键值对都不返回。
该过滤器还可以有一个可选布尔参数 —— dropDependentColumn. 如果为true, 从属的列不返回。
该过滤器还可以有两个可选参数 —— 一个比较操作符和一个值比较器,用于列族和修饰的进一步检查。如果从属的列找到,其值还必须通过值检查,然后就是时间戳必须考虑。
1. package filters;
2.
3. // cc DependentColumnFilterExample Example using a filter to include only specific column families
4. import org.apache.hadoop.conf.Configuration;
5. import org.apache.hadoop.hbase.HBaseConfiguration;
6. import org.apache.hadoop.hbase.KeyValue;
7. import org.apache.hadoop.hbase.client.Get;
8. import org.apache.hadoop.hbase.client.HTable;
9. import org.apache.hadoop.hbase.client.Result;
10. import org.apache.hadoop.hbase.client.ResultScanner;
11. import org.apache.hadoop.hbase.client.Scan;
12. import org.apache.hadoop.hbase.filter.BinaryPrefixComparator;
13. import org.apache.hadoop.hbase.filter.CompareFilter;
14. import org.apache.hadoop.hbase.filter.DependentColumnFilter;
15. import org.apache.hadoop.hbase.filter.Filter;
16. import org.apache.hadoop.hbase.filter.RegexStringComparator;
17. import org.apache.hadoop.hbase.filter.WritableByteArrayComparable;
18. import org.apache.hadoop.hbase.util.Bytes;
19. import util.HBaseHelper;
20.
21. import java.io.IOException;
22.
23. public class DependentColumnFilterExample {
24.
25. private static HTable table = null;
26.
27. // vv DependentColumnFilterExample
28. private static void filter(boolean drop,
29. CompareFilter.CompareOp operator,
30. WritableByteArrayComparable comparator)
31. throws IOException {
32. Filter filter;
33. if (comparator != null) {
34. new DependentColumnFilter(Bytes.toBytes("colfam1"), // co DependentColumnFilterExample-1-CreateFilter Create the filter with various options.
35. "col-5"), drop, operator, comparator);
36. else {
37. new DependentColumnFilter(Bytes.toBytes("colfam1"),
38. "col-5"), drop);
39.
40. }
41.
42. new Scan();
43. scan.setFilter(filter);
44. ResultScanner scanner = table.getScanner(scan);
45. // ^^ DependentColumnFilterExample
46. "Results of scan:");
47. // vv DependentColumnFilterExample
48. for (Result result : scanner) {
49. for (KeyValue kv : result.raw()) {
50. "KV: " + kv + ", Value: " +
51. Bytes.toString(kv.getValue()));
52. }
53. }
54. scanner.close();
55.
56. new Get(Bytes.toBytes("row-5"));
57. get.setFilter(filter);
58. Result result = table.get(get);
59. // ^^ DependentColumnFilterExample
60. "Result of get: ");
61. // vv DependentColumnFilterExample
62. for (KeyValue kv : result.raw()) {
63. "KV: " + kv + ", Value: " +
64. Bytes.toString(kv.getValue()));
65. }
66. // ^^ DependentColumnFilterExample
67. "");
68. // vv DependentColumnFilterExample
69. }
70.
71. public static void main(String[] args) throws IOException {
72. // ^^ DependentColumnFilterExample
73. Configuration conf = HBaseConfiguration.create();
74.
75. HBaseHelper helper = HBaseHelper.getHelper(conf);
76. "testtable");
77. "testtable", "colfam1", "colfam2");
78. "Adding rows to table...");
79. "testtable", 1, 10, 10, true, "colfam1", "colfam2");
80.
81. new HTable(conf, "testtable");
82.
83. // vv DependentColumnFilterExample
84. true, CompareFilter.CompareOp.NO_OP, null);
85. false, CompareFilter.CompareOp.NO_OP, null); // co DependentColumnFilterExample-2-Filter Call filter method with various options.
86. true, CompareFilter.CompareOp.EQUAL,
87. new BinaryPrefixComparator(Bytes.toBytes("val-5")));
88. false, CompareFilter.CompareOp.EQUAL,
89. new BinaryPrefixComparator(Bytes.toBytes("val-5")));
90. true, CompareFilter.CompareOp.EQUAL,
91. new RegexStringComparator(".*\\.5"));
92. false, CompareFilter.CompareOp.EQUAL,
93. new RegexStringComparator(".*\\.5"));
94. }
95. // ^^ DependentColumnFilterExample}
2.1 SingleColumnValueFilter
选定列簇和某一列,然后与列的value相比,正确的返回全部的row,注意如果某一行不含有该列,同样返回,除非通过filterIfColumnMissing 设置成真。
构造函数
1. <pre name="code" class="java">SingleColumnValueFilter(byte[] family, byte[] qualifier, CompareOp compareOp, byte[] value)
2. SingleColumnValueFilter(byte[] family, byte[] qualifier, CompareOp compareOp, WritableByteArrayComparable comparator)</pre>
3. <pre></pre>
4. 第一个构造函数相当于构建了一个BinaryComparator的实例。其他的跟CompareFilter的参数含义一样。
5. <pre></pre>
6. <pre></pre>
7. <pre></pre>
该过滤器通过下面两个参数 filterIfMissing,latestVersionOnly
1. boolean getFilterIfMissing()
2. void setFilterIfMissing(boolean filterIfMissing)
3. boolean getLatestVersionOnly()
4. void setLatestVersionOnly(boolean latestVersionOnly)
如果 filterIfColumnMissing 标志设为真,如果该行没有指定的列,那么该行的所有列将不发出。缺省值为假。
如果setLatestVersionOnly 标志设为假,将检查此前的版本。缺省值为真。实例如下:
1. // vv SingleColumnValueFilterExample
2. new SingleColumnValueFilter(
3. "colfam1"),
4. "col-5"),
5. CompareFilter.CompareOp.NOT_EQUAL,
6. new SubstringComparator("val-5"));
7. true);
8.
9. new Scan();
10. scan.setFilter(filter);
11. ResultScanner scanner = table.getScanner(scan);
12. // ^^ SingleColumnValueFilterExample
13. "Results of scan:");
14. // vv SingleColumnValueFilterExample
15. for (Result result : scanner) {
16. for (KeyValue kv : result.raw()) {
17. "KV: " + kv + ", Value: " +
18. Bytes.toString(kv.getValue()));
19. }
20. }
21. scanner.close();
22.
23. new Get(Bytes.toBytes("row-6"));
24. get.setFilter(filter);
25. Result result = table.get(get);
26. "Result of get: ");
27. for (KeyValue kv : result.raw()) {
28. "KV: " + kv + ", Value: " +
29. Bytes.toString(kv.getValue()));
30. }
2.2 SingleColumnValueExcludeFilter
该过滤器同上面的过滤器正好相反,如果条件相符,将不会返回该列的内容。
2.3 PrefixFilter
所有的row的实例匹配prefix的时候返回结果集合
1. Filter filter = new PrefixFilter(Bytes.toBytes("row1"));
2. Scan scan = new Scan();
3. scan.setFilter(filter);
4. ResultScanner scanner = table.getScanner(scan);
5.
6.
7. for(Result result: scanner){
8. for(KeyValue kv: result.raw()) {
9. "KV:" + kv + ", Value:" + Bytes.toString(kv.getValue()));
10. }
11. }
12. scanner.close();
13.
14.
15. Get get = new Get(Bytes.toBytes("row-5"));
16. get.setFilter(filter);
17. Result result = table.get(get);
18. for(KeyValue kv : result.raw()){
19. "KV:" + kv + ", Value:" + Bytes.toString(kv.getValue()));
20. }
页过滤,通过设置pagesize参数可以返回每一页page的数量。
客户端需要记住上一次访问的row的key值。
1. package hbaseTest;
2.
3. import org.apache.hadoop.conf.Configuration;
4. import org.apache.hadoop.hbase.HBaseConfiguration;
5. import org.apache.hadoop.hbase.client.HTable;
6. import org.apache.hadoop.hbase.client.Result;
7. import org.apache.hadoop.hbase.client.ResultScanner;
8. import org.apache.hadoop.hbase.client.Scan;
9. import org.apache.hadoop.hbase.filter.Filter;
10. import org.apache.hadoop.hbase.filter.PageFilter;
11. import org.apache.hadoop.hbase.util.Bytes;
12.
13. import java.io.IOException;
14.
15. /**
16. * Hello world!
17. */
18. public class PageFilterExample {
19. public static void main(String[] args) throws IOException {
20. Configuration config = HBaseConfiguration.create();
21. "hbase.zookeeper.quorum", "QT-H-0038");
22.
23. "testTable";
24. "colfam1";
25. final byte[] POSTFIX = new byte[] { 0x00 };
26. new HTable(config, tableName);
27. new PageFilter(15);
28. byte[] lastRow = null;
29. int totalRows = 0;
30. while (true) {
31. new Scan();
32. scan.setFilter(filter);
33. if(lastRow != null){
34. //注意这里添加了POSTFIX操作,不然死循环了
35. byte[] startRow = Bytes.add(lastRow,POSTFIX);
36. scan.setStartRow(startRow);
37. }
38. ResultScanner scanner = table.getScanner(scan);
39. int localRows = 0;
40. Result result;
41. while((result = scanner.next()) != null){
42. ":" + result);
43. totalRows ++;
44. lastRow = result.getRow();
45. }
46. scanner.close();
47. if(localRows == 0) break;
48. }
49. "total rows:" + totalRows);
50. }
51.
52. }
因为一些应用只想获取data数据,而不是真实的val,可以使用这个过滤器。该过滤器通过
1. KeyOnlyFilter(boolean lenAsVal)
1. final byte[] POSTFIX = new byte[] { 0x00 };
2. new HTable(config, tableName);
3. new KeyOnlyFilter(false);
4. byte[] lastRow = null;
5. int totalRows = 0;
6.
7.
8. new Scan();
9. scan.setFilter(filter);
10. ResultScanner scanner = table.getScanner(scan);
11. for(Result result: scanner){
12. for(KeyValue kv: result.raw()){
13. ":" + Bytes.toString(kv.getValue()));
14. }
15. }
在对hbase的表进行扫描的时候,如果指定了FirstKeyOnlyFilter过滤条件则仅仅会返回相同key的第一条kv。
当对hbase中的表进行count,sum操作等集合操作的时候,使用FirstKeyOnlyFilter会带来性能上的提升。
1. public class KeyOnlyFilterExample {
2. public static void main(String[] args) throws IOException {
3. Configuration config = HBaseConfiguration.create();
4. "hbase.zookeeper.quorum", "QT-H-0038");
5.
6. "testTable";
7. "colfam1";
8. final byte[] POSTFIX = new byte[] { 0x00 };
9. new HTable(config, tableName);
10. new FirstKeyOnlyFilter();
11. byte[] lastRow = null;
12. int totalRows = 0;
13.
14. new Scan();
15. scan.setFilter(filter);
16. ResultScanner scanner = table.getScanner(scan);
17. for(Result result: scanner){
18. for(KeyValue kv: result.raw()){
19. ":" + Bytes.toString(kv.getValue()));
20. }
21. }
22. }
23. }
1. row-5/colfam1:qual1/1354673733503/Put/vlen=4:row1
2. row1/colfam1:qual1/1354432930568/Put/vlen=4:val1
3. row2/colfam1:qual2/1354432930568/Put/vlen=4:val3
如果注释掉过滤器的返回的结果是:
1. row-5/colfam1:qual1/1354673733503/Put/vlen=4:row1
2. row1/colfam1:qual1/1354432930568/Put/vlen=4:val1
3. row1/colfam1:qual2/1354435819120/Put/vlen=4:val2
4. row2/colfam1:qual2/1354432930568/Put/vlen=4:val3
2.7 InclusiveStopFilter
因为hbase的scan包含start-row不包含stop-row 如果使用这个过滤器我们可以包含stop-row
1. HTable table = new HTable(config, tableName);
2.
3. Filter filter = new InclusiveStopFilter(Bytes.toBytes("row1"));
4.
5. Scan scan = new Scan();
6. scan.setFilter(filter);
7. scan.setStartRow(Bytes.toBytes("row-5"));
8. ResultScanner scanner = table.getScanner(scan);
9.
10. for(Result result: scanner){
11. System.out.println(result);
12. }
会看到row1包含在结果中了。
2.8 TimestampsFilter
当访问某个Timestamp的新闻的时候,我们需要如下的代码:
1. TimestampsFilter(List<Long> timestamps)
接受的参数的list参数,该Filter也可以和scan.setTimeRange混合使用。例如:
1. // vv TimestampFilterExample
2. new ArrayList<Long>();
3. new Long(5));
4. new Long(10)); // co TimestampFilterExample-1-AddTS Add timestamps to the list.
5. new Long(15));
6. new TimestampsFilter(ts);
7.
8. new Scan();
9. // co TimestampFilterExample-2-AddFilter Add the filter to an otherwise default Scan instance.
10. ResultScanner scanner1 = table.getScanner(scan1);
11. // ^^ TimestampFilterExample
12. "Results of scan #1:");
13. // vv TimestampFilterExample
14. for (Result result : scanner1) {
15. System.out.println(result);
16. }
17. scanner1.close();
18.
19. new Scan();
20. scan2.setFilter(filter);
21. 8, 12); // co TimestampFilterExample-3-AddTSRange Also add a time range to verify how it affects the filter
22. ResultScanner scanner2 = table.getScanner(scan2);
23. // ^^ TimestampFilterExample
24. "Results of scan #2:");
25. // vv TimestampFilterExample
26. for (Result result : scanner2) {
27. System.out.println(result);
28. }
29. scanner2.close();
2.9 ColumnCountGetFilter
这个在scan时,无用。
2.10 ColumnPaginationFilter(下来用到的时候在仔细研究下)
* A filter, based on the ColumnCountGetFilter, takes two arguments: limit and offset.
* This filter can be used for row-based indexing, where references to other tables are stored across many columns,
* in order to efficient lookups and paginated results for end users.
1. Filter filter = new ColumnPaginationFilter(5, 15);
2.
3. new Scan();
4. scan.setFilter(filter);
5. ResultScanner scanner = table.getScanner(scan);
6. // ^^ ColumnPaginationFilterExample
7. "Results of scan:");
8. // vv ColumnPaginationFilterExample
9. for (Result result : scanner) {
10. System.out.println(result);
11. }
12. scanner.close();
2.11 ColumnPrefixFilter
跟prefxiFilter相似,只是改成了Column,实例如下:
1. // vv ColumnPaginationFilterExample
2. new ColumnPrefixFilter(Bytes.toBytes("qual2"));
3.
4. new Scan();
5. scan.setFilter(filter);
6. ResultScanner scanner = table.getScanner(scan);
7. // ^^ ColumnPaginationFilterExample
8. "Results of scan:");
9. // vv ColumnPaginationFilterExample
10. for (Result result : scanner) {
11. System.out.println(result);
12. }
13. scanner.close();
14.
2.12 RandomRowFilter
随即的返回row的数据,构造函数为
1. RandomRowFilter(float chance)
3、Decorating Filters
装饰性过滤器
这个过滤器只作用到keyValueFilter上。KeyValueFilter会返回所有满足条件的row及对应的列。
1. public static void main(String[] args) throws IOException {
2. Configuration conf = HBaseConfiguration.create();
3.
4. HBaseHelper helper = HBaseHelper.getHelper(conf);
5. "testtable");
6. "testtable", "colfam1");
7. "Adding rows to table...");
8. "testtable", 1, 30, 5, 2, true, true, "colfam1");
9.
10. new HTable(conf, "testtable");
11.
12. // vv SkipFilterExample
13. new ValueFilter(CompareFilter.CompareOp.NOT_EQUAL,
14. new BinaryComparator(Bytes.toBytes("val-0")));
15.
16. new Scan();
17. // co SkipFilterExample-1-AddFilter1 Only add the ValueFilter to the first scan.
18. ResultScanner scanner1 = table.getScanner(scan);
19. // ^^ SkipFilterExample
20. "Results of scan #1:");
21. int n = 0;
22. // vv SkipFilterExample
23. for (Result result : scanner1) {
24. for (KeyValue kv : result.raw()) {
25. "KV: " + kv + ", Value: " +
26. Bytes.toString(kv.getValue()));
27. // ^^ SkipFilterExample
28. n++;
29. // vv SkipFilterExample
30. }
31. }
32. scanner1.close();
33.
34. new SkipFilter(filter1);
35.
36. // co SkipFilterExample-2-AddFilter2 Add the decorating skip filter for the second scan.
37. ResultScanner scanner2 = table.getScanner(scan);
38. // ^^ SkipFilterExample
39. "Total KeyValue count for scan #1: " + n);
40. 0;
41. "Results of scan #2:");
42. // vv SkipFilterExample
43. for (Result result : scanner2) {
44. for (KeyValue kv : result.raw()) {
45. "KV: " + kv + ", Value: " +
46. Bytes.toString(kv.getValue()));
47. // ^^ SkipFilterExample
48. n++;
49. // vv SkipFilterExample
50. }
51. }
52. scanner2.close();
53. // ^^ SkipFilterExample
54. "Total KeyValue count for scan #2: " + n);
55. }
相当于while执行,知道不match就break了返回了。