0

ハイブに2つのテーブルがあります。'access' と呼ばれる最初のフィールドには apache ログが含まれており、最初のフィールドは完全な IP アドレスです。

10.4.5.12 - - [26/Jun/2010:11:16:09 +1000] "GET /myportal/pageA HTTP/1.1"
10.4.41.2 - - [26/Jun/2010:11:18:09 +1000] "GET /myportal/pageB HTTP/1.1"
10.5.1.111 - - [26/Jun/2010:11:22:09 +1000] "GET /myportal/pageA HTTP/1.1"
192.10.4.177 - - [26/Jun/2010:11:22:41 +1000] "GET /myportal/pageC HTTP/1.1"

IP範囲の開始と文字列を含む「クライアント」と呼ばれる別のもの:

10.4 clientA
10.5 clientB
10.7 ClientC

クライアントごとにヒットの合計を見つけて、その名前を表示したいと思います。したがって、この2つのテーブルを次のように結合しようとします:

SELECT client.name, count(access.ip) FROM access JOIN client WHERE access.ip RLIKE client.ip GROUP BY client.name;

それは機能しますが、clientA の場合、Apache ログの最後のエントリ (192.10.4.177) にもヒットします。これは望ましくありません。client.ip と access.ip の先頭だけを比較したいと思います。

特定の正規表現だと思います...または私のシンタックスが間違っているかもしれません...誰かがアイデアを持っていますか?

前もって感謝します

4

1 に答える 1

2

RLIKE は Java 正規表現を使用します。つまり、「^」を使用して、何かで始まることを表すことができます。たとえば、「CONCAT("^",client.ip)」を使用して、「^」を の前に置くことができますclient.ip

SELECT client.name, count(access.ip)
FROM access JOIN client
WHERE access.ip RLIKE CONCAT("^",client.ip)
GROUP BY client.name;

ただし、「。」は、任意の文字を意味する正規表現の特殊文字でもあります。したがって、上記の解決策は完全ではありません。たとえば、クライアント IP が の場合、1.3「103.2.3.4」と一致する可能性があります。したがって、より良い解決策は「。」をエスケープすることです。クライアントIPで。最終的な解決策は次のとおりです。

SELECT client.name, count(access.ip)
FROM access JOIN client
WHERE access.ip RLIKE CONCAT("^",REGEXP_REPLACE(client.ip, "\\.", "\\."))
GROUP BY client.name;

1 つ目\\.は正規表現を意味し\.ます (Hive で「\」を指定するには、「\」を追加する必要があります)。2 番目\\.は string を意味します\.。Java の正規表現に慣れていない場合は、混乱する可能性があります。

于 2013-08-06T03:05:21.573 に答える