I have objects that look like:
[<ltree_val: "1", contents: "blah">,
<ltree_val: "1.1", contents: "blah">,
<ltree_val: "1.1.1", contents: "blah">,
<ltree_val: "2", contents: "blah">,
<ltree_val: "2.1", contents: "blah">]
Where ltree_val determines their tree structure.
I need to generate something like...
[{ "data" : "1",
"children" :
[{ "data" : "1.1",
"children" :
[{ "data" : "1.1.1" }]
}]
},
{ "data" : "2" }]
Where I have children which are determined by an ltree value, which are themselves elements of the same object.
If I sort these objects by their ltree value, how can I create nested entries?
I'm open to either RABL or JBuilder. I'm totally lost.
The answer was to use a recursive function...
# encoding: UTF-8
def json_ltree_builder( json, ltree_item )
json.title t( ltree_item.title )
json.attr do
json.id ltree_item.id
end
json.metadata do
json.val1 ltree_item.val1
json.val2 ltree_item.val2
end
children = ltree_item.children
unless children.empty?
json.children do
json.array! children do |child|
json_ltree_builder( json, child )
end
end
end
end
json.array! #menu_items do |menu_item|
json_ltree_builder( json, menu_item )
end
This builds something like
[
{ "title":"Title 1",
"attr" : {
"id": 111
},
"data" : {
"val1" : "Value 1",
"val2" : "Value 2"
},
"children" : [
{
"title":"Child 1",
"attr" : {
"id": 112
},
"data" : {
"val1" : "Value 1",
"val2" : "Value 2"
}
},
{
"title":"Child 2",
"attr" : {
"id": 112
},
"data" : {
"val1" : "Value 1",
"val2" : "Value 2"
}
}
]
}
]
Related
I have a set of Author nodes. An Author node is the single parent of multiple Book nodes.
My goal: To print all Author nodes with no order and no limit, with each authors' first three books in alphabetical order.
Desired output: (let's pretend book names are a single letter)
[
{
"name" : "Leo Tolstoy",
"books": [
{ "name": "A" },
{ "name": "B" },
{ "name": "D" }
]
},
{
"name": "Charles Dickens",
"books": [
{ "name": "C" },
{ "name": "E" },
{ "name": "F" }
]
},
{
"name": "Oscar Wilde
...
]
My Problem:
I tried this:
MATCH(author:Author)
WITH author
OPTIONAL MATCH(author)-[:WROTE]->(book:Book)
WITH author, book
ORDER BY book.name
LIMIT 3
WITH author, collect(book) AS books
RETURN collect (
{
name: author.name,
books: books
}
);
But this gives:
[
{
"name" : "Leo Tolstoy",
"books": [
{ "name": "A" },
{ "name": "B" },
]
},
{
"name": "Charles Dickens",
"books": [
{ "name": "C" }
]
}
]
How could I achieve my desired output in Neo4j v3.5?
[EDITED]
This should work:
MATCH(author:Author)
OPTIONAL MATCH(author)-[:WROTE]->(book:Book)
WITH author, book.name AS bookName
ORDER BY bookName
WITH author, COLLECT({name: bookName})[..3] AS bookNames
RETURN COLLECT({name: author.name, books: bookNames}) AS result
Hi guys I am having trouble to find out a solution to a problem.So I have an array like bellow.
{
"9": [
{
"id": "9",
"day": "2017-08-02",
"voltage": "3397.1"
},
{
"id": "9",
"day": "2017-08-01",
"voltage": "11518.67"
},
{
"id": "9",
"day": "2017-07-31",
"voltage": "12835.5900000002"
}
],
"11": [
{
"id": "11",
"day": "2017-08-02",
"voltage": "910.21"
},
{
"id": "11",
"day": "2017-08-01",
"voltage": "3616.43"
},
{
"id": "11",
"day": "2017-07-31",
"voltage": "2085.37"
}
],
"12": [
{
"id": "12",
"day": "2017-08-02",
"voltage": "4793.96"
},
{
"id": "12",
"day": "2017-08-01",
"voltage": "17762.2999999998"
},
{
"id": "12",
"day": "2017-07-31",
"voltage": "18334.4000000001"
}
]
}
Now what I want to do is to produce an array like below
{
"9": [
"day": ["2017-08-02", "2017-08-01", "2017-07-31"],
"voltage": ["3397.1", "11518.67", "12835.5900000002"]
],
"11": [
"day": ["2017-08-02","2017-08-01", "2017-07-31"]
"voltage": ["910.21", "3616.43", "2085.37"]
]
...
}
and so on.
I have tried to iterate over the array using .each and .map method but it didn't work.I search trough existing solutions in stackoverflow but nothing helps me out.
Can some one help me with this.
Thanks so much in advance.
If you define hash as the original object you can do it with reduce like so:
result = hash.reduce({}) do |memo, (key, vals)|
memo[key] = {
"day" => vals.map { |val| val[:day] },
"voltage" => vals.map { |val| val[:voltage] }
}
memo
end
You can also do it with just each:
result = {}
hash.each do |key, vals|
result[key] = {
"day" => vals.map { |val| val[:day] },
"voltage" => vals.map { |val| val[:voltage] }
}
end
I am unsure if you are writing your hash as JSON or Ruby, but I didn't have time to rewrite it to Ruby, to I just copy pasted it into a script, which made all the keys be symbols.
I believe this should be working:
new_hash = {}
current_hash.each do |key, value_array|
new_hash[key] ||= {}
value_array.each do |values|
new_values = values.dup
new_values.delete(:id)
new_values.each do |attribute_name, attribute_value|
new_hash[key][attribute_name] ||= []
new_hash[key][attribute_name] << attribute_value
end
end
end
Which gives me this result:
{:"9"=>{:day=>["2017-08-02", "2017-08-01", "2017-07-31"], :voltage=>["3397.1", "11518.67", "12835.5900000002"]}, :"11"=>{:day=>["2017-08-02", "2017-08-01", "2017-07-31"], :voltage=>["910.21", "3616.43", "2085.37"]}, :"12"=>{:day=>["2017-08-02", "2017-08-01", "2017-07-31"], :voltage=>["4793.96", "17762.2999999998", "18334.4000000001"]}}
One more solution from me :)
For Ruby 2.4.0:
hash.transform_values do |values|
values.each_with_object({}) do |value, memo|
memo[:day] ? memo[:day] << value[:day] : memo[:day] = [value[:day]]
memo[:voltage] ? memo[:voltage] << value[:voltage] : memo[:voltage] = [value[:voltage]]
end
end
And for earlier:
hash.map do |key, values|
[
key,
values.each_with_object({}) do |value, memo|
memo[:day] ? memo[:day] << value[:day] : memo[:day] = [value[:day]]
memo[:voltage] ? memo[:voltage] << value[:voltage] : memo[:voltage] = [value[:voltage]]
end
]
end.to_h
I'm looking to grab the image 'src' within this JSON response, but my trying has left me at a loose end. Any help would be brilliant.
My Model
def test
response = self.class.get("URLFORRESPONSE")
#elements = response.parsed_response["extractorData"]
#parsed = #elements.collect { |e| e['src'] }
end
JSON Response
{
"extractorData" : {
"url" : "http://testwebsite.com/",
"resourceId" : "409417ee21618b70d74b03231a793c2d7",
"data" : [ {
"group" : [ {
"image" : [ {
"src" : "test0.jpg"
} ]
}, {
"image" : [ {
"src" : "test1.jpg"
} ]
}, {
"image" : [ {
"src" : "test2.jpg"
} ]
}, {
"image" : [ {
"src" : "test3.jpg"
} ]
}, {
"image" : [ {
"src" : "test4.jpg"
} ]
}
Your JSON is invalid. It should be:
{
"extractorData": {
"url": "http://testwebsite.com/",
"resourceId": "409417ee21618b70d74b03231a793c2d7",
"data": [{
"group": [{
"image": [{
"src": "test0.jpg"
}]
}, {
"image": [{
"src": "test1.jpg"
}]
}, {
"image": [{
"src": "test2.jpg"
}]
}, {
"image": [{
"src": "test3.jpg"
}]
}, {
"image": [{
"src": "test4.jpg"
}]
}]
}]
}
}
To extract the src's:
#parsed = #elements['data'][0]['group'].map{| g | g['image'][0]['src'] }
I know this is ugly as hell but i hope this sugestion helps.
Since HTTParty.parsed_response returns a hash and assuming you're using ruby 2.3, you can do:
#elements = response.parsed_response["extractorData"]
#elements.dig('data').collect{|h| h.dig('group').collect{|h| h.dig('image').collect{|h| h.dig('src')}}}
see it:
h = {"extractorData"=>{"url"=>"http://testwebsite.com/", "resourceId"=>"409417ee21618b70d74b03231a793c2d7", "data"=>[{"group"=>[{"image"=>[{"src"=>"test0.jpg"}]}, {"image"=>[{"src"=>"test1.jpg"}]}, {"image"=>[{"src"=>"test2.jpg"}]}, {"image"=>[{"src"=>"test3.jpg"}]}, {"image"=>[{"src"=>"test4.jpg"}]}]}]}}
h.dig('extractorData', 'data').collect{|h| h.dig('group').collect{|h| h.dig('image').collect{|h| h.dig('src')}}}
=> [[["test0.jpg"], ["test1.jpg"], ["test2.jpg"], ["test3.jpg"], ["test4.jpg"]]]
I have model named Shop which has name, image. There is possibility that there will be multiple shops with the same name.
For example if I have these shops:
[{_id: "1", name: "Shop A", image: "ImageShopA.jpg"},
{_id: "2", name: "Shop A", image: "ImageShopA1.jpg"},
{_id: "3", name: "Shop B", image: "ImageShopB.jpg"},
{_id: "4", name: "Shop B", image: "ImageShopB1.jpg"},
{_id: "5", name: "Shop C", image: "ImageShopC.jpg"}]
I want to get this kind of result:
[{name: "Shop A", ids: ["1", "2"], image: "ImageShopA.jpg"},
{name: "Shop B", ids: ["3", "4"], image: "ImageShopB.jpg"},
{name: "Shop C", ids: ["5"], image: "ImageShopC.jpg"}]
It creates JSON Objects which has ids of grouped models which are grouped by name and get image of first found model.
Is it possible to do that with aggregation?
Yes, its possible. If you run the following aggregation pipeline in mongo shell with the given data sample
db.collection.aggregate([
{
"$sort": {
"_id": 1
}
},
{
"$group": {
"_id": "$name",
"ids": {
"$push": "$_id"
},
"image": {
"$first": "$image"
}
}
},
{
"$project": {
"name": "$_id", "ids": 1, "image": 1
}
}
])
you will get the desired results:
/* 0 */
{
"result" : [
{
"_id" : "Shop C",
"ids" : [
"5"
],
"image" : "ImageShopC.jpg",
"name" : "Shop C"
},
{
"_id" : "Shop B",
"ids" : [
"3",
"4"
],
"image" : "ImageShopB.jpg",
"name" : "Shop B"
},
{
"_id" : "Shop A",
"ids" : [
"1",
"2"
],
"image" : "ImageShopA.jpg",
"name" : "Shop A"
}
],
"ok" : 1
}
You would need to convert this to the appropriate ruby implemenation
I've implemented as_json in the parent model as follows:
def as_json(options = {})
options[:include] = :items
super(options)
end
include_root_in_json = true is set in the configuration.
What I GET is:
[
{
"order": {
"items": [
{
"key1": "value1"
},
{
"key1":"value2"
}
],
"key1": "value1"
}
}
]
But what I WANT is this:
[
{
"order": {
"items": [
{
"item": {
"key1": "value1"
}
},
{
"item": {
"key1": "value2"
}
}
],
"key1": "value1"
}
}
]
So the root name is not included for nested associations. Is that a bug or am I missing something?
As far as i can tell "include_root_in_json" does not work for nested attributes but only on the very root like:
[
{
"videos": {
"video": [
"id": 1
]
}
}
]
For this example it would remove the "videos" root.
Tip
I found that as_json is not really good if you are building something like an API where you need to be very flexible sometimes. For that reason i am using RABL, mabye you should give it a try https://github.com/nesquena/rabl