问题
I am trying to create a spec that will take input
abc:true
abc: {strings ...}
and output:
abc:true
abc: {strings ...}
I know this shouldn't require a Jolt shift, I just have to include it so that segment of my data (both abc
keys) transfers over and doesn't get lost,
Does anyone know what to add to a Jolt shift spec to do this (shift 2 duplicate keys based on their value types).
回答1:
For the jolt processor, when you try to add key mappings that are already existing, the application will yell at you for it. However in your case, it would seem that you are dealing with two different types of memory storage, where 1 is an array, the other is a variable. The processor seems to take precedence with the arrays over the single values for some reason but fret not, there are plenty of work-a-rounds to this.
The first and most obvious solution is passing
"@":"&"
within the array index ofabc
. According to the documentation of wildcards in the shift operations of jolt processors ,@
being on the left hand side of:
stands for putting the passed key as an index.&
being on the right hand side of:
stands for the value associated at this passed index (A dereference if you will).
Together this will pull all information associated with the passed key. However, this would include a duplication of all your array values, which in most cases goes against your reasoning to remap its index's in the first place.
- The second solution, and perhaps most ideal would be a remapping of the variables. According to the wildcard documentation, the
#
allows for a referencing of information. On the right hand side of a:
, its used to pull an index based on the number of matches found while backtracking through its array information. The left hand side has far more use in our case which allows us to hardcode a map of an instance value to a new field
Take the code
"foo" :{
"bar" : {
"#lemonade" : "drinks"
}}
Upon the instance of bar being spotted as a tangible value to field "foo", you would then be mapping a value called "lemonade" to a field called "drinks". This will allow you to handle the instance where abc
is being outputted differently than your standard array. However, this is a hard coding and as such it can not be casted to the Boolean values that you were initially seeking.
The third and most ideal solution is a rather sneaky way of circumventing this issue which is to create a separate index with the fields you want to cast to. For reference and clarification to this technique, see here. Take the following code:
[{ "operation" : "default", "spec":{ "ref":{ "True" : true, "False": false } } }, { "operation" : "shift", "spec":{ "abc":{ "true":{ "@(3,ref.true)":"abc" }, "false":{ "@(3,ref.false)":"abc" } } } }, { "operation" : "remove", "spec":{ "ref" : "" } }]
What we are doing here is at the start of the jolt processor, we are making a reference index called ref, which we pass values of Boolean true and false to it for later use. We move on to the shift operation which we then proceed to do what we did in example 2, by starting to indicate what we do when this particular value occurs within the parent header, but instead we use an additional function of @
to trace back into the tree 3 parents, and use the reference values of the fields True
and False
to attach the necessary Booleans to the field abc
. It tidy's everything up by removing the ref
field so all that you are left with is the correct mapping of abc
.
This method, if not the most elegant, not only circumvents the initial issue, but it preserves data type and could perhaps be extended to handle a variety of other values like integers or even doubles, however further testing and research would be required for such endeavors.
来源:https://stackoverflow.com/questions/44144846/json-jolt-shift-specification-for-duplicate-keys-with-different-value-types