使用JSON输入步骤处理不均匀的数据

时间:2012-02-22 15:37:12

标签: json pentaho kettle data-integration

我正在尝试使用JSON输入步骤处理以下内容:

{"address":[
  {"AddressId":"1_1","Street":"A Street"},
  {"AddressId":"1_101","Street":"Another Street"},
  {"AddressId":"1_102","Street":"One more street", "Locality":"Buenos Aires"},
  {"AddressId":"1_102","Locality":"New York"}
]}

然而,这似乎不可能:

Json Input.0 - ERROR (version 4.2.1-stable, build 15952 from 2011-10-25 15.27.10 by buildguy) : 
The data structure is not the same inside the resource! 
We found 1 values for json path [$..Locality], which is different that the number retourned for path [$..Street] (3509 values). 
We MUST have the same number of values for all paths.

该步骤提供了 Ignore Missing Path 标志,但它仅在所有行都错过相同路径时才有效。在这种情况下,步骤按预期运行,用null填充缺失值。

这限制了此步骤读取不均匀数据的能力,这实际上是我的优先事项之一。

我的步骤字段定义如下:

JSON Input Fields definition

我错过了什么吗?这是正确的行为吗?

2 个答案:

答案 0 :(得分:11)

我所做的是使用$ .address [*]的JSON输入来读取每个元素的完整地图的jsonRow字段p.e:

{"address":[
    {"AddressId":"1_1","Street":"A Street"},  
    {"AddressId":"1_101","Street":"Another Street"},  
    {"AddressId":"1_102","Street":"One more street", "Locality":"Buenos Aires"},   
    {"AddressId":"1_102","Locality":"New York"} 
]}

这导致每个元素有4个jsonRows,p.e。 jsonRow = {"AddressId":"1_101","Street":"Another Street"}。然后使用Javascript步骤我使用以下方法映射我的值:

var AddressId = getFromMap('AddressId', jsonRow);
var Street = getFromMap('Street', jsonRow);
var Locality = getFromMap('Locality', jsonRow);

在第二个脚本选项卡中,我插入了来自https://github.com/douglascrockford/JSON-js的缩小JSON解析代码和getFromMap函数:

function getFromMap(key,jsonRow){
  try{
   var map = JSON.parse(jsonRow);
  }
  catch(e){
   var message = "Unparsable JSON: "+jsonRow+" Desc: "+e.message;
   var nr_errors = 1;
   var field = "jsonRow";
   var errcode = "JSON_PARSE";
   _step_.putError(getInputRowMeta(), row, nr_errors, message, field, errcode);
   trans_Status = SKIP_TRANSFORMATION;
   return null;
  }

  if(map[key] == undefined){
   return null;
  }
  trans_Status = CONTINUE_TRANSFORMATION;
  return map[key]
}

答案 1 :(得分:2)

您可以通过更改JSONPath并在两个JSON输入步骤中拆分步骤来解决此问题。以下网站解释了很多关于JSONPath的内容:http://goessner.net/articles/JsonPath/

$..AddressId

实际上是否返回地址数组中的所有AddressId,但是因为Pentaho正在使用网格行进行输入和输出[4行x 3列],所以当你想要结果时,它无法处理缺失值aka null值返回所有Streets(3行)并返回所有Locality(2行),原因很简单,因为数组本身没有空值,因为你不能通过汽车上的3个轮子驱车出你的车库而不是通常4。

我猜你的脚本返回null(其中X为零)值如:

A S X
A S X
A S L
A X L

通过将第一个JSONinput步骤的Fields路径更改为:

,可以避免编写脚本步骤
$.address[*]

这是检索所有4个地址行。根据新的源字段创建下一个JSONinput步骤,该新字段包含用于检索每行地址详细信息的地址行:

$.AddressId
$.Street
$.Locality

当地址行中没有地址详细信息时,这会在四条地址线上产生空值。