问题描述
我正在尝试连接两个表,其中表 1 中的列“包含”来自表 2 中一列的数据,即考虑以下假设:
-
表error_log:
id| description 1 | this is right,bla bla,bla 2 | this is,bla,wrong 3 | this is,a disaster,bla 4 | bla,bla
-
表格result_type:
id|type 1|Right 2|Wrong 3|disaster
现在,我想连接这两个表并将结果存储在第三个表中,即
-
表格分析:
id|error_log_id|result_type_id 1 | 1 | 1 2 | 2 | 2 3 | 3 | 3 4 | 4 | null
通常,在任何 RDBMS 中,我可以使用具有类似条件的左连接轻松完成此操作,即
select e.error_log_id,r.result_type_id from error_log e
left join result_type r on e.description like '%'+ r.type +'%'
但我似乎无法通过 snaplogic 找到这样做?我试过 Snap Join,但它只提供 equals join 条件,即
非常感谢任何建议。
解决方法
假设 result_type
中的记录数不会经常变化并且比 error_log
中的记录数少很多,您可以使用 In-memory Lookup
snap 而不是Join
快照。除此之外,使用常规快照没有直接的方法来做到这一点。我建议尽可能在数据库中进行复杂的查询。以下是使用 Script
snap 的实现。
样本管道
内存查找
添加一个名为 join_id
(或其他)的字段,其值为 1
(或其他),并基于该字段在查找中加入。这将在所有传入文档中添加整个查找(在您的情况下为类型)。
脚本
try { load("nashorn:mozilla_compat.js"); } catch(e) { }
importPackage(com.snaplogic.scripting.language);
importClass(java.util.ArrayList);
importClass(java.util.LinkedHashMap);
var impl = {
input : input,output : output,error : error,log : log,execute : function () {
this.log.info("Executing Transform Script");
while (this.input.hasNext()) {
try {
var inDoc = this.input.next();
var outDocs = new ArrayList();
var errorLogId = inDoc.id;
var description = inDoc.description;
var types = inDoc.types;
var flag = false;
for(var idx in types) {
var type = types[idx];
if(description.toLowerCase().contains(type.type.toLowerCase())) {
var outDoc = new LinkedHashMap();
outDoc.put('error_log_id',errorLogId);
outDoc.put('result_type_id',type.id);
outDocs.add(outDoc);
}
}
if(outDocs.isEmpty()) {
var outDoc = new LinkedHashMap();
outDoc.put('error_log_id',errorLogId);
outDoc.put('result_type_id',null);
outDocs.add(outDoc);
}
for(var idx in outDocs) {
var outDoc = outDocs[idx];
this.output.write(inDoc,outDoc);
}
}
catch (err) {
var errDoc = new LinkedHashMap();
errDoc.put("error",err);
this.log.error(err);
this.error.write(errDoc);
}
}
this.log.info("Script executed");
},cleanup : function () {
this.log.info("Cleaning up")
}
};
var hook = new com.snaplogic.scripting.language.ScriptHook(impl);
输出
,这是正确的 snap,尝试将“Join type”更改为相关值,例如 Outer。