using ruby json library to parse json data into a hash some keys missing - ruby

lets say I have this json data file
{
"page": {
"title": "Example Page"
},
"employers": {
"name": "Jon"
},
"employees": [
{ "name": "Mike", "nicknames": ["Superman"] },
{ "name": "Peter", "nicknames": ["Peet", "Peetee", "Peterr"] }
]
}
this data.json file exist as a file outside of the script
I have these 3 lines to read and parse it with json ruby library
data = File.read("data.json")
obj = JSON.parse(data)
puts obj.values
in my terminal it comes out to be like this
{"title"=>"Example Page"}
{"name"=>"Jon"}
{"name"=>"Mike", "nicknames"=>["Superman"]}
{"name"=>"Peter", "nicknames"=>["Peet", "Peetee", "Peterr"]}
what happened to employers and employees? now I have the same key or name in this case. Its difficult for me to grab the values to use them.

Employers and employees are the keys for primary hash, and you requested values, that's why you get what you get. Try putting obj .

Related

Match keys with sibling object JSONATA

I have an JSON object with the structure below. When looping over key_two I want to create a new object that I will return. The returned object should contain a title with the value from key_one's name where the id of key_one matches the current looped over node from key_two.
Both objects contain other keys that also will be included but the first step I can't figure out is how to grab data from a sibling object while looping and match it to the current value.
{
"key_one": [
{
"name": "some_cool_title",
"id": "value_one",
...
}
],
"key_two": [
{
"node": "value_one",
...
}
],
}
This is a good example of a 'join' operation (in SQL terms). JSONata supports this in a path expression. See https://docs.jsonata.org/path-operators#-context-variable-binding
So in your example, you could write:
key_one#$k1.key_two[node = $k1.id].{
"title": $k1.name
}
You can then add extra fields into the resulting object by referencing items from either of the original objects. E.g.:
key_one#$k1.key_two[node = $k1.id].{
"title": $k1.name,
"other_one": $k1.other_data,
"other_two": other_data
}
See https://try.jsonata.org/--2aRZvSL
I seem to have found a solution for this.
[key_two].$filter($$.key_one, function($v, $k){
$v.id = node
}).{"title": name ? name : id}
Gives:
[
{
"title": "value_one"
},
{
"title": "value_two"
},
{
"title": "value_three"
}
]
Leaving this here if someone have a similar issue in the future.

Ruby - Parse a file into hash

I've a file containing hundreds of object and value combination like below manner. I want to get input from user as object name & numeric value and return that associated value.
Object cefcFRUPowerOperStatus
Type PowerOperType
1:offEnvOther
2:on
3:offAdmin
4:offDenied
5:offEnvPower
6:offEnvTemp
Object cefcModuleOperStatus
Type ModuleOperType
1:unknown
2:ok
3:disabled
4:okButDiagFailed
5:boot
6:selfTest
E.g. - input -
objectName = 'cefcModuleOperStatus'
TypeNumber = '4'
Return - 'okButDiagFailed'
I am not aware of Ruby and get this done to help my peer. So please excuse if this is a novice question.
Note:- I've to create the file so with any file format it would be a great help.
If like you say you have control over creating the original data file, then creating it in json format would make accessing it trivial.
Here is a repl.it of complete working example. Just select the main.rb file and hit run!
For example if you create json file like:
data.json
{
"cefcFRUPowerOperStatus": {
"type": "PowerOperType",
"status": {
"1": "offEnvOther",
"2": "on",
"3": "offAdmin",
"4": "offDenied",
"5": "offEnvPower",
"6": "offEnvTemp"
}
},
"cefcModuleOperStatus": {
"type": "ModuleOperType",
"status": {
"1": "unknown",
"2": "ok",
"3": "disabled",
"4": "okButDiagFailed",
"5": "boot",
"6": "selfTest"
}
}
}
Then parsing it and accessing it in Ruby is as simple as :
require 'json'
file = File.read('data.json')
data = JSON.parse(file)
#accessing this data is simple now:
puts data["cefcModuleOperStatus"]["status"]["4"]
# > okButDiagFailed
Note: that this JSON format will work if your statuses are unique. If they are not, you can still use this way, but you will need to convert JSON to an array format. Let me know if this is the case and I can show you how to modify the json and ruby code for this.
Hope that helps, let me know if you have further questions about how this works.

Try to understand normalizr's schema.entity VS Array and Object

All:
I am trying to understand the relationship between Entity Array and Object:
Are they just different format to describe diff structure of data? Or Entity is quite diff from the rest two?
The normalized data result has a structure like {result:,entities:}, are the data structures only defined with schema.Entity put inside entities or so can schema.Array and Object? When I define a schema only use Object and Array, it seems nothing put in entities, I am not sure if it is my schema def fault or this is how normalizr work?
If only schema.Entity() defined data can put into entities, then how can I put an data array into it, something like {0:.., 1:..,2:,}?
For exmaple, I have data like:
var data = [
{
id:"0",
items:[
{
id: "0",
data: {name:"data-0-0"}
},
{
id: "1",
data: {name:"data-0-1"}
}
]
},
{
id:"1",
items:[
{
id: "0",
data: {name:"data-1-0"}
},
{
id: "1",
data: {name:"data-1-1"}
}
]
}
]
const normalizedData = normalize(data, [{items:[{data:{}}]}]);
And the normalized data is like:
{
"entities": {},
"result": {
"0": {
"id": "0",
"items": [
{
"id": "0",
"data": {
"name": "data-1-0"
}
}
]
}
}
}
Thanks
Question: Are they just different format to describe diff structure of data? Or Entity is quite diff from the rest two?
Answer: Yes. An Entity is a singular object that has a unique identifier associated with it. Array and Object are more generic structures that can't be uniquely identified. In your case, it looks like you only need to use Array and Entity for the data you're describing.
Question: Are the data structures only defined with schema? Entity put inside entities?
Answer: Yes.

Wrapping Data Structure in a data key API Blueprint / Apiary

So let's say I have a 200 response which body should be:
{
"data": [
{
"id": 1,
"title": "Activity 1"
},
{
"id": 1,
"title": "Activity 2"
}
]
}
I have managed to get this behavior of the response body by using this in API Blueprint.
+ Response 200 (application/json)
+ Attributes
+ data (array[Activity])
(Note that I can't add the data key to the data structure itself, because it's only present on the single response. If I need to nest an Activity inside another structure, it shouldn't have the data key.)
This doesn't seem right
The reason why I don't think it's the correct way of doing it, is beacuse of the JSON schema for this response which is:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"data": {
"type": "array"
}
}
}
Note how the actual activity is excluded.
How can I wrap my response in a data key properly, and have it reflected in both the body AND the schema?
You should use this line:
+ data(array[Activity], fixed-type)
The fixed-type keyword fixes the type of the items in the array.

Find matching array items in MongoDB document

I am developing a web app using Codeigniter and MongoDB.
In the database I got a document that look like this:
{
"_id": {
"$id": "4f609932615a935c18r000000"
},
"basic": {
"name": "The project"
},
"members": [
{
"user_name": "john",
"role": "user",
"created_at": {
"sec": 1331730738,
"usec": 810000
}
},
{
"user_name": "markus",
"role": "user",
"created_at": {
"sec": 1331730738,
"usec": 810000
}
}
]
}
I need to search this document using both user_name and role. Right now when I am using the below code I get both. I only want to get array items matching both user_name and role.
$where = array (
'_id' => new MongoId ($account_id),
'members.user_id' => new MongoId ($user_id),
'members.role' => $role
);
$this -> cimongo -> where ($where) -> count_all_results ('accounts');
This is an old question, but as of MongoDB 2.2 or so you can use the $ positional operator in a projection so that only the matched array element is included in the result.
So you can do something like this:
$this->cimongo->where($where)->select(array('members.$'))->get('accounts');
This is a repeat of this question:
Get particular element from mongoDB array
Also you might want to use $elemMatch
http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-ValueinanArray
Here is the rub -- you aren't going to be able to get the array items that match because mongo is going to return the entire document if those elements match. You will have to parse out the code client side. Mongo doesn't have a way to answer, "return only the array that matches."

Resources