1

ハイ、

Hbase では、列ファミリーが異なる行に異なる修飾子を持つことができます。私の場合、列ファミリーには次の仕様があります

abc[cnt] # where cnt is an integer that can be any positive integer

私が達成したいのは、記述された修飾子 (別の列ファミリー内) の値が一致する場合にのみ、別の列ファミリーからすべてのデータを取得することです。

スキャンを絞り込むために、クエリに必要な 2 つのファミリを追加するだけです。しかし、それは私が今のところ得ることができる限りです。

私はすでに SingleColumnValueFilter で同じ動作を達成しましたが、修飾子は事前にわかっていました。ただし、この場合、修飾子はabc1abc2にすることができます...オプションが多すぎるため、SingleColumnValueFilterが多すぎます。

次に、ValueFilter を使用してみましたが、このフィルターは値に一致する列のみを返すため、間違った列ファミリーが返されます。

列ファミリーで動的に作成された修飾子内の値を照会し、列ファミリーと別の列ファミリーの内容を返すという私の目標を達成する方法を考えてもらえますか (スキャンの作成時に指定)? できれば一度だけクエリを実行してください。

ご意見をお寄せいただきありがとうございます。

更新:(コメントで説明されているように明確にするため)

よりグラフィカルな方法で、行には次のものが含まれる場合があります。

colfam1:aaa
colfam1:aab
colfam1:aac
colfam2:abc1
colfam2:abc2

一方、colfam2:abc[cnt] が cnt が任意の正の整数で動的に作成されるという事実に関して、colfam2 のいずれかの値がたとえば値 x である場合、すべてのファミリー colfam1 を取得したい

4

1 に答える 1

3

これには、クライアント側のフィルタリングとサーバー側のフィルタリングの 2 つのアプローチがあります。

クライアント側のフィルタリングはより簡単です。スキャンは、" colfam1" と " "の 2 つのファミリのみを追加しますcolfam2。次に、Resultから取得したそれぞれについてscanner.next()、「 」の修飾子に従ってフィルタリングする必要がありますcolfam2

byte[] queryValue = Bytes.toBytes("x");
Scan scan = new Scan();
scan.addFamily(Bytes.toBytes("colfam1");
scan.addFamily(Bytes.toBytes("colfam2");
ResultScanner scanner = myTable.getScanner(scan);
Result res;
while((res = scanner.next()) != null) {
   NavigableMap<byte[],byte[]> colfam2 = res.getFamilyMap(Bytes.toBytes("colfam2"));
   boolean foundQueryValue = false;
   SearchForQueryValue: while(!colfam2.isEmpty()) {
       Entry<byte[], byte[]> cell = colfam2.pollFirstEntry();
       if( Bytes.equals(cell.getValue(), queryValue) ) {
           foundQueryValue = true;
           break SearchForQueryValue;
       }
   }
   if(foundQueryValue) {
       NavigableMap<byte[],byte[]> colfam1 = res.getFamilyMap(Bytes.toBytes("colfam1"));
       LinkedList<KeyValue> listKV = new LinkedList<KeyValue>();
       while(!colfam1.isEmpty()) {
           Entry<byte[], byte[]> cell = colfam1.pollFirstEntry();
           listKV.add(new KeyValue(res.getRow(), Bytes.toBytes("colfam1"), cell.getKey(), cell.getValue()); 
       }
       Result filteredResult = new Result(listKV);
   }
}

(このコードはテストされていません)

そして最後filteredResultに、あなたが望むものです。このアプローチはエレガントではなく、これらのファミリに大量のデータがある場合、パフォーマンスの問題が発生する可能性もあります。「colfam1」に多くのデータがある場合、値「x」が「colfam2」の修飾子にない場合に使用されなくなる場合は、クライアントに転送したくありません。

サーバー側のフィルタリング。これには、独自の Filter クラスを実装する必要があります。提供されたフィルターの種類を使用してこれを行うことはできないと思います。独自のフィルターを実装するには、いくつかの作業が必要です。それを .jar としてコンパイルし、すべての RegionServer で使用できるようにする必要もあります。ただし、「colfam1」の大量のデータを無駄に送信するのを避けるのに役立ちます。フィルターをカスタム実装する方法を説明するのは面倒なので、良い本 ( HBase: The Definitive Guideなど) を読むことをお勧めします。ただし、フィルター コードは、先ほど示したクライアント側のフィルター処理とほとんど同じように見えるので、これで作業の半分は完了です。

于 2012-07-23T14:40:27.390 に答える