2017-05-25 4 views
1

Ich versuche, eine Reihe mit Hilfe von JavaScript in einer älteren Version von Pentaho 4.4) und bekommen einige seltsame Ergebnisse zu manipulieren, die ich nicht erklären kann/nicht verstehen, was Pentaho tutPentaho Javascript - Reihe Manipulation

var test = 'field'; 
Alert (this[test]); //--> Undefined 
Alert (this['field']); // --> Expected result 
Alert (this[test]); //--> Expected Result 

Aus irgendeinem Grund ist die anfängliche Anforderung für this[test] undefiniert, bis ich die literale Zeichenfolgeverweis verwenden, die es unmöglich macht, den Prozess dynamisch zu fahren (dh ich kann auf Zeileninformationen nicht durch Referenzen zugreifen).

Irgendwelche Ideen, warum? Geht Pentaho einfach mit Variablen um? Effektiv möchte ich, dass mein Endergebnis mir erlaubt, den Reihenwert an jeder gegebenen Position zu ändern. Entweder:

row[test] = 'New value 

oder

this[test] = 'New Value 

oder

this[test].setValue('New Value'); 

jedoch keine der oben genannten Arbeiten, ohne die Werte zu ersetzen es einen sehr statischer Prozess.

Antwort

2

Soweit ich sehen kann, fügt Kettle dem Skriptumfang kein Feld hinzu, es sei denn, das Feld ist im Skript-Quellcode als Teilzeichenfolge enthalten (es sollte hinzugefügt werden, selbst wenn das im Kommentar erwähnte Feld). Siehe determineUsedFields() und addValues() Methoden (https://github.com/pentaho/pentaho-kettle/blob/4.4.0/src/org/pentaho/di/trans/steps/scriptvalues_mod/ScriptValuesMod.java#L106).

Das genaue Skript, das Sie angegeben haben, erzeugt also entweder drei definierte Werte oder drei undefinierte Werte, je nachdem, ob das Feld existiert oder nicht. Ich konnte Ihr Problem nur reproduzieren, nachdem ich Strings mit dem Feldnamen vollständig aus dem Code entfernt und den Feldnamen in einem anderen Feld übergeben habe.

Eine Möglichkeit, Zeilenwerte zu manipulieren, könnte darin bestehen, alle Feldnamen im Skript zu erwähnen (z. B. in einem Kommentar), dann versuchen Sie setValue zu verwenden (scheint nur im Kompatibilitätsmodus zu funktionieren).

Ein andere Möglichkeit ist es, die row Array-Variablen zu verwenden, um Werte zu erhalten und getInputRowMeta().indexOfValue(fieldName) den Index des Feldes zu erhalten, zum Beispiel:

var idx = getInputRowMeta().indexOfValue(fieldName) 
// WARNING: you may assign value of any type this way 
// and the value will not be converted to a type defined 
// in the field's ValueMeta: 
row[idx] = 'New value' 

jedoch umgeht dieser Ansatz Typkonvertierungen, die beim Durchgang in der Regel durchgeführt werden, JavaScript-Werte außerhalb des JS-Schritts in getValueFromJScript() Methode.

Zum Beispiel wird der folgende Code ungültigen Wert in der Ausgabe gesetzt, und Sie können es nicht einmal bemerken, bis einige nachfolgenden Schritt wird der Wert in einigen unangebrachter Weise handhaben:

// Let's assume that fieldName is name of the 0th input field. 
// I'd expect, that the value would remain the same 
// but in fact the `fieldName` references some wrapper oject 
// which looks similar to its value 
// but has a different type 
row[0] = fieldName; 

In den folgenden JS Schritt:

for(var i = 0; i < row.length; i++) { 
    Alert(row[i]) // alerts same value as the input, e.g. 'test' 
    Alert(row[i].class) // alerts undefined. While expected is 'java.lang.String' 
    // Some other subsequent steps may crash once this value encountered 
}