How to only include a key if the value meets a certain criteria - anypoint-studio

I have this piece of Dataweave code
list_of_orders: {
order: payload map ((payload01 , indexOfPayload01) -> {
order_dtl:
"" when payload01[30] == "S"
otherwise
"" when payload01[30] == "C"
otherwise
[{
data: some_data
}],
order_hdr: {
data: some_data
}
})
}
This code will output the following data
"list_of_orders": {
"order": [
{
"order_dtl": [
{
"data": "some_data"
}
],
"order_hdr": {
"data": "some_data"
}
}
]
}
But it will only do this if payload01[30] != "S" or "C"
If payload01[30] is equal to "S" or "C" then it does this
"list_of_orders": {
"order": [
{
"order_dtl": "",
"order_hdr": {
"data": "some_data"
}
}
]
}
The reason I have done this is because I have been asked to only include the DETAIL line if the order_type is not "C" or "S".
The problem is that the actual key - order_dtl - is still present and I don't want anything there at all.
How do I make a KEY conditional?
Any help appreciated
Thanks

What you are looking is called conditional elements
list_of_orders: {
order: payload map ((payload01 , indexOfPayload01) -> {
(order_dtl:
[{
data: some_data
}]) when((payload01[30] != "S") and (payload01[30] != "C")),
order_hdr: {
data: some_data
}
})
}

Related

Query item in nested array

Customer appointments with top level locationId sample data set:
[
{
"locationId": 9999,
"customerAppointments": [
{
"customerId": "1",
"appointments": [
{
"appointmentId": "cbbce566-da59-42c2-8845-53976ba63d56",
"locationName": "Sullivan St"
},
{
"appointmentId": "5f09e2af-ddae-47aa-9f7c-fd1001a9c5e6",
"locationName": "Oak St"
}
]
},
{
"customerId": "2",
"appointments": [
{
"appointmentId": "964a3c1c-ccec-4082-99e2-65795352ba79",
"locationName": "Kellet St"
}
]
},
{
"customerId": "3",
"appointments": []
}
]
},
{
...
},
{
...
}
]
I need to pull out appointment by locationId and customerId and only get the appointment for that customerId e.g
Sample response:
[
{
"appointmentId": "964a3c1c-ccec-4082-99e2-65795352ba79",
"locationName": "Kellet St"
}
]
Tried below query, but it just returns all records for all customers ids (which is kind of expected):
db.getCollection("appointments").find(
{
"locationId" : NumberInt(9999),
"customerAppointments" : {
"$elemMatch" : {
"customerId" : "2"
}
}
}
);
But how can I get just the appointment record for a specific customerId?
When asking this question I was unaware of the older version of MongoDB driver (< v5) so we cannot use the $getField operator.
However, this query seems to work well:
db.getCollection("appointments").aggregate([
{
$match: {
"locationId": NumberInt(9999)
}
},
{
$unwind: "$customerAppointments"
},
{
$match: {
"customerAppointments.customerId": "2"
}
},
{
$project: {
appointments: "$customerAppointments.appointments"
}
}
]);
Yields:
{
"_id" : ObjectId("63eebe95c7a0da54804c1db2"),
"appointments" : [
{
"appointmentId" : "964a3c1c-ccec-4082-99e2-65795352ba79",
"locationName" : "Kellet St"
}
]
}

How to access json array elements (keys) , values in json nested dictionary type using postgresql?

I have a nested structure json .
How to extract the specific elements(keys) and values?
How to access " sky: selling":"1"
Or "U1":"0000" ?
I tried json_object_keys and json_array_elements for extracting the array .
But I don't know exactly how to do this query.
Example code:
Table- record and column name : report
{
"PIname": {
"n1": "x1",
"n2": "x2",
"params": {
"S1": {
"code1": "y1",
"Code2": "y2",
},
"id": "2d",
"Dest": {
"Code3": "mi"
}
},
"PIDataArea": {
"m1": null,
"PInven": {
"head": {
"Code4": "Increase",
"line": "2020-01"
},
"PILine": [
{
"u1": "0000",
"u2": "0",
"u3": "1",
"modes": {
"#cID": "Sng",
"#txt": "12.21"
} },
{
"Qualify": ".0001",
"QOrder": "1",
"UPriceAmt": {
"#cID": "sng",
"#txt": "13" },
"sky:Qa": ".000",
"sky:Partcode": {
"#c1ID": "a"
},
"sky:SCode": "Ni",
"sky:PItem": {
"sky:ID": "h"
},
"sky:Forest": {
"sky:q1": [
{
"sky:selling": "1"
}
{
"sky:selling": "0"
}
]
} } }} }}
I tried lot ,one example query here like,
Select * from record r
Where exists( select report->'sky: selling' from json_each(r.report) b where b.value->>'sky:selling' Ilike '0');
You can use the json_path_query or jsonb_path_query function. Example to extract the element with key = "sky:selling" :
json_path_query(r.report, $.** ? (#.key == 'sky:selling'))

Karate - filter a specific json key from response based on another static array

I have the following JSON response (reference name: "list") and
[
{
"key": "101",
"val": {
"portCall": {
"id": 12664978
},
"status": "in-port"
}
},
{
"key": "102",
"val": {
"portCall": {
"id": 12415798
},
"status": "in-port"
}
},
{
"key": "103",
"val": {
"status": "on-voyage",
"voyage": {
"id": "7kynv-7lq85"
}
}
},
{
"key": "104",
"val": {
"status": "on-voyage",
"voyage": {
"id": "7kynv-2385"
}
}
}
]
also, I have an array list of few key values, evImos = [101,102,104]
In that, I have to identify the first key in the "list" response that has status as "on-voyage". So, the result should be "104".
I have tried the following and I need some help to make it work. Any help would be appreciated.
* def function getFirst = function(evImos) { for (let num of evImos) { let results = list.filter(d => d["key"] === num && d["val"]["status"] === "on-voyage"); if(results.length === 1) { karate.log(num); return num; } } }
* list.forEach(getFirst(evImos))
I'll just give you one hint. This one line will convert the whole thing in to a form that is much easier for you to validate:
* def temp = {}
* list.forEach(x => temp[x.key] = x.val.status)
Which gives you:
{
"101": "in-port",
"102": "in-port",
"103": "on-voyage",
"104": "on-voyage"
}
Now you can do:
* def isOnVoyage = function(key){ return temp[key] == 'on-voyage' }
Also read this: https://stackoverflow.com/a/59162760/143475
Thanks, to #Peter.
Based on his hint, I just tweaked it a little bit to match my requirement and it worked for me.
Here is the working copy for anyone to refer in the future.
* def temp = {}
* list.forEach(x => temp[x.key] = x.val.status)
* def isOnVoyage = function(keys){ for (let key of keys) { if(temp[key] == 'on-voyage'){ karate.log(key); karate.set('num', key); break; }}}
* isOnVoyage(evImos)

How to get all values where a certain Key matches in Dataweave 2.0?

Payload :
[
{
"Contacts": "123456,098765",
"Emails" : ""
},
{
"Contacts": "ABC123",
"Emails" : ""
}
]
How can I get a list of all emails from the below array of objects where the contact Id matches from each row in the payload? (Expected output below)
Variable accConts
{
"queryResponse": [
{
"Email": "test123#test.com",
"SalesforceId": "123456"
},
{
"Email": "test#test.com",
"SalesforceId": "098765"
},
{
"Email": "ABC#test.com",
"SalesforceId": "ABC123"
}
]
}
Expected Output:
[
{
"Contacts": "123456,098765",
"Emails" : "test123#test.com, test#test.com"
},
{
"Contacts": "ABC123",
"Emails" : "ABC#test.com"
}
]
HTH..
%dw 2.0
output application/json
var qResp ={
"queryResponse": [
{
"Email": "test123#test.com",
"SalesforceId": "123456"
},
{
"Email": "test#test.com",
"SalesforceId": "098765"
},
{
"Email": "ABC#test.com",
"SalesforceId": "ABC123"
}
]
}
---
payload filter ($.Contacts != null) map using (iter = $$) {
"Contacts" : $.Contacts,
"Emails": (qResp.queryResponse filter (payload[iter].Contacts contains $.SalesforceId)) reduce ((item,acc = "") -> (acc ++ "," ++ item.Email)[1 to -1]
)
}
I accepted Salim Khan's answer as he guided me in the right direction and the logic to get emails worked. I just needed to rework the map logic,
payload map (row, index) -> {
"Contacts" : row."Contacts",
"Emails" : (qResp.queryResponse filter (row."Contacts" contains $.SalesforceId)) reduce ((item,acc = "") -> (acc ++ "," ++ item.Email)[1 to -1]
),
}
Hopefully this comaprision helps
Wanted to add a slightly more succinct solution to show another approach.
%dw 2.0
output application/json
var qResp =
{
"queryResponse": [
{
"Email": "test123#test.com",
"SalesforceId": "123456"
},
{
"Email": "test#test.com",
"SalesforceId": "098765"
},
{
"Email": "ABC#test.com",
"SalesforceId": "ABC123"
}
]
}
---
payload map (value) ->
{
'Contacts':value.Contacts,
'Emails': qResp.queryResponse[?(value.Contacts contains $.SalesforceId)]..Email joinBy ", "
}

How to implement group by in Dataweave based on first column in CSV

I have an incoming CSV file that looks like this (notice that the first field is common - this is the order number)
36319602,100,12458,HARVEY NORMAN,
36319602,101,12459,HARVEY NORMAN,
36319602,102,12457,HARVEY NORMAN,
36319601,110,12458,HARVEY NORMAN,
36319601,111,12459,HARVEY NORMAN,
36319601,112,12457,HARVEY NORMAN,
36319603,110,12458,HARVEY NORMAN,
36319603,121,12459,HARVEY NORMAN,
36319603,132,12457,HARVEY NORMAN,
This is my current Dataweave code
list_of_orders: {
order: payload map ((payload01 , indexOfPayload01) -> {
order_dtl:
[{
seq_nbr: payload01[1],
route_nbr: payload01[2]
}],
order_hdr: {
ord_nbr: payload01[0],
company: payload01[3],
city: payload01[4],
}
})
}
An example of the desired output would be something like this ... (this is just mocked up). Notice how I would like a single header grouped by the first column which is the order number - but with multiple detail lines
"list_of_orders": {
"order": [
{
"order_dtl": [
{
seq_nbr: 100,
route_nbr: 12458
},
{
seq_nbr: 101,
route_nbr: 12459
},
{
seq_nbr: 102,
route_nbr: 12457
}
],
"order_hdr":
{
ord_nbr: 36319602,
company: HARVEY NORMAN
}
}
]
}
It works fine except that it is repeating the order_hdr key.
What they would like is a single header key with multiple details beneath.
The grouping is to be based on "ord_nbr: payload01[0]"
Any help appreciated
Thanks
I think you're using Dataweave 1. In dw1, this groupBy gets the desired output(Note you can change the field pointers [0],1 etc to field name mappings if you have them set up as metadata etc):
%dw 1.0
%output application/json
---
list_of_orders: {
order: (payload groupBy ($[0])) map {
order_dtl: $ map {
seq_nbr: $[1],
route_nbr: $[2]
},
order_hdr:
{
ord_nbr: $[0][0],
company: $[0][3]
}
}}
UPDATE
Here is the output for the new input sample with multiple orders:
{
"list_of_orders": {
"order": [
{
"order_dtl": [
{
"seq_nbr": "110",
"route_nbr": "12458"
},
{
"seq_nbr": "121",
"route_nbr": "12459"
},
{
"seq_nbr": "132",
"route_nbr": "12457"
}
],
"order_hdr": {
"ord_nbr": "36319603",
"company": "HARVEY NORMAN"
}
},
{
"order_dtl": [
{
"seq_nbr": "100",
"route_nbr": "12458"
},
{
"seq_nbr": "101",
"route_nbr": "12459"
},
{
"seq_nbr": "102",
"route_nbr": "12457"
}
],
"order_hdr": {
"ord_nbr": "36319602",
"company": "HARVEY NORMAN"
}
},
{
"order_dtl": [
{
"seq_nbr": "110",
"route_nbr": "12458"
},
{
"seq_nbr": "111",
"route_nbr": "12459"
},
{
"seq_nbr": "112",
"route_nbr": "12457"
}
],
"order_hdr": {
"ord_nbr": "36319601",
"company": "HARVEY NORMAN"
}
}
]
}
}