jsonata filter by "outside" property - jsonata

I need to filter values of list2 by property of list1 as such:
JSON:
{
"list1": [
{"b":1, "list2": [{"a":1},{"a":2},{"a":3}]},
{"b":2, "list2": [{"a":1},{"a":2},{"a":3}]},
{"b":3, "list2": [{"a":1},{"a":2},{"a":3}]}
]
}
JSONata:
{
"result": $$.list1.{
"v": list2[a=b].{
"v":a
}
}
}
The issue is - I don't know how to reference b property of list1 in filter list2[a=b]
https://try.jsonata.org/dxPC5s-zM
Expected result is:
{
"result": [
{"v":1},
{"v":2},
{"v":3}
]
}
I know example is "stupid" but it simply illustrate problem.
I was wondering if some temp variables could be used to solve it?
Thank you!

ok I found solution with temp. variables:
JSONata:
{
"result": $$.list1.(
$b := b; /* temp var. */
{
"v": list2[a=$b].{
"v":a
}
})
}

You can use the 'parent' operator to reference this 'outside' property. So if you are within the context of the list2 array, you can refer to the 'b' property of list1 using:
list1.list2[a = %.b]
See https://docs.jsonata.org/path-operators#-parent

Related

Laravel - Convert list object to key value

I have a list object like:
"my_list":
[
{
"id": 1,
"name": A
},
{
"id": 2,
"name": B
},
]
I want to convert to key - value like:
my_list = {
1: 'A',
2: 'B'
}
How can I do that? Does anyone have solution?
Please help, thanks!
Cast it to Laravel collection and use mapWithKeys()
$keyed = collect($my_list)->mapWithKeys(function ($item) {
return [$item['id'] => $item['name']];
});
If you need to convert it to object then:
$keyed = (object)$keyed->toArray();
You can use array helper methods combines with array_combine():
(object)array_combine(Arr::pluck($my_list, 'id'), Arr::pluck($my_list, 'name'));

Logstash filter out values with null values for a key in a nested json array

I have quite an extensive Logstash pipeline ending in a Json as such:
{
"keyA": 1,
"keyB": "sample",
"arrayKey": [
{
"key": "data"
},
{
"key": null
}
]
}
What I want to achieve is to filter "arrayKey" and remove objects within with value for "key" is null.
Tried this to no luck:
filter {
ruby {
code => "
event.get('arrayKey').each do |key|
[key].delete_if do |keyCandidate|
if [keyCandidate][key] != nil
true
end
end
end
"
}
}
This gives no implicit converter found from |hash|:|Int| error. How do I achieve this? Is there and easier way to do this?
As Aleksei pointed out, you can create a copy of the array that does not contain entries where [key] is null using reject. You have to use event.set to overwrite the inital value of [arrayKey]
ruby {
code => '
a = event.get("arrayKey")
if a
event.set("arrayKey", a.reject { |x| x["key"] == nil })
end
'
}

How to use ReQL filter and match command on arrays

I have a table in rethinkdb where each row has following structure -
{
'name':'clustername',
'services':[
{
'name':'service1'
},
{
'name':'service2'
}
]
}
I am running a query to filter service2 object like this
r.table('clusters').filter({"name": "clustername"})
.pluck('services').filter((service) => {
return service("name").match('service2')
})
But this is not returning anything: No results were returned for this query
Can anyone tell why this is happening?
pluck returns sequence, so this query:
r.table('clusters').filter({"name": "clustername"}).pluck('services')
will return:
{
"services": [
{
"name": "service1"
} ,
{
"name": "service2"
}
]
}
You need get services field from it, it will return array with services field of items found by filter.
And after that you need to use your second filter on each item by using map.
So, correct query:
r.table('clusters').filter({"name": "clustername"}).pluck('services')("services").map(item => {
return item.filter(service => {
return service("name").match("service2");
});
})

Create or append to an array in a rethinkdb document

How should we append an item to an array if the array exists, or create an array and insert to it.
I tried the merge command but that doesn't allow merging arrays, only replacing them.
r.db('testdb').table('users').get('27e55a4a-a6f8-4ec9-bd02-f55f206700ff').merge({ 'hobbies':['Reading'] })
I further tried passing a function but doesnt seem to work:
r.db('testdb').table('users').get('27e55a4a-a6f8-4ec9-bd02-f55f206700ff').merge(function(user) {
return r.branch(user('hobbies').eq(null),
{ 'hobbies' : ['Reading'] }
user('hobbies').append('Reading'))
});
Consider the below doc structure:
{
"email": email.123#gmail.com, »
"id": "27e55a4a-a6f8-4ec9-bd02-f55f206700ff" ,
"image": https://lh4.googleusercontent.com/-O4ZXcLRpkHE/AAArAAAAAAAI/AdAAAAAAALMM/Fq968TTkd88Y/photo.jpg?sz=50, »
"name": "John Doe"
}
If I would like to add hobbies as an array how should I do it. The query has to work both if the hobby array exists or not.
The most idiomatic way would be .update(function(user) { return {hobbies: user('hobbies').default([]).append('reading')}; })
Finally I have figured out myself.
r.db('testdb').table('users')
.get("27e55a4a-a6f8-4ec9-bd02-f55f206700ff")
.update(function(user){
return r.branch(user.hasFields('hobbies'),
{ hobbies: user('hobbies').append('reading')},
{ hobbies : ['reading']}
)})

Complex array in Ruby

I need to create this structure in ruby
{
"list": {
"ownerList" : [ {
"owner" : "Nacho",
"list" : "MyList"
},
{
"owner" : "Nacho2",
"list" : "MyList2"
}
]
}
}
but I'm not sure how to create a multientry array in ruby. Any ideas?
my_hash = {
owner_list: [
{
owner: "Nacho",
list: "MyList"
},
{
owner: "Nacho",
list: "MyList"
},
]
}
This creates a hash with the data you want. You can then very easily transform it to a json if you like and make operations over it.

Resources