How can we paginate a big hash? - ruby

I have a pure ruby hash like the following one:
"1875": {
"child1": {
"field1": 1875,
"field2": "Test1"
},
"child2": {
"field1": "value1",
"field2": "value2"
}
},
"1959": {
"child1": {
"field1": 1875,
"field2": "Test1"
},
"child2": {
"field1": "value1",
"field2": "value2"
}
}
I have so many keys that follow the above structure that I want to paginate it.
I have tried the following code:
#records = #records.t_a.paginate(page: params[:page], per_page: 5)
But it is returning me all the elements in an array, like this:
["1875", {
"child1": {
"field1": 1875,
"field2": "Test1"
},
"child2": {
"field1": "value1",
"field2": "value2"
}
}
]
["1959", {
"child1": {
"field1": 1875,
"field2": "Test1"
},
"child2": {
"field1": "value1",
"field2": "value2"
}
}
]

First of all, note that a Hash is a dictionary-like collection and order shouldn't mater. So if you need to use pagination most likely a hash is the wrong data structure to use and you should use something like an array.
#records.t_a.paginate(page: params[:page], per_page: 5) returns an array because you are converting the hash to array with to_a. Depending what you are using the hash/pagination for this may be enough. For example, to display a the returned records assuming there is a function for printing child:
#records.t_a.paginate(page: params[:page], per_page: 5).each |key, value| do
<h1><%= book.title %></h1>
<p>print_child(value)</p>
If you really want a hash, you can convert the Array back to a hash:
Hash[#records.t_a.paginate(page: params[:page], per_page: 5)]

Related

Transform array of values to array of key value pair

I have a json data which is in the form of key and all values in a array but I need to transform it into a array of key value pairs, here is the data
Source data
"2022-08-30T06:58:56.573730Z": [
{ "tag": "AC 3 Phase/7957", "value": 161.37313113545272 },
{ "tag": "AC 3 Phase/7956", "value": 285.46869739695853 }
]
}
Transformation looking for
[
{ "tag": "AC 3 Phase/7957",
"ts": 2022-08-30T06:58:56.573730Z,
"value": 161.37313113545272
},
{ "tag": "AC 3 Phase/7956",
"ts": 2022-08-30T06:58:56.573730Z,
"value": 285.46869739695853
}
]
I would do it like this:
$each($$, function($entries, $ts) {
$entries.{
"tag": tag,
"ts": $ts,
"value": value
}
}) ~> $reduce($append, [])
Feel free to play with this example on the playground: https://stedi.link/g6qJGcP

How to use JSONpath to extract specific values

I'm using JSONpath to try and find data with an array of JSON objects but I'm struggling to get to the information I want. The array contains many objects similar to below where there are values for RecID throughout. If I use $..RecID I get them all when I only want the first Key.RecID of each object (with a value 1338438 in this example). Is there a way to only extract the top level Key.RecID value?
BTW I'm trying to do this in jMeter and I'm assuming JSONpath is the best way to do what I want but if there is a better way I'd be happy to hear about it.
Thanks in advance
[{
"Key": {
"RecID": 1338438
},
"Users": [{
"FullName": "Miss Burns",
"Users": {
"Key": {
"Name": "Burns",
"RecID": 1317474
}
}
},
{
"FullName": "Mrs Fisher",
"Users": {
"Key": {
"Name": "Fisher",
"RecID": 1317904
}
}
}
],
"User": {
"FullName": "Mrs Fisher",
"Key": {
"Name": "Fisher",
"RecID": 1317904
}
},
"Organisation": {
"Key": {
"RecID": 1313881
}
}
}]

Strapi Graphql query with filtering/conditional rendering

In my Strapi project, i'm trying to write a Graphql query that filters posts by an array of tags.
The post has to belong to all tags of the given array.
E.g. the post below would not meet the condition if given array is [1,2,3] but would pass the condition if array is [3,5].
Any help would be much appreciated
Example Post:
{
"id": "1",
"title": "Lorem Iopsum",
"created_at": "2021-02-19T22:53:19.204Z",
"tags": [
{
"id": "3",
"tag": "Porte De Gentily"
},
{
"id": "5",
"tag": "Bridges"
},
{
"id": "6",
"tag": "Towers"
}
]
}
I was trying something like:
query {
posts( where: {tags: {id_contains: [3,1]}}) {
title
tags{id},
created_at
}
}
You can do it something like this
query($ids:[ID]) {
posts( where: {tags: {id:$ids}}) {
title
tags{id},
created_at
}
}
And pass your ids as a query variable:
{
"ids": [1,5]
}

How to loop through a nested array and retrieve values

I have the following array:
my_tst = [
[
{
"name": "shield",
"version": "8.6.3"
},
{
"name": "bosh-dns",
"version": "1.17.0"
},
{
"name": "nessus_agent",
"version": "1.0.24"
},
{
"name": "node-exporter",
"version": "4.2.0"
},
{
"name": "syslog",
"version": "11.6.1"
}
],
[
{
"name": "shield",
"version": "8.6.3"
},
{
"name": "bosh-dns",
"version": "1.16.0"
},
{
"name": "nessus_agent",
"version": "1.0.24"
},
{
"name": "node-exporter",
"version": "4.2.0"
},
{
"name": "syslog",
"version": "11.6.1"
}
]
]
I am trying to loop through the array and output only the values of name.
I used this loop:
my_tst["name"].each do |run|
p run
end
The loop is returning an Error:
TypeError: no implicit conversion of String into Integer
How do I output all values in the nested array?
You're trying to use [] in an array, which is meant to be used passing a numeric parameter in order to access its elements by their index. You're passing a string, which is the way you get values from hashes, and there's the problem.
You have an array of arrays containing hashes (with an interesting indentation), so in that case you need to first iterate the "main" array, to be able to get the hashes over each array.
This is one way you can achieve that:
my_tst.each_with_object([]) do |e, arr|
e.each { |f| arr << f[:name] }
end
# ["shield", "bosh-dns", "nessus_agent", "node-exporter", "syslog", "shield", "bosh-dns", "nessus_agent", "node-exporter", "syslog"]
Or:
data.flat_map do |e|
e.map { |f| f[:name] }
end
Anyway, there's going to be a nested iteration.

Logstash 5.0 Ruby Filter Can't Update Hash in Array

I'm a newbie to both Logstash and Ruby, and I meet a subtle problem today.
My input JSON like the following:
{
"1": "1",
"2": "2",
"market": [
{
"id": "1",
"name": "m1"
},
{
"id": "2",
"name": "m2"
}
]
}
My filter is like the following code, and I want to set event["1"] to m1, event["2"] to m2, event["market"][0]["id"] to m1, event["market"][1]["id"] to m2:
filter {
......
ruby {
code => "
markets = event.get('market')
markets.each_index do |index|
event.set(markets[index]['id'], markets[index]['name'])
markets[index]['id'] = markets[index]['name']
end
"
}
......
}
And the output is following:
{
"1": "m1",
"2": "m2",
"market": [
{
"id": "1",
"name": "m1"
},
{
"id": "2",
"name": "m2"
}
]
}
The event["1"] and event["2"] get the expected values, but the event["market"][0]["id"] and event["market"][1]["id"] do not, and I want to know why? The desired output should be:
{
"1": "m1",
"2": "m2",
"market": [
{
"id": "m1",
"name": "m1"
},
{
"id": "m2",
"name": "m2"
}
]
}
PS: The logstash I'm using is version 5.0.
I think it is because of the new Event API introduced in the Logstash 5.0. After changing my filter to the following, I get the desired output:
filter {
......
ruby {
code => "
markets = event.get('market')
markets.each_index do |index|
event.set(markets[index]['id'], markets[index]['name'])
markets[index]['id'] = markets[index]['name']
end
event.set('market', markets) // comment: adding this setter in the filter
"
}
......
}
According to Logstash Git Issue, "Mutating a collections after setting it in the Event has an undefined behaviour".

Resources