Splunk lookupテーブル利用時の重複レコードの扱い
lookupテーブルの中に重複レコードがある時の振る舞い
表題の通りなのだけれど、そういうことした時のsplunkでの扱いが少々意外だったので、TIPSまで。
重複レコードがある場合って?
具体的には、こんなケースです。
192.168.1.1の行が2つあります。
Group | address |
---|---|
Office A | 192.168.1.1 |
Office B | 192.168.1.1 |
Office C | 192.168.1.2 |
SQL的に考えると、addressで別テーブルと突合した場合、例えば以下のようなテーブルとjoinすると、、、
address | useragent |
---|---|
192.168.1.1 | Mozilla ... |
192.168.1.1 | curl ... |
192.168.1.2 | Mozilla ... |
こうなるはずなんですよね。
Group | address | useragent |
---|---|---|
Office A | 192.168.1.1 | Mozilla ... |
Office A | 192.168.1.1 | curl ... |
Office B | 192.168.1.1 | Mozilla ... |
Office B | 192.168.1.1 | curl ... |
Office C | 192.168.1.2 | Mozilla ... |
Splunkのlookupを使うとそうはならん、という話です。
SplunkのLookupで同じことをすると、、?
以下のように、<search>の部分でGroup-addressのテーブルを作り、lookupで読み込んだaddress-useragentのテーブルと結合すると、、、
<search (Group-address)>
| lookup (address-useragent) address
こーなる。
Group | address | useragent |
---|---|---|
Office A | 192.168.1.1 | Mozilla ..., curl ... |
Office B | 192.168.1.1 | Mozilla ..., curl ... |
Office C | 192.168.1.2 | Mozilla ... |
lookup側からとってきた要素(useragent)について、addressが同じものはmultivalueとして束ねた上で結合されるんですね。。
Lookup結合の厄介なケース
上記のようなシンプルなケースなら、処理後にmvexpand useragen
とすれば、SQLの時と同じ、1行1データの形式に変換できます。
ただ厄介なのが、lookupから持ってくる要素が複数ある場合。
例えば、、
Group | address | useragent | priority |
---|---|---|---|
Office A | 192.168.1.1 | Mozilla ..., curl ... | High, Low |
Office B | 192.168.1.1 | Mozilla ..., curl ... | High, Low |
Office C | 192.168.1.2 | Mozilla ... | High |
これをmvexpand useragent
すると、、、
Group | address | useragent | priority |
---|---|---|---|
Office A | 192.168.1.1 | Mozilla ... | High, Low |
Office A | 192.168.1.1 | curl ... | High, Low |
Office B | 192.168.1.1 | Mozilla... | High, Low |
Office B | 192.168.1.1 | curl ... | High, Low |
Office C | 192.168.1.2 | Mozilla ... | High |
えぇぇ、、、、
じゃぁmvexpand useragent | mvexpand priority
とすると、、
Group | address | useragent | priority |
---|---|---|---|
Office A | 192.168.1.1 | Mozilla ... | High |
Office A | 192.168.1.1 | Mozilla ... | Low |
Office A | 192.168.1.1 | curl ... | High |
Office A | 192.168.1.1 | curl ... | Low |
Office B | 192.168.1.1 | Mozilla | High |
Office B | 192.168.1.1 | Mozilla | Low |
Office B | 192.168.1.1 | curl ... | High |
Office B | 192.168.1.1 | curl ... | Low |
Office C | 192.168.1.2 | Mozilla ... | High |
。。。うん、わかってた。。
一応、eval description=mvzip(useragent, priority, "-") | mvexpand description
とすれば、意図に近いことはできるのだけど、そうじゃないんだよな。。。
Group | address | description |
---|---|---|
Office A | 192.168.1.1 | Mozilla ...-High |
Office A | 192.168.1.1 | curl ...-Low |
Office B | 192.168.1.1 | Mozilla ...-High |
Office B | 192.168.1.1 | curl ...-Low |
Office C | 192.168.1.2 | Mozilla ...-High |
備考 join処理としてみた時の振る舞い
Left outer joinです。
元のserchの結果(上記だと、Group-address)側がLeft。
引数で制御はできないようですので、right outer join相当にしようとすると、かなり泥臭い方法をとらないといけなくなる。。。
inner join化も泥臭行っちゃ泥臭いですが、where NOT isnull(Rightにしかないfield)
を挟めばinner相当のデータに絞り込めます。
まとめ
正しいやり方があるんじゃなかろうかという気はしつつも、現状は思いつかず。
Discussion