【问题标题】:Get filtered rows in HBase在 HBase 中获取过滤的行
【发布时间】:2012-06-17 02:03:53
【问题描述】:

在应用一些过滤器后,我试图从 HBase 中获取行中选定的列。考虑如下表格:

ename:fname ename:lname 薪水:总薪水:da 薪水:ta

我想获取总工资 > 1500 的所有员工的列表。为此,我编写了以下代码。我面临的问题是,当我过滤列时,我只会在输出中得到那个过滤器,这是有道理的,因为这是它们的创建目的,但是如果我想获得所需的列,但只想基于特定列进行过滤怎么办,就像我刚才提到的那样 - 所有工资 > 1500 的员工列表。

输出应该是以下一组列:

lname,fname,salary:gross,salary:ta

到目前为止的代码

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.filter.BinaryComparator;
import org.apache.hadoop.hbase.filter.RegexStringComparator;
import org.apache.hadoop.hbase.filter.SubstringComparator;
import org.apache.hadoop.hbase.filter.CompareFilter;
import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.filter.QualifierFilter;
import org.apache.hadoop.hbase.filter.FamilyFilter;
import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.filter.ValueFilter;
import org.apache.hadoop.hbase.util.Bytes;


import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


public class MyQualifierFilterExample {

  public static void main(String[] args) throws IOException {
    Configuration conf = HBaseConfiguration.create();

    HTable table = new HTable(conf, "emp");

    List<Filter> filters = new ArrayList<Filter>();

    Filter famFilter = new FamilyFilter(CompareFilter.CompareOp.EQUAL,
              new BinaryComparator(Bytes.toBytes("salary")));
    filters.add(famFilter);

    Filter colFilter = new QualifierFilter(CompareFilter.CompareOp.EQUAL,
      new BinaryComparator(Bytes.toBytes("gross")));

    filters.add(colFilter);

    Filter valFilter = new ValueFilter(CompareFilter.CompareOp.GREATER_OR_EQUAL,
              new BinaryComparator(Bytes.toBytes("1500")));

    filters.add(valFilter);

    FilterList fl = new FilterList( FilterList.Operator.MUST_PASS_ALL, filters);


    Scan scan = new Scan();
    scan.setFilter(fl);
    ResultScanner scanner = table.getScanner(scan);
    System.out.println("Scanning table... ");
    for (Result result : scanner) {
        //System.out.println("getRow:"+Bytes.toString(result.getRow()));
        for (KeyValue kv : result.raw()) {
            //System.out.println("Family - "+Bytes.toString(kv.getFamily()));
            //System.out.println("Qualifier - "+Bytes.toString(kv.getQualifier() ));
            System.out.println("kv:"+kv +", Key: " + Bytes.toString(kv.getRow())  + ", Value: " +Bytes.toString(kv.getValue()));
        }
    }   

    scanner.close();
    System.out.println("Completed ");
  }
}

输出

Scanning table... 
kv:101/salary:gross/1339876269770/Put/vlen=4, Key: 101, Value: 2000
kv:102/salary:gross/1339876277659/Put/vlen=4, Key: 102, Value: 2400
kv:105/salary:gross/1339876300585/Put/vlen=4, Key: 105, Value: 2300
kv:106/salary:gross/1339876310004/Put/vlen=4, Key: 106, Value: 2900
Completed 

解决方案 1

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.filter.BinaryComparator;
import org.apache.hadoop.hbase.filter.RegexStringComparator;
import org.apache.hadoop.hbase.filter.SubstringComparator;
import org.apache.hadoop.hbase.filter.CompareFilter;
import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.filter.QualifierFilter;
import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
import org.apache.hadoop.hbase.filter.FamilyFilter;
import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.filter.ValueFilter;
import org.apache.hadoop.hbase.util.Bytes;


import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


public class MyQualifierFilterExample {

  public static void main(String[] args) throws IOException {
    Configuration conf = HBaseConfiguration.create();

    HTable table = new HTable(conf, "emp");

    List<Filter> filters = new ArrayList<Filter>();

    SingleColumnValueFilter colValFilter = new SingleColumnValueFilter(Bytes.toBytes("salary"), Bytes.toBytes("gross")
            , CompareFilter.CompareOp.GREATER_OR_EQUAL, new BinaryComparator(Bytes.toBytes("1300")));
    colValFilter.setFilterIfMissing(false);
    filters.add(colValFilter);          

    Filter colValFilter2 = new SingleColumnValueFilter(Bytes.toBytes("salary"), Bytes.toBytes("da")
            , CompareFilter.CompareOp.GREATER_OR_EQUAL, new BinaryComparator(Bytes.toBytes("150")));
    filters.add(colValFilter2);

    //Filter colValFilter3 = new SingleColumnValueFilter(Bytes.toBytes("ename"), Bytes.toBytes("fname")
    //      , CompareFilter.CompareOp.GREATER_OR_EQUAL, new SubstringComparator("jack"));
    //filters.add(colValFilter3);

    FilterList fl = new FilterList( FilterList.Operator.MUST_PASS_ALL, filters);


    Scan scan = new Scan();
    scan.setFilter(fl);
    scan.addColumn(Bytes.toBytes("ename"), Bytes.toBytes("fname"));
    scan.addColumn(Bytes.toBytes("ename"), Bytes.toBytes("lname"));
    scan.addColumn(Bytes.toBytes("salary"), Bytes.toBytes("gross"));
    scan.addColumn(Bytes.toBytes("salary"), Bytes.toBytes("da"));

    ResultScanner scanner = table.getScanner(scan);
    String key = new String("~");
    String keyFlag = new String("~");
    System.out.println("Scanning table... ");
    for (Result result : scanner) {
        //System.out.println("getRow:"+Bytes.toString(result.getRow()));
        key = "~";
        for (KeyValue kv : result.raw()) {

            if (key.compareTo(keyFlag)==0)
            {
                key = Bytes.toString(kv.getRow());
                System.out.print("Key: " + key);
            }
            //System.out.print("Family - "+Bytes.toString(kv.getFamily()));

            //System.out.print(", Buffer - "+Bytes.toString(kv.getBuffer() ));
            //System.out.print(", FamilyOffset - " + kv.getFamilyOffset() );
            System.out.print(", "+Bytes.toString(kv.getFamily())+"."+Bytes.toString(kv.getQualifier()));
            System.out.print("=" +Bytes.toString(kv.getValue()));
        }
        System.out.println("");
        System.out.println("-------------------");
    }   

    scanner.close();
    System.out.println("Completed ");
  }
}

输出:

Scanning table... 
Key: 103, ename.fname=peter, ename.lname=parker, salary.da=190, salary.gross=1400
-------------------
Key: 105, ename.fname=harry, ename.lname=potter, salary.da=154, salary.gross=2300
-------------------
Completed 

【问题讨论】:

  • 你的薪水真的保存为代表字符串的字节吗?这可能是个问题,因为字符串 "900" 大于字符串 "1500"

标签: hbase


【解决方案1】:

您应该使用SingleColumnValueFilteraddFamily(或addColumn)的组合

见下文(我目前无法对其进行测试):

SingleColumnValueFilter filter = new SingleColumnValueFilter(
    Bytes.toBytes("salary"),
    Bytes.toBytes("gross"),
    CompareOp.GREATER,
    Bytes.toBytes("1500")
);
//To prevent the entire row from being emitted
//if the column is not found on a row
scan.setFilterIfMissing(true)
scan.setFilter(filter);

scan.addFamily(Bytes.toBytes("ename"))
scan.addColumn(Bytes.toBytes("salary"), Bytes.toBytes("da"))
scan.addColumn(Bytes.toBytes("salary"), Bytes.toBytes("gross"))

【讨论】:

  • 我建议将参数CompareOp.GREATER 替换为CompareOperator.GREATER,因为第一个参数已被弃用。
【解决方案2】:

您的要求是相关的。所以,我建议你在 HBase 上使用一个包装器来简化生活。

考虑使用:Apache Phoenix。它是 HBase 的高性能 SQL 包装器,您可以使用它运行如下查询:select * from emp where salary&gt;1500

【讨论】:

    【解决方案3】:

    值过滤器 此过滤器可以仅包含具有特定值的列

    这就是为什么您只能获取您在过滤器中指定的列。

    如果我错了,请告诉我,但您要做的是在薪水 > 1500 时检索所有列,不是吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多