2013-05-26 14 views
5

1つの列ファミリを持つHBase(v0.94.7)テーブルがあり、時間の経過とともに列が追加されています。これらの列は、作成されたタイムスタンプとして名前が付けられています。行を照会しない限り、すべての列がわかりません。HBase Row行のすべての列を置換するための突然変異

今度はになります。この列ファミリの既存の列をすべて削除し、新しい列と値のセットを追加します。

だから私は次のようにHBaseののRowMutationsを使用するのではと思った:

RowMutations mutations = new RowMutations(row); 

//delete the column family 
Delete delete = new Delete(row); 
delete.deleteFamily(cf); 

//add new columns 
Put put = new Put(row); 
put.add(cf, col1, v1); 
put.add(cf, col2, v2); 

//delete column family and add new columns to same family 
mutations.add(delete); 
mutations.add(put); 

table.mutateRow(mutations); 

しかし、このコードがやって終わることがちょうどそれが新しい列を追加しません、列ファミリを削除しています。この動作は期待されていますか?

もし私がの目標を達成するには、どうすれば列ファミリのすべての列を新しい列のセットに置き換えることができますか?ここで

は同じのためのテストケースである:

import junit.framework.Assert; 
import org.apache.hadoop.conf.Configuration; 
import org.apache.hadoop.hbase.HBaseConfiguration; 
import org.apache.hadoop.hbase.HColumnDescriptor; 
import org.apache.hadoop.hbase.HTableDescriptor; 
import org.apache.hadoop.hbase.TableExistsException; 
import org.apache.hadoop.hbase.client.*; 
import org.apache.hadoop.hbase.util.Bytes; 
import org.junit.Before; 
import org.junit.BeforeClass; 
import org.junit.Test; 

import java.util.NavigableMap; 

public class TestHBaseRowMutations { 
    static String tableName = "nnn"; 
    static byte[] cf1 = Bytes.toBytes("cf1"); 
    static byte[] row = Bytes.toBytes("r1"); 
    static HTablePool hTablePool; 

    @BeforeClass 
    public static void beforeClass() throws Exception { 
     Configuration config = HBaseConfiguration.create(); 
     hTablePool = new HTablePool(config, Integer.MAX_VALUE); 
     HBaseAdmin admin = new HBaseAdmin(config); 
     HTableDescriptor tableDescriptor = new HTableDescriptor(tableName); 
     tableDescriptor.addFamily(new HColumnDescriptor(cf1)); 
     try { 
      admin.createTable(tableDescriptor); 
     } catch (TableExistsException ignored){} 
    } 

    @Before 
    public void before() throws Exception { 
     HTableInterface table = hTablePool.getTable(tableName); 
     try { 
      Delete delete = new Delete(row); 
      table.delete(delete); 
      System.out.println("deleted old row"); 

      Put put = new Put(row); 
      put.add(cf1, Bytes.toBytes("c1"), Bytes.toBytes("v1")); 
      put.add(cf1, Bytes.toBytes("c11"), Bytes.toBytes("v11")); 
      table.put(put); 
      System.out.println("Created row with seed data"); 
     } finally { 
      table.close(); 
     } 
    } 


    @Test 
    public void testColumnFamilyDeleteRM() throws Exception { 
     HTableInterface table = hTablePool.getTable(tableName); 
     try { 
      RowMutations rm =new RowMutations(row); 

      //delete column family cf1 
      Delete delete = new Delete(row); 
      delete.deleteFamily(cf1); 
      rm.add(delete); 
      System.out.println("Added delete of cf1 column family to row mutation"); 

      //add new columns to same column family cf1 
      Put put = new Put(row); 
      put.add(cf1, Bytes.toBytes("c1"), Bytes.toBytes("new_v1")); 
      put.add(cf1, Bytes.toBytes("c11"), Bytes.toBytes("new_v11")); 
      rm.add(put); 
      System.out.println("Added puts of cf1 column family to row mutation"); 

      //atomic mutate the row 
      table.mutateRow(rm); 
      System.out.println("Mutated row"); 

      //now read the column family cf1 back 
      Result result = table.get(new Get(row)); 
      NavigableMap<byte[], byte[]> familyMap = result.getFamilyMap(cf1); 

      //column family cf1 should have 2 columns because of the Put above 
      //------Following assert fails as cf1 does not exist anymore, why does cf1 not exist anymore?------- 
      Assert.assertNotNull(familyMap); 
      Assert.assertEquals(2, familyMap.size()); 
     } finally { 
      table.close(); 
     } 
    } 
} 
+0

個々の列自体ではなく、*列ファミリを削除することはできますか? –

+0

上記のように、私は列名を前もって知っていません。そう、はい、私は列ファミリをdelete.deleteFamily(cf)で削除しています。 put.add(cf、col1、v1);で新しい列を追加する – vinodv26

答えて

4

は、HBaseのユーザーフォーラムで同じ質問を投稿し、これはHBaseのバグです判明します。

期待された振る舞いは、RowMutationにDeleteをいくつかの列ファミリ/列/行に加え、同じ列ファミリ/列/行に置くと、Putも尊重されます(ただし、これは現在のケース)。

この上でHBaseのユーザグループディスカッション:同じ用 http://apache-hbase.679495.n3.nabble.com/Using-RowMutations-to-replace-all-columns-of-a-row-td4045247.html

のHBase JIRA: https://issues.apache.org/jira/browse/HBASE-8626もパッチを提供します。

1

行うことができます最も近いものは削除よりも高くなるように入れ上のタイムスタンプを設定されている:

long now = System.currentTimeMillis(); 

Delete delete = new Delete(row); 
delete.deleteFamily(cf1, now); 

Put put = new Put(row); 
put.add(cf1, col1, now + 1); 

RowMutations mutations = new RowMutations(row); 
mutations.add(delete); 
mutations.add(put); 

table.mutateRow(mutations); 

悲しいことに、それはタイムスタンプにgetは、「今」という点では何も持っていないことを意味してい列ファミリ。 Source

関連する問題