Pig 實現關鍵詞匹配
Pig是一種資料流語言和執行環境,用於檢索非常大的資料集。為大型資料集的處理提供了一個更高層次的抽象。Pig包括兩部分:一是用於描述資料流的語言,稱為Pig Latin;二是用於執行Pig Latin程式的執行環境。 |
收集日誌avro資料中有兩個Map欄位appInstall、appUse分別表示已安裝的app、正在使用的app,且key值為app的名稱,value值為app使用資訊。現在要得到一份匹配上購物類app支付寶|京東|淘寶|天貓的使用者名稱單;MapReduce 解決辦法如下:
public static class M extends Mapper{ Text text = new Text(); @SuppressWarnings("unchecked") @Override protected void map(String key, Pair value, Context context) throws IOException, InterruptedException { Map data = value.fields.data; String dvc = data.get("dvc").toString(); MapappInstall = (Map) data.get("appInstall"); MapappUse = (Map) data.get("appUse"); for(String app: appInstall.keySet()) { if(app.matches("支付寶|京東|淘寶|天貓")) { text.set(appInstall.keySet().toString()); context.write(dvc, text); return; } } for(String app: appUse.keySet()) { if(app.matches("支付寶|京東|淘寶|天貓")) { text.set(appUse.keySet().toString()); context.write(dvc, text); return; } } } }
但是,如果要匹配遊戲類的app、金融類的app類呢?如果匹配關鍵詞發生了變化呢?顯然,我們應該將匹配關鍵詞開放成API,可以自由地匹配正規表示式。這時,pig派上了用場。
A = load '//' using org.apache.pig.piggybank.storage.avro.AvroStorage(); -- A: {key: chararray,value: (fields: (data: map[]))} B = foreach A generate value.fields.data#'dvc' as dvc, value.fields.data#'appInstall' as ins:map[], value.fields.data#'appUse' as use:map[]; -- B: {dvc: bytearray,ins: map[],use: map[]} C = foreach B generate dvc, KEYSET(ins) as insk, KEYSET(use) as usek; -- C: {dvc: bytearray,insk: {(chararray)},usek: {(chararray)}}
在上述程式碼中,load 資料轉換得到bag型別的app-set(insk與usek);但是,應如何遍歷bag中的tuple與正規表示式做匹配呢?答案是UDF。
Apache DataFu Pig 提供了豐富的UDF,其中關於bags的UDF可以參看這裡。TupleFromBag 提供根據index從bag提取tuple,支援三個輸入引數。依葫蘆畫瓢,遍歷bag匹配正規表示式的UDF如下:
package com.pig.udf.bag; /** * This UDF will return true if one tuple from a bag matches regex. * * There are two input parameter: * 1. DataBag * 2. Regex String */ public class BagMatchRegex extends FilterFunc { @Override public Boolean exec(Tuple tinput) throws IOException { try{ DataBag samples = (DataBag) tinput.get(0); String regex = (String) tinput.get(1); for (Tuple tuple : samples) { if(((String) tuple.get(0)).matches(regex)){ return true; } } } catch (Exception e) { return false; } return false; } }
其中,FilterFunc為過濾UDF的基類,繼承於EvalFunc,即exec(Tuple tinput)的返回值必為Boolean型別。bag正則匹配的pig 指令碼如下:
REGISTER ../piglib/udf-0.0.1-SNAPSHOT-jar-with-dependencies.jar define BagMatchRegex com.pig.udf.bag.BagMatchRegex(); A = load '/user/../current/*.avro' using org.apache.pig.piggybank.storage.avro.AvroStorage(); B = foreach A generate value.fields.data#'dvc' as dvc, value.fields.data#'appInstall' as ins:map[], value.fields.data#'appUse' as use:map[]; C = foreach B generate dvc, KEYSET(ins) as insk, KEYSET(use) as usek; D = filter C by BagMatchRegex(insk, '支付寶|京東|淘寶|天貓') or BagMatchRegex(usek, '支付寶|京東|淘寶|天貓');
還有沒有可以做優化的地方呢?我們先來看看pig中的KEYSET實現:
package org.apache.pig.builtin; public class KEYSET extends EvalFunc{ private static final TupleFactory TUPLE_FACTORY = TupleFactory.getInstance(); @SuppressWarnings("unchecked") @Override public DataBag exec(Tuple input) throws IOException { if(input == null || input.size() == 0) { return null; } Mapm = null; // Input must be of type Map. This is verified at compile time m = (Map)(input.get(0)); if(m == null) { return null; } DataBag bag = new NonSpillableDataBag(m.size()); for (String s : m.keySet()) { Tuple t = TUPLE_FACTORY.newTuple(s); bag.add(t); } return bag; } ... }
需要指出的一點——pig的map資料型別是由Java類Map實現的。從KEYSET原始碼中可以看出在呼叫時已經將map遍歷了一次,然後在呼叫BagMatchRegex時又需要將key-set的bag再遍歷一次。其實,完全可以只用一次遍歷做map-key值的正則匹配:
package com.pig.udf.map; /** * This UDF will return true if map's key matches regex. * * There are two input parameter: * 1. Map * 2. Regex String */ public class KeyMatchRegex extends FilterFunc { @SuppressWarnings("unchecked") @Override public Boolean exec(Tuple input) throws IOException { try{ Mapm = null; // Input must be of type Map. This is verified at compile time m = (Map)(input.get(0)); String regex = (String) input.get(1); for (String key : m.keySet()) { if(key.matches(regex)){ return true; } } } catch (Exception e) { return false; } return false; } }
原文地址: https://www.linuxprobe.com/pig-keyword-matching.html
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31559985/viewspace-2678142/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 匹配關鍵詞和敏感詞
- 高亮:單關鍵詞、多關鍵詞、多組多關鍵詞,從簡單到複雜實現滿足多方面需求的頁面關鍵詞高亮
- JavaScript new 關鍵詞解析及原生實現 newJavaScript
- 關鍵詞加粗和插入關鍵詞
- 【python】百度關鍵詞排名查詢實現Python
- Mysql 如何實現全文檢索,關鍵詞跑分MySql
- 微信小程式實現搜尋關鍵詞高亮微信小程式
- VVICAPI介面解析,實現根據關鍵詞取商品列表API
- robot 關鍵詞
- 關鍵詞提取
- 網站關鍵詞堆砌後,處理關鍵詞堆砌方法網站
- java—— finall 關鍵詞Java
- 什麼是長尾關鍵詞?如何找到長尾關鍵詞?
- NLP segment-03-基於 TF-IDF 實現關鍵詞提取 java 開源實現Java
- 如何在 Excel 外掛 PowerPivot 中實現詞根模糊匹配Excel
- 什麼是關鍵詞策略?網站關鍵詞佈局重要嗎?網站
- 如何優化多個關鍵詞?分享多關鍵詞優化心得優化
- 分享五步網站優化技巧實現關鍵詞排名首頁網站優化
- 直播平臺搭建,uni-app 實現搜尋關鍵詞高亮效果APP
- 作用域鏈this關鍵詞
- Eclipse註釋關鍵詞Eclipse
- 關鍵詞感知檢索
- transient關鍵詞的概述
- 20190118-利用Python實現Pig Latin遊戲Python遊戲
- Trie|如何用字典樹實現搜尋引擎的關鍵詞提示功能
- Java關鍵詞synchronized解讀Javasynchronized
- 關鍵路徑JS實現JS
- AI繪畫怎麼寫關鍵詞?AI繪畫高畫質桌布關鍵詞分享AI
- 雙向最大匹配演算法——基於詞典規則的中文分詞(Java實現)演算法中文分詞Java
- Hive常用命令,快鍵和關鍵詞Hive
- 直播電商平臺開發,uni-app 實現搜尋關鍵詞高亮效果APP
- [譯] 深入淺出 JavaScript 關鍵詞 -- thisJavaScript
- 如何用Python提取中文關鍵詞?Python
- 從JavaScript 的關鍵詞談起JavaScript
- 正規表示式關鍵詞解析
- SnowNLP——獲取關鍵詞(keywords(1))
- JavaFx 關鍵字高亮文字實現Java
- 實現 MongoDB 外來鍵關聯MongoDB