Regexp_extractで問題が発生しています。
タブ区切りファイルでクエリを実行しています。チェックしている列には、次のような文字列があります。
abc.def.ghi
今、私がするなら:
select distinct regexp_extract(name, '[^.]+', 0) from dummy;
MRジョブが実行され、機能し、インデックス0から「abc」を取得します。
しかし今、インデックス1から "def"を取得したい場合は、次のようにします。
select distinct regexp_extract(name, '[^.]+', 1) from dummy;
Hiveが失敗する:
2011-12-13 23:17:08,132 Stage-1 map = 0%, reduce = 0%
2011-12-13 23:17:28,265 Stage-1 map = 100%, reduce = 100%
Ended Job = job_201112071152_0071 with errors
FAILED: Execution Error, return code 2 from org.Apache.hadoop.Hive.ql.exec.MapRedTask
ログファイルは言う:
Java.lang.RuntimeException: org.Apache.hadoop.Hive.ql.metadata.HiveException: Hive Runtime Error while processing row
ここで根本的に間違っていることをしていますか?
ありがとう、マリオ
ドキュメントから https://cwiki.Apache.org/confluence/display/Hive/LanguageManual+UDF regexp_extract()は、抽出するデータのレコード/行抽出であるように見えます。
グローバルではなく、最初に見つかった(その後終了した)場合に機能するようです。したがって、インデックスはキャプチャグループを参照します。
0 =完全一致
1 =キャプチャグループ1
2 =キャプチャグループ2など...
マニュアルから言い換えると:
_regexp_extract('foothebar', 'foo(.*?)(bar)', 2)
^ ^
groups 1 2
This returns 'bar'.
_
したがって、あなたの場合、ドットの後にテキストを取得するには、次のようなものが機能する可能性があります。regexp_extract(name, '\.([^.]+)', 1)
またはこれregexp_extract(name, '[.]([^.]+)', 1)
edit
私はこれに再び興味を持ちました、ただのファイです、あなたのためのショートカット/回避策があるかもしれません。
ドットの_.
_文字で区切られた特定のセグメントが必要であるように見えます。これはほとんど分割のようなものです。
複数回定量化される場合、使用される正規表現エンジンがグループを上書きする可能性が高いです。
次のようなものでそれを利用できます:
最初のセグメントを返します:abc
。def.ghiregexp_extract(name, '^(?:([^.]+)\.?){1}', 1)
2番目のセグメントを返します:abc .def
。ghiregexp_extract(name, '^(?:([^.]+)\.?){2}', 1)
3番目のセグメントを返します:abc.def .ghi
regexp_extract(name, '^(?:([^.]+)\.?){3}', 1)
インデックスは変更されません(インデックスはまだキャプチャグループ1を参照しているため)。正規表現の繰り返しのみが変更されます。
いくつかのメモ:
ただし、この正規表現^(?:([^.]+)\.?){n}
には問題があります。
セグメント内のドットの間に何かがあるか、正規表現が_...
_と一致しないことが必要です。
これは^(?:([^.]*)\.?){n}
の可能性がありますが、n-1ドット未満の場合でも一致します。
空の文字列を含みます。これはおそらく望ましくありません。
ドットの間にテキストを必要としないが、少なくともn-1ドットが必要な場合にそれを行う方法があります。
これは、先読みアサーションとキャプチャバッファ2をフラグとして使用します。
^(?:(?!\2)([^.]*)(?:\.|$())){2}
、それ以外はすべて同じです。
したがって、Javaスタイルの正規表現を使用している場合、これは機能するはずです。regexp_extract(name, '^(?:(?!\2)([^.]*)(?:\.|$())){2}', 1)
{2}を必要な「セグメント」に変更します(これによりセグメント2が実行されます)。
また、{N}番目の反復後もキャプチャバッファ1を返します。
ここで分解されます
_^ # Begining of string
(?: # Grouping
(?!\2) # Assertion: Capture buffer 2 is UNDEFINED
( [^.]*) # Capture buffer 1, optional non-dot chars, many times
(?: # Grouping
\. # Dot character
| # or,
$ () # End of string, set capture buffer 2 DEFINED (prevents recursion when end of string)
) # End grouping
){3} # End grouping, repeat group exactly 3 (or N) times (overwrites capture buffer 1 each time)
_
アサーションを行わない場合、これは機能しません。
「グループ」を作らないといけないと思いますか?
select distinct regexp_extract(name, '([^.]+)', 1) from dummy;
(未試験)
私はそれがJavaライブラリのように動作すると思います、そしてこれはうまくいくはずですが、私に知らせてください。