web-dev-qa-db-ja.com

Hiveクエリ内の列として入力ファイル名を取得する方法

いくつかのディレクトリにマップされたHive外部テーブルがあります。このディレクトリには、いくつかのファイルが含まれています。

ユーザー「abc」が存在する場所でファイル名を検索するようなクエリを実行したい

 select file_name , usr from usrs_tables where usr = "abc"

しかしもちろん、データにはファイル名が含まれていません。

MapReduceでは、

FileSplit fileSplit = (FileSplit)context.getInputSplit();
String filename = fileSplit.getPath().getName();
System.out.println("File name "+filename);
System.out.println("Directory and File name"+fileSplit.getPath().toString());

Hiveでそれを行うにはどうすればよいですか?

19
Julias

はい、INPUT__FILE__NAMEという名前の仮想列を使用して、レコードが見つかったファイルを取得できます。次に例を示します。

select INPUT__FILE__NAME, id, name from users where ...;

次のようなものが得られます:

hdfs://localhost.localdomain:8020/user/Hive/warehouse/users/users1.txt    2    user2
hdfs://localhost.localdomain:8020/user/Hive/warehouse/users/users2.txt    42    john.doe

必要に応じて、提供されている string functions を使用して、URIからホストとディレクトリを削除します。

ここで仮想列のドキュメントを見つけることができます: https://cwiki.Apache.org/confluence/display/Hive/LanguageManual+VirtualColumns

43
jkovacs

Hiveのすべてのテーブルには2つの仮想列があります。彼らです

  1. INPUT__FILE__NAME
  2. BLOCK__OFFSET__INSIDE__FILE

INPUT__FILE__NAMEはファイルの名前を示します。 BLOCK__OFFSET__INSIDE__FILEは現在のグローバルファイルの位置です。ファイル内の各レコードに対応するファイルの名前を検索したいとします。 INPUT__FILE__NAME列。この機能は、0.8以上のHiveバージョンから使用できます。小さな例を以下に示します。

クエリ

select INPUT__FILE__NAME, name from customer_data;

これにより、各レコードに対応するファイル名がわかります。 Hiveテーブルに対応するファイル名を取得する場合は、以下のクエリが役立ちます。

select distinct(INPUT__FILE__NAME) from customer_data;
6
Maheswaran M

Hive 0.8.0は、2つの仮想列をサポートします。

1つはINPUT__FILE__NAMEは、マッパータスクの入力ファイルの名前です。

もう1つはBLOCK__OFFSET__INSIDE__FILEは、現在のグローバルファイルの位置です。

ブロック圧縮ファイルの場合、これは現在のブロックのファイルオフセットであり、現在のブロックの最初のバイトのファイルオフセットです。

Hive 0.8.0以降、次の仮想列が追加されました。

  • ROW__OFFSET__INSIDE__BLOCK
  • RAW__DATA__SIZE
  • ROW__ID
  • GROUPING__ID

Hiveの仮想列の更新されたリンク: https://cwiki.Apache.org/confluence/display/Hive/LanguageManual+VirtualColumns

3
david1977