Filtering vales in Dataweave - filtering

I am trying to filter out vales matching a variable using dataweave.
result = {
"drives": [{
"id": "0AEBByqXZ0xb4Uk9PVA",
"name": "QA-zz-SFJobs-Contacts"
}, {
"id": "0AC_FdkeL63mHUk9PVA",
"name": "QA"
}]
}
above is my payload.
Am trying below code
%dw 2.0
output application/json
---
{
drives: payload.result.drives[0] filter ((item, index) -> item.name == "QA")
}
which gives me error
error:
You called the function 'Value Selector' with these arguments:
1: String ("{"drives":[{"id":"0AEBByqXZ0xb4Uk9PVA","name":"QA-zz-SFJobs-Contact...)
2: Name ("drives")
But it expects one of these combinations:
(Array, Name)
(Array, String)
(Date, Name)
(DateTime, Name)
(LocalDateTime, Name)
(LocalTime, Name)
(Object, Name)
(Object, String)
(Period, Name)
(Time, Name)
5| drives: payload.result.drives[0] filter ((item, index) -> item.name == vars.folderName)
^^^^^^^^^^^^^^^^^^^^^
Trace:
at filter (line: 5, column: 13)
at main (line: 5, column: 38)" evaluating expression: "%dw 2.0
output application/json
{
drives: payload.result.drives[0] filter ((item, index) -> item.name == vars.folderName)
}".
Expected output:
{
"id": "0AC_FdkeL63mHUk9PVA",
"name": "QA"
}
how can i achieve this?

The input should be a valid "JSON" like :
{
"result": {
"drives": [{
"id": "0AEBByqXZ0xb4Uk9PVA",
"name": "QA-zz-SFJobs-Contacts"
},
{
"id": "0AC_FdkeL63mHUk9PVA",
"name": "QA"
}]
}
}
Here applying the logic above :
{
drives: payload.result.drives[0]
}
returns output as :
{
"drives": {
"id": "0AEBByqXZ0xb4Uk9PVA",
"name": "QA-zz-SFJobs-Contacts"
}
}
which is a single object containing object, and hence filter method cannot be applied as filter is applicable on arrays and arrays of objects.
To try your dataweave code snippet you can use the online dataweave editor :
Online Dataweave Editor
which can give you better insights.

As #Bibek mentioned, you need a properly formatted json as input:
{
"result": {
"drives": [{
"id": "0AEBByqXZ0xb4Uk9PVA",
"name": "QA-zz-SFJobs-Contacts"
},
{
"id": "0AC_FdkeL63mHUk9PVA",
"name": "QA"
}]
}
}
And then you can use filter on an array (drives), so your query would be:
%dw 2.0
output application/json
---
payload.result.drives filter ((item, index) -> item.name == "QA")
If you use "drives[0]" you are selecting the first element in the array, so, you don't need to use filter (unless the first element also contains an array inside of it, which is not the case)

Related

DynamoDB PartiQL Request Parameter In Select

I am attempting to use PartiQL to query a set of data that looks like this:
{
"userId": {
"S": "someuserID"
},
"mapWithData": {
"M": {
"1": {
"M": {
"neededVal": {
"S": "A Needed Value1"
},
"name": {
"S": "A Name1"
}
}
},
"2": {
"M": {
"neededVal": {
"S": ""A Needed Value12"
},
"name": {
"S": "A Name2"
}
}
}
}
},
"userName": {
"S": "someuserName"
}
}
I am developing this query using the NoSQL Workbench. I want to use a Request Parameter in the query to get a specific object from the mapWithData based on its key value. For instance, if I wanted to get the n-th value from the map, I could use this query:
SELECT "mapWithData"."N"."neededVal"
FROM "some-table"
WHERE "userId" = 'someuserID'
But I would like to be able to make the "N" and the 'someruserID' into Request Parameters to prevent any PartiQL injections (assuming the Request Parameters are actually cleansed). So what I'm trying to do is this:
SELECT "mapWithData".?."neededVal"
FROM "some-table"
WHERE "userId" = ?
This does not work unfortunately and I get this error:
Execute PartiQL statement failed: Validation Error: Statement wasn't well formed, can't be processed: Invalid path dot component
So then I tried to use a different format like this:
SELECT "mapWithData"[ ? ]["neededVal"]
FROM "some-table"
WHERE "userId" = ?
But when I do that, I get this error:
Execute PartiQL statement failed: Validation Error: Unexpected path component at 1:23:1
Is it possible to include a ? for inserting request parameters in the SELECT part of this statement? Is there another way to do this that I'm missing?
#Francis, sure you can do that: if you use the PythonSDK to implement it you can write:
table_name = 'mytable'
someruserID =
stmt = f"SELECT * FROM {table_name} WHERE userId=?"
pmt =[{
"S": userId
}]
resp = dynamodb.execute_statement(
Statement=stmt , Parameters= pmt
)
Hope that helps. A

use JsLookup for multiple level array using play Json for lists with objects and simple lists

i have a function that exctract from a json list of elements based on the path i give it.
the func looks like this:
def findAllValuesAtPath(jsValue: JsObject, path: String): List[JsValue] = {
val jsPath = JsPath(path
.split("\\[\\*]\\.")
.flatMap(s => s.split("\\.")
.map(RecursiveSearch)
).toList)
jsPath(jsValue)
}
for example:
{
"person": {
"kids": [
{
"name": "josh",
"age": 5
},
{
"name": "julia",
"age": 13
}
]
}
}
now if i give the path - "person.kids[*].name" I will get list of their names List("josh", "julia") which its what i want.
but if the list of kids were just simple list like:
{
"person": {
"kids": [
"josh",
"julia"
]
}
}
and i will give the path - "person.kids[*]" I will get empty list List() and I want to get this as List("josh", "julia") (without the brakets)
do you see any way to improve my func to handle both cases?

mongodb $ causing error The positional operator did not find the match needed from the query

I’ve been trying to update the data in my mongoDB.
I want to update all products with a new productName field.
my data looks something like:
{
"id": "12345",
"products": [{
"id": 0
"productCode": "test",
"status": "PENDING",
},
{
"id": 1
"productCode": "test",
"status": "COMPLETE",
}],
}
When I try the following. I get this error The positional operator did not find the match needed from the query.
db.customers.updateMany(
{ id: "12345" },
{ $set: {
"products.$.productName": "Name here" }
}
)
If I do account.0.productName then it’s fine and updates. I’m not sure why $ is not working for me
db.customers.updateMany(
{ id: "12345" },
{ $set: {
"products.0.productName": "Name here" }
}
)
Positional operator is not working because you are not using the array into the find (first object)
If you try this query it will work as expected because you have the position finding by products.id.
Otherwise, if you don't have the position into array where update, yo can't use $ operator in this way. You need this query:
db.collection.update({
"id": "12345",
},
{
"$set": {
"products.$[].newField": "test2"
}
},
{
"multi": true
})
Mongo playground example here
Using $[] you can reference the array and add the value into each object.
$[] docs here
It says:
The all positional operator $[] indicates that the update operator should modify all elements in the specified array field.
That's exactly we want :)

How to convert inner json part into object in dart/flutter

I need to convert every element of 'content' array to object.
Here is json:
{
"content": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"author": {
"userId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
},
"createDate": "2020-01-30T20:18:29.764Z",
"executor": {
"userId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
},
}
],
"first": true,
"numberOfElements": 0,
}
The problem is that 'content' array is inside json, and its parts as executor and author has to be objects too, and I don't know how to reach it and parse.
How it can be done? Any help, thanks.
You access the elements like this:
var decoded = json.decode(j);
var inner = decoded['content'][0]; // if you expect more than one entry, iterate the list
print(inner['id']); // -> 3fa85f64-5717-4562-b3fc-2c963f66afa6
print(inner['createDate']);
print(inner['author'].runtimeType); // another Map<String, dynamic> as expected
print(inner['author']['userId']);
You can create Dart classes to model, for example, a 'user' if you want.

Decode a nested array with circe-optics

I have JSON like this:
"data": {
"project": {
"activityChildren": [
{
"id": 2,
"parents": [
{
"id": 1
}
]
},
]
}
}
I'd like to decode this to List[(Long, List[Long])] with circe-optics. I got as far as:
val activityParents: Map[Long, List[Long]] = root.data.activityChildren.each.json
.getAll(json)
.flatMap { activity =>
root.id.long.getOption(activity).map(_ -> root.parents.each.long.getAll(activity))
}
.toMap
I wonder whether it's possible to define a single lens for this that just turns the JSON into the desired map without explicitly mapping over the intermediate array. If so, how?