9

我正在尝试使用 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.

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

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

我的 step 字段定义如下:

JSON 输入字段定义

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

4

2 回答 2

11

我所做的是使用 JSON Input 使用 $.address[*] 将每个元素 pe 的完整映射读取到 jsonRow 字段:

{"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"} 
]}

这会为每个元素 pe 生成 4 个 jsonRows 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和 getFromMap 函数插入了缩小的 JSON 解析代码:

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]
}
于 2012-03-14T16:17:33.087 回答
3

您可以通过更改 JSONPath 并将步骤拆分为两个 JSON 输入步骤来解决此问题。以下网站对 JSONPath 进行了很多解释:http: //goessner.net/articles/JsonPath/

$..AddressId

实际上返回地址数组中的所有 AddressId,但是由于 Pentaho 使用网格行进行输入和输出 [4 行 x 3 列],因此当您想要返回所有结果时,它无法处理缺失值(即空值) 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

当地址详细信息在地址行中不可用时,这会在四个地址行上产生空值。

于 2013-07-12T14:19:23.723 回答