I have a group of records being returned by an Active Record query. I need to somehow iterate over these to build an array of hashes that sort of looks like:
[
{ '15/01/2013': 3 },
{ '24/051/2012': 1 },
{ '08/07/2015': 22 }
]
The records returned will be in the form of having 3 records for the first, 1 record for the second and 22 records for the 3rd. I basically need a way to transform that into a simple hash like above.
Here's an example of my DB output:
[
{
"item_id": 21728,
"id": 31731,
"notes": "sample",
"date": "2014-09-12",
"created_at": "2015-08-13T15:16:06.074Z",
"updated_at": "2015-08-13T15:16:06.074Z"
},
{
"item_id": 21728,
"id": 31732,
"notes": "sample",
"date": "2014-09-12",
"created_at": "2015-08-13T15:16:06.104Z",
"updated_at": "2015-08-13T15:16:06.104Z"
},
{
"item_id": 21728,
"id": 31733,
"notes": "sample",
"date": "2014-09-13",
"created_at": "2015-08-13T15:16:06.112Z",
"updated_at": "2015-08-13T15:16:06.112Z"
}
]
Let's say your DB results are stored in an array called results.
results.group_by(&:date).map{|k,v| {k => v.count}}
This, first groups your DB results according to their dates and then counts how many objects correspond to each date.
Related
I am trying to figure out cypher query in order to get nested JSON structure as a result. Below I present an example of the graph.
MATCH (user:User {name:"User_1"})
OPTIONAL MATCH (user)-[rel*]->(subUser:User)
RETURN *
Query above allows me to get all the nodes and relationships required to transform everything to JSON structure I want but that requires me to process everything after getting the result from querying the database. To achieve that I need to match identity of nodes and relationship in order to get the nested JSON.
I was wondering if it is possible to achieve that directly from building cypher query.
Important thing is that we do not know how many levels of "child" Users we have starting from User_1
Expected JSON structure:
{
"user": "User_1",
"children": [
{
"user": "User_2",
"children": [
{
"user": "User_5",
"children": []
}
]
},{
"user": "User_3",
"children": [
{
"user": "User_6",
"children": []
}
]
},{
"user": "User_4",
"children": []
}
]
}
Is it possible?
As suggested in the comments by #nimrod serok, you can use the apoc.convert.toTree method, it will give you the tree-structured JSON, as desired, with one caveat, the keys of the JSON will be different. For the data:
MERGE (u1:User{name: 'User1'})
MERGE (u2:User{name: 'User2'})
MERGE (u3:User{name: 'User3'})
MERGE (u4:User{name: 'User4'})
MERGE (u5:User{name: 'User5'})
MERGE (u6:User{name: 'User6'})
MERGE (u1)-[:POINTS]->(u2)-[:POINTS]->(u5)
MERGE (u1)-[:POINTS]->(u3)-[:POINTS]->(u6)
MERGE (u1)-[:POINTS]->(u4)
The query:
MATCH (user:User {name:"User1"})
OPTIONAL MATCH path = (user)-[:POINTS*]->(subUser:User)
WITH collect(path) AS paths
CALL apoc.convert.toTree(paths, true, {nodes: {User: ['name']}})
YIELD value
RETURN value
produces the output:
{
"_type": "User",
"name": "User1",
"_id": 4,
"points": [
{
"_type": "User",
"name": "User3",
"_id": 6,
"points": [
{
"_type": "User",
"name": "User6",
"_id": 9
}
]
},
{
"_type": "User",
"name": "User2",
"_id": 5,
"points": [
{
"_type": "User",
"name": "User5",
"_id": 8
}
]
},
{
"_type": "User",
"name": "User4",
"_id": 7
}
]
}
as you can see, the relationship type POINTS, comes in place of children, and the key name comes for the user name. The other fields _type and _id can be ignored.
apoc.convert.toTree() is certainly the best answer for the question you asked.
If one is interested in a text output then ORDPATH would be another solution. ORDPATH is a concatenated bitstring which sorts in hierarchical order. More on this at this link. A Neo4j user defined function implementing this is at GitHub.
There is already an existing CouchDB database which was created based on existing records from a MySQL database.
I have a set of documents like this:
[
{
"_id": "lf_event_users_1247537_11434",
"_rev": "1-19e90d3f19e9da7cc5adab44ebbe3894",
"TS_create": "2018-12-17T10:29:20",
"emm_id": 204662,
"eu_user_id": 201848611,
"type": "lf_event_users",
"uid": 1247537,
"vendor_id": 11434
},
{
"_id": "lf_event_users_1247538_11434",
"_rev": "1-0d0d1e9f1fb5aad9bafd4c53a6cada17",
"TS_create": "2018-12-17T10:29:20",
"emm_id": 204661,
"eu_user_id": 201848611,
"type": "lf_event_users",
"uid": 1247538,
"vendor_id": 11434
},
{
"_id": "lf_event_users_1247539_11434",
"_rev": "1-09bc2bfc709ee9c6e6cac9cb34964ac4",
"TS_create": "2018-12-17T10:29:20",
"emm_id": 204660,
"eu_user_id": 201848611,
"type": "lf_event_users",
"uid": 1247539,
"vendor_id": 11434
}
]
As you can see, all of them are for the same "eu_user_id" = 201848611, and each one has a different "emm_id".
Now, I have another set of document like this in the same CouchDB database:
[
{
"_id": "lf_event_management_master_204660_11434",
"_rev": "2-320111a3814a3efd6838baa0fb5412bb",
"emm_disabled": "n",
"emm_title": "Scanned for local delivery",
"settings": {
"event_view": "ScannedForLocalDeliveryEvent",
"sort_weight": 0
},
"type": "lf_event_management_master",
"uid": 204660,
"vendor_id": 11434
},
{
"_id": "lf_event_management_master_204661_11434",
"_rev": "2-e6d6ebbd4dc4ca473a376d3d16a58e93",
"emm_disabled": "n",
"emm_title": "Local Delivery Cancelled",
"settings": {
"event_view": "CancelDeliveryEvent",
"sort_weight": 4
},
"type": "lf_event_management_master",
"uid": 204661,
"vendor_id": 11434
},
{
"_id": "lf_event_management_master_204662_11434",
"_rev": "2-53cb3d3eba80704e87ea5ff8d5c269df",
"emm_disabled": "n",
"emm_title": "Local Delivery Exception",
"settings": {
"event_view": "DeliveryExceptionEvent",
"sort_weight": 3
},
"type": "lf_event_management_master",
"uid": 204662,
"vendor_id": 11434
}
]
As you can see, each document in this last set has a "uid" matching the "emm_id" in the previous set of documents. Basically this means:
A "user" has many allowed "events".
You can see also that the documents of type "lf_event_management_master" has no "eu_user_id" value or any other key matching this.
My question is:
How can I get all documents of type "lf_event_management_master" allowed for user "201848611" in a single query?
In my case, I only have the User ID (201848611) available at the point where I need to get the allowed events. Currently what is happening is:
I get all the "lf_event_users" records for this user.
Loop all results from previous query and build a new query, extracting this time to find all the "lf_event_management_master" where the "uid" includes any of the "emm_id" values found with the previous query.
Thank you in advance.
For the Discovery REST api, the argument/parameter "return" controls which fields are returned.
So if I pass these arguments to the API
{
"query": named_sector,
"count": "10",
"filter": filter_dates,
"aggregation" : "term(docSentiment.type,count:3)"
}
my_query = discovery.query(my_disc_environment_id, my_disc_collection_id, qopts)
print(json.dumps(my_query, indent=2))
I get the following:
{
"matching_results": 14779,
"aggregations": [
{
"type": "term",
"field": "docSentiment.type",
"count": 3,
"results": [
{
"key": "positive",
"matching_results": 4212
},
{
"key": "negative",
"matching_results": 3259
},
{
"key": "neutral",
"matching_results": 152
}
]
}
],
"results": [
{
"id": "6389715fe7e7f711e0bc09d4f1236639",
"score": 1.3689895,
"yyyymm": "201704",
"url": "https://seekingalpha.com/article/4060446-valuation-dashboard-consumer-discretionary-update",
"enrichedTitle": null,
"host": "seekingalpha.com",
"text": "Valuation Dashboard: Consumer Discretionary - Update\n\nSummary\n\nValuation metrics in Consumer Discretionary.\n\nEvolution since last month.\n\nA list of stocks loo ....
and thousands of more lines. How do I restrict the output to the aggregations section? Is this an issue of me better handling the JSON structure that is returned?
thanks
If you change the count argument to 0, the returned JSON will only contain the aggregations.
Also, if you're using the Discovery web tooling, you can enter 0 for the "Number of results to return (Count)" field.
More details and an example can be found here: https://www.ibm.com/watson/developercloud/doc/discovery/using.html#building-aggregations
I have a simple "rss" (ApplicationRecord) table indexed by an id. I would like to have a structured JSON that group each user from a family in an array structure. And then each family in a global array. How can I do that ?
my current plain code to put my data in a json file is :
json.rss #rss do |rs|
json.id rs.id
json.name rs.name
json.family rs.family
json.lastdate rs.lastdate
json.last rs.last
json.s1w rs.s1w
json.s2w rs.s2w
end
But the target file that I want is this one :
{
"rss": [
{
"familyname": "Smith",
"children": [
{
"id": "1",
"name": "bob",
"lastdate": "2010-09-23",
"last": "0.88",
"s1w": "0.83",
"s2w": "0.88"
},
{
"id": 2,
"name": "Mary",
"lastdate": "2011-09-23",
"last": "0.89",
"s1w": "0.83",
"s2w": "0.87"
}
]
},
{
"familyname": "Wesson",
"children": [
{
"id": "1",
"name": "john",
"lastdate": "2001-09-23",
"last": "0.88",
"s1w": "0.83",
"s2w": "0.88"
},
{
"id": 2,
"name": "Bruce",
"lastdate": "2000-09-23",
"last": "0.89",
"s1w": "0.83",
"s2w": "0.87"
}
]
}
]
}
The grouping you are trying to achieve can be done in Ruby with:
#rss.group_by(&:family).values
This is assuming #rss is an array-like collection of objects that have a .family method. The result: is an array of arrays of objects grouped by family.
Now it will be up to use to use Jbuilder's array! method to build the desired JSON output.
I'm using Magical Record to import data returned from a webservice. Following is the json
{
"notes": null,
"logged_on": "2014-08-08",
"updated_at": "2014-08-08T15:33:25-04:00",
"user_id": 876,
"url": "https://august.roundtriptohealth.com/entries/5006",
"is_logged": true,
"id": 5006,
"entry_recording_activities": [
{
"recording_activity_id": 1,
"updated_at": "2014-08-08T16:39:19-04:00",
"url": "https://august.roundtriptohealth.com/entry_recording_activities/5006",
"recording_activity": {
"type_of_prompt": "textbox",
"updated_at": "2014-07-10T15:55:14-04:00",
"options": [],
"regex_validation": {
"message": "Up to three digits",
"name": "three_digits",
"regex": "^(\\d){1,3}$",
"display": "0 to 999"
},
"url": "https://august.roundtriptohealth.com/recording_activities/1",
"name": "Exercise Minutes",
"id": 1,
"cap_value": 360,
"summary": null,
"created_at": "2013-11-01T11:50:36-04:00",
"content": "**30+ minutes = 1 point**\n\nChoose a physical activity that elevates your heart, increases your breathing, and can be sustained for 30 minutes or more.\n\nWhen you and your Travel Companion log this activity the **same day**, you earn a bonus point and can visit a new attraction.",
"cap_message": "You have exceeded the maximum number of minutes."
},
"entry_id": 5006,
"id": 5006,
"value": "37",
"created_at": "2014-07-14T23:41:04-04:00"
},
{
"recording_activity_id": 1,
"updated_at": "2014-08-08T15:33:24-04:00",
"url": "https://august.roundtriptohealth.com/entry_recording_activities/16131",
"recording_activity": {
"type_of_prompt": "textbox",
"updated_at": "2014-07-10T15:55:14-04:00",
"options": [],
"regex_validation": {
"message": "Up to three digits",
"name": "three_digits",
"regex": "^(\\d){1,3}$",
"display": "0 to 999"
},
"url": "https://august.roundtriptohealth.com/recording_activities/1",
"name": "Exercise Minutes",
"id": 1,
"cap_value": 360,
"summary": null,
"created_at": "2013-11-01T11:50:36-04:00",
"content": "**30+ minutes = 1 point**\n\nChoose a physical activity that elevates your heart, increases your breathing, and can be sustained for 30 minutes or more.\n\nWhen you and your Travel Companion log this activity the **same day**, you earn a bonus point and can visit a new attraction.",
"cap_message": "You have exceeded the maximum number of minutes."
},
"entry_id": 5006,
"id": 16131,
"value": "45",
"created_at": "2014-08-08T15:33:24-04:00"
},
{
"recording_activity_id": 37,
"updated_at": "2014-08-08T15:33:24-04:00",
"url": "https://august.roundtriptohealth.com/entry_recording_activities/16132",
"recording_activity": {
"type_of_prompt": "checkbox",
"updated_at": "2014-07-30T13:42:27-04:00",
"options": [],
"regex_validation": null,
"url": "https://august.roundtriptohealth.com/recording_activities/37",
"name": "Eat 2 Different Colored Fruit Servings",
"id": 37,
"cap_value": null,
"summary": "You’ll make a couple of colorful choices on this week’s Tour Bus.",
"created_at": "2013-11-08T10:17:55-05:00",
"content": "By spreading daily choices across the rainbow of colors, you’ll get the best produce has to offer — vitamins, minerals, fiber, and phytochemicals — for better health and energy. Have at least 2 fruit servings (2 cups), each from a different color group: red, orange, yellow/white, green, and blue/violet.",
"cap_message": null
},
"entry_id": 5006,
"id": 16132,
"value": null,
"created_at": "2014-08-08T15:33:24-04:00"
}
],
"created_at": "2014-08-08T15:33:24-04:00"
}
I can import top level object with method:
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
if ([responseObject isKindOfClass:[NSArray class]]) {
[Entry importFromArray:responseObject inContext:localContext];
}
}];
However, the second level (inside array entry_recording_activities) doesn't import. I've declared entries in data model file. The top level object named "Entry". You can see from the image.
The second level object is as follow:
The relatedByAttribute and relationships are set also. So how can I import data to many entries (from top level to lower level object)?
Click on the activities property. Under your relatedByAttribute, add 'mappedKeyName', and add the nested path. In this case, entry_recording_activities.
The basic problem is you've defined how to auto-connect the data, but have not told the import library where the data is relative to the start of the import.