ValueFilter 的疑问,是bug?

无边的绿波 TC 2014-01-08 11:38:11
在使用ValueFilter过滤数据的时候会出现会把所有版本的符合过滤条件的结果都返回出来。
例如:

列名为:name
值为:limu

之后将 “limu” 改成“zhangsan”

使用
ValueFilter vf = new ValueFilter(CompareFilter.CompareOp.EQUAL,
new SubstringComparator("li"));
Get get = new Get(key.getBytes());
get.setFilter(vf);

最后的结果中有列名:name 值为:limu的数据

就是把之前版本的数据也过滤出来了。

像SingleColumnValueFilter 里面可以设置 setLatestVersionOnly(true); 来达到最后一个版本的过滤。

不知道ValueFilter 应该怎么过滤最后一个版本,希望知道的 ,不吝赐教,如果不能过滤,还有什么其他方式来实现我的需求吗?

...全文
239 点赞 收藏 8
写回复
8 条回复
无边的绿波 2014年01月21日
谢谢楼上了,现在使用的方法是每次修改某个数据的时候先把数据删除再进行修改,就可以使用valuefilter过滤了!
回复 点赞
撸大湿 2014年01月08日
引用 2 楼 wubo2qml 的回复:
[quote=引用 1 楼 tntzbzc 的回复:] 直接设置get.setMaxVersions(1)不行吗
Get.setMaxVersions()//可以返回多个版本的数据。
Get.setTimeRange()//可以返回其他时间范围的版本。
设置这个也不行,不信你可以试试![/quote] 我看错问题了,我这个是得到最后一个版本,不是过滤 最简单的办法设置Get.setMaxVersions(2) 这样可以获取两个TS版本的数据,然后在Client实现最后一个TS版本过滤
回复 点赞
无边的绿波 2014年01月08日
引用 1 楼 tntzbzc 的回复:
直接设置get.setMaxVersions(1)不行吗
Get.setMaxVersions()//可以返回多个版本的数据。
Get.setTimeRange()//可以返回其他时间范围的版本。
设置这个也不行,不信你可以试试!
回复 点赞
撸大湿 2014年01月08日
直接设置get.setMaxVersions(1)不行吗
Get.setMaxVersions()//可以返回多个版本的数据。
Get.setTimeRange()//可以返回其他时间范围的版本。
回复 点赞
撸大湿 2014年01月08日
引用 6 楼 wubo2qml 的回复:
[quote=引用 5 楼 tntzbzc 的回复:] [quote=引用 4 楼 wubo2qml 的回复:] 设置 Get.setMaxVersions(2) 根本达不到获取两个TS版本数据的效果,又怎么在client实现最后TS版本的过滤呢?
怎么可能 刚刚测了下,全部贴出来 先用hbase shell 测试

hbase(main):005:0> create 'test0001',{NAME=>'_0',VERSIONS=>3}
//建表

hbase(main):010:0> put 'test0001','111','_0:t1','111',111
hbase(main):013:0> put 'test0001','111','_0:t1','222',222
//对ROWKEY=111 插入两条数据 TS分别为 111 222


hbase(main):017:0> scan 'test0001',{VERSIONS=>1}
ROW                                                COLUMN+CELL                                                                                                                                      
 111                                               column=_0:t1, timestamp=222, value=222 
//这时只有timestamp=111的数据

hbase(main):016:0> scan 'test0001',{VERSIONS=>2}
ROW                                                COLUMN+CELL                                                                                                                                      
 111                                               column=_0:t1, timestamp=222, value=222                                                                                                           
 111                                               column=_0:t1, timestamp=111, value=111
//这时有timestamp=111和222两个version数据
再看java API 调用测试

import org.apache.hadoop.conf.Configuration;
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;

public class hbasetest {
	public static void main(String[] agrs) throws Exception {
		Configuration myConf;
		myConf = new Configuration();
		myConf.set("hbase.zookeeper.quorum", "10.128.24.200");
		myConf.set("hbase.zookeeper.property.clientPort", "2181");

		HTable tb = new HTable(myConf, "test0001");
		Get get = new Get("111".getBytes());
		get.setMaxVersions(2);
		Result rs = tb.get(get);

		for (KeyValue kv : rs.list())
		{
			System.out.println(new String(kv.getQualifier()) + ":" +
					new String(kv.getValue()) + "\t");
			System.out.println();
		}		
	}
}


//get.setMaxVersions(1);  结果看下方

t1:222	

//get.setMaxVersions(2);  结果看下方

t1:222	

t1:111	

怎么过滤最后一个VERSION数据,不用我再写了吧[/quote] 你把get.setMaxVersions(2) 结合ValueFilter 使用的时候 就达不到这个效果了, 代码如下: ValueFilter vf = new ValueFilter(CompareFilter.CompareOp.EQUAL, new SubstringComparator("D_")); String key = "6745701"; Get get = new Get(key.getBytes()); get.setMaxVersions(1); get.setFilter(vf); Result re = table.get(get); List<KeyValue> list = re.list(); for (int i = 0; i < list.size(); i++) { System.out.println("列名:" + Bytes.toString(list.get(i).getQualifier())); System.out.println("列值:" + Bytes.toString(list.get(i).getValue())); System.out.println("时间戳:" + list.get(i).getTimestamp()); System.out.println(); } 结果如下: 列名:h_8679935873_111031001706 列值:D_43610 时间戳:1388994473015 列名:h_8679935873_111031001708 列值:D_6001 时间戳:1388996755580 列名:h_8888dsahjdsa 列值:D_200 时间戳:1389166949242 控制台信息如下: 最新版本的数据中值以D_开头的只有一个列,其他的列如:h_8888dsahjdsa 这个过滤到的是D_200但是现在的数据是 H_200 ,如何一次查询取得两个的时间戳呢?[/quote] 不管怎么设置Version数量 如果用filter 限制 “D_”开头,那永远都拿不到“H_”的数据 除非有两个“D_”开头,不同版本的数据,才肯被搜索到 要解决这个问题,LZ你只能放弃filter ,全部取下来让Client筛选 要不就重新设计TS,用有规则的TS插入数据 然后用TimestampsFilter判断筛选
回复 点赞
无边的绿波 2014年01月08日
引用 5 楼 tntzbzc 的回复:
[quote=引用 4 楼 wubo2qml 的回复:]
设置 Get.setMaxVersions(2) 根本达不到获取两个TS版本数据的效果,又怎么在client实现最后TS版本的过滤呢?


怎么可能
刚刚测了下,全部贴出来

先用hbase shell 测试

hbase(main):005:0> create 'test0001',{NAME=>'_0',VERSIONS=>3}
//建表

hbase(main):010:0> put 'test0001','111','_0:t1','111',111
hbase(main):013:0> put 'test0001','111','_0:t1','222',222
//对ROWKEY=111 插入两条数据 TS分别为 111 222


hbase(main):017:0> scan 'test0001',{VERSIONS=>1}
ROW COLUMN+CELL
111 column=_0:t1, timestamp=222, value=222
//这时只有timestamp=111的数据

hbase(main):016:0> scan 'test0001',{VERSIONS=>2}
ROW COLUMN+CELL
111 column=_0:t1, timestamp=222, value=222
111 column=_0:t1, timestamp=111, value=111
//这时有timestamp=111和222两个version数据


再看java API 调用测试


import org.apache.hadoop.conf.Configuration;
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;

public class hbasetest {
public static void main(String[] agrs) throws Exception {
Configuration myConf;
myConf = new Configuration();
myConf.set("hbase.zookeeper.quorum", "10.128.24.200");
myConf.set("hbase.zookeeper.property.clientPort", "2181");

HTable tb = new HTable(myConf, "test0001");
Get get = new Get("111".getBytes());
get.setMaxVersions(2);
Result rs = tb.get(get);

for (KeyValue kv : rs.list())
{
System.out.println(new String(kv.getQualifier()) + ":" +
new String(kv.getValue()) + "\t");
System.out.println();
}
}
}




//get.setMaxVersions(1); 结果看下方

t1:222

//get.setMaxVersions(2); 结果看下方

t1:222

t1:111



怎么过滤最后一个VERSION数据,不用我再写了吧[/quote]


你把get.setMaxVersions(2) 结合ValueFilter 使用的时候 就达不到这个效果了,

代码如下:

ValueFilter vf = new ValueFilter(CompareFilter.CompareOp.EQUAL,
new SubstringComparator("D_"));
String key = "6745701";
Get get = new Get(key.getBytes());
get.setMaxVersions(1);
get.setFilter(vf);
Result re = table.get(get);
List<KeyValue> list = re.list();
for (int i = 0; i < list.size(); i++) {
System.out.println("列名:" + Bytes.toString(list.get(i).getQualifier()));
System.out.println("列值:" + Bytes.toString(list.get(i).getValue()));
System.out.println("时间戳:" + list.get(i).getTimestamp());
System.out.println();
}
结果如下:


列名:h_8679935873_111031001706
列值:D_43610
时间戳:1388994473015

列名:h_8679935873_111031001708
列值:D_6001
时间戳:1388996755580

列名:h_8888dsahjdsa
列值:D_200
时间戳:1389166949242

控制台信息如下:



最新版本的数据中值以D_开头的只有一个列,其他的列如:h_8888dsahjdsa 这个过滤到的是D_200但是现在的数据是 H_200 ,如何一次查询取得两个的时间戳呢?
回复 点赞
撸大湿 2014年01月08日
引用 4 楼 wubo2qml 的回复:
设置 Get.setMaxVersions(2) 根本达不到获取两个TS版本数据的效果,又怎么在client实现最后TS版本的过滤呢?


怎么可能
刚刚测了下,全部贴出来

先用hbase shell 测试

hbase(main):005:0> create 'test0001',{NAME=>'_0',VERSIONS=>3}
//建表

hbase(main):010:0> put 'test0001','111','_0:t1','111',111
hbase(main):013:0> put 'test0001','111','_0:t1','222',222
//对ROWKEY=111 插入两条数据 TS分别为 111 222


hbase(main):017:0> scan 'test0001',{VERSIONS=>1}
ROW COLUMN+CELL
111 column=_0:t1, timestamp=222, value=222
//这时只有timestamp=111的数据

hbase(main):016:0> scan 'test0001',{VERSIONS=>2}
ROW COLUMN+CELL
111 column=_0:t1, timestamp=222, value=222
111 column=_0:t1, timestamp=111, value=111
//这时有timestamp=111和222两个version数据


再看java API 调用测试


import org.apache.hadoop.conf.Configuration;
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;

public class hbasetest {
public static void main(String[] agrs) throws Exception {
Configuration myConf;
myConf = new Configuration();
myConf.set("hbase.zookeeper.quorum", "10.128.24.200");
myConf.set("hbase.zookeeper.property.clientPort", "2181");

HTable tb = new HTable(myConf, "test0001");
Get get = new Get("111".getBytes());
get.setMaxVersions(2);
Result rs = tb.get(get);

for (KeyValue kv : rs.list())
{
System.out.println(new String(kv.getQualifier()) + ":" +
new String(kv.getValue()) + "\t");
System.out.println();
}
}
}




//get.setMaxVersions(1); 结果看下方

t1:222

//get.setMaxVersions(2); 结果看下方

t1:222

t1:111



怎么过滤最后一个VERSION数据,不用我再写了吧
回复 点赞
无边的绿波 2014年01月08日
引用 3 楼 tntzbzc 的回复:
[quote=引用 2 楼 wubo2qml 的回复:] [quote=引用 1 楼 tntzbzc 的回复:] 直接设置get.setMaxVersions(1)不行吗
Get.setMaxVersions()//可以返回多个版本的数据。
Get.setTimeRange()//可以返回其他时间范围的版本。
设置这个也不行,不信你可以试试![/quote] 我看错问题了,我这个是得到最后一个版本,不是过滤 最简单的办法设置Get.setMaxVersions(2) 这样可以获取两个TS版本的数据,然后在Client实现最后一个TS版本过滤 [/quote] 设置 Get.setMaxVersions(2) 根本达不到获取两个TS版本数据的效果,又怎么在client实现最后TS版本的过滤呢?
回复 点赞
发动态
发帖子
Hadoop
创建于2011-06-27

6903

社区成员

4307

社区内容

分布式计算/Hadoop/Hbase/Cassandra/Storm/Spark/大数据
社区公告
暂无公告