2012-02-22 33 views
6

Tôi đang cố gắng để xử lý sau đây với một bước Input JSON:Sử dụng JSON bước đầu vào để xử lý dữ liệu không đồng đều

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

Tuy nhiên điều này dường như không thể:

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. 

Bước cung cấp Bỏ qua đường dẫn thiếu nhưng chỉ hoạt động nếu tất cả các hàng đều bỏ lỡ cùng một đường dẫn. Trong trường hợp đó, bước hoạt động như mong đợi sẽ lấp đầy các giá trị bị thiếu bằng null.

Điều này giới hạn sức mạnh của bước này để đọc dữ liệu không đồng đều, thực sự là một trong những ưu tiên của tôi.

Fields bước của tôi được định nghĩa như sau:

JSON Input Fields definition

Tôi có thiếu cái gì? Đây có phải là hành vi đúng không?

Trả lời

10

Những gì tôi đã làm là sử dụng JSON Input sử dụng $ .address [*] để đọc cho một lĩnh vực jsonRow bản đồ đầy đủ của mỗi pe yếu tố:

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

Điều này dẫn đến 4 jsonRows một cho mỗi yếu tố, pe jsonRow = {"AddressId":"1_101","Street":"Another Street"}. Sau đó, sử dụng một bước Javascript tôi ánh xạ giá trị của tôi sử dụng này:

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

Trong tab kịch bản thứ hai tôi chèn được rút gọn mã JSON phân tích cú pháp từ https://github.com/douglascrockford/JSON-js và chức năng 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] 
} 
+0

sẽ rất tuyệt nếu bạn có thể sao chép các phần tử trả lời ở đây từ liên kết của bạn :) (và chấp nhận câu trả lời của riêng bạn) – redben

+1

Xong! Câu trả lời có hữu ích cho bạn không? – rsilva4

+0

ít nhất nó hoạt động hoàn hảo cho tôi. cảm ơn bạn! –

1

Bạn có thể giải quyết việc này bằng cách thay đổi JSONPath và chia nhỏ các bước trong hai bước nhập JSON. Các trang web sau đây giải thích rất nhiều về JSONPath: http://goessner.net/articles/JsonPath/

$..AddressId 

Liệu trên thực tế trả lại tất cả của AddressID trong mảng địa chỉ, NHƯNG từ Pentaho là sử dụng hàng lưới cho đầu vào và đầu ra [4 hàng x 3 cột], nó có thể 't xử lý một giá trị còn thiếu aka giá trị null khi bạn muốn kết quả trả về tất cả các đường phố (3 hàng) và trả về tất cả các địa phương (2 hàng), đơn giản vì không có giá trị null trong mảng chính nó như trong bạn không thể lái xe ra khỏi nhà để xe của bạn với 3 bánh xe trên xe của bạn thay vì bình thường 4.

Tôi đoán tập lệnh của bạn trả về giá trị rỗng (trong đó X là số không) như:

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

Bước kịch bản có thể tránh được bằng cách thay đổi cùng một con đường Fields của bước JSONinput đầu tiên vào:

$.address[*] 

Điều này là để lấy tất cả 4 dòng địa chỉ. Tạo một bước JSONinput tiếp theo dựa trên các lĩnh vực nguồn mới, trong đó có dòng địa chỉ (s) để lấy các chi tiết địa chỉ trên mỗi dòng:

$.AddressId 
$.Street 
$.Locality 

này mang lại các giá trị null trên bốn dòng địa chỉ khi một chi tiết địa chỉ không phải là có sẵn trong một dòng địa chỉ.

+0

Tôi đã thử nghiệm đề xuất của bạn. Không may mắn, vẫn thất bại. Kiểm tra nó ra ở đây http://pastebin.com/8Ez68rpV – rsilva4

+0

Hi rsilva, bạn đã đúng. Tôi chỉ thực hiện công việc này, bằng cách sử dụng một bước đầu vào json đầu tiên để có được tất cả các dòng địa chỉ và một số khác để lấy Street/AddressId và địa phương nếu có: http://pastebin.com/iRqNJMPF – bsecker

+0

Điều này làm việc tốt cho tôi và có vẻ thanh lịch hơn câu trả lời được chấp nhận. Chấp nhận một nên làm việc quá, nhưng nó đẹp hơn để tránh Javascripting theo cách của bạn để giải pháp khi có thể. – codemonkey

Các vấn đề liên quan