Solving this simple(?) JSONPath - json

I am new to this topic, but I hope you can help me. I can't figure out a correct JSON expression for solving my problem.
Given JSON structure (coming from zigbee2mqtt):
{
"message" : "announce",
"meta" : {
"friendly_name" : "Lamp1"
},
"type" : "device_announced"
}
What I am trying:
if $.type == 'device_announced' then return the friendly_name
which in this case is
Lamp1

If I understand correctly, you are looking for an expression like this:
$[?(#.type=='device_announced')].meta.friendly_name
So, we are filtering the root collection on types equal to the search string, and then drill down to the friendly_name. You can test this online here.
Note: Some implementations require you to wrap your JSON in an array [ ] to allow this kind of filtering.

Related

Return nested JSON in AWS AppSync query

I'm quite new to AppSync (and GraphQL), in general, but I'm running into a strange issue when hooking up resolvers to our DynamoDB tables. Specifically, we have a nested Map structure for one of our item's attributes that is arbitrarily constructed (its complexity and form depends on the type of parent item) — a little something like this:
"item" : {
"name": "something",
"country": "somewhere",
"data" : {
"nest-level-1a": {
"attr1a" : "foo",
"attr1b" : "bar",
"nest-level-2" : {
"attr2a": "something else",
"attr2b": [
"some list element",
"and another, for good measure"
]
}
}
},
"cardType": "someType"
}
Our accompanying GraphQL type is the following:
type Item {
name: String!
country: String!
cardType: String!
data: AWSJSON! ## note: it was originally String!
}
When we query the item we get the following response:
{
"data": {
"genericItemQuery": {
"name": "info/en/usa/bra/visa",
"country": "USA:BRA",
"cardType": "visa",
"data": "{\"tourist\":{\"reqs\":{\"sourceURL\":\"https://travel.state.gov/content/passports/en/country/brazil.html\",\"visaFree\":false,\"type\":\"eVisa required\",\"stayLimit\":\"30 days from date of entry\"},\"pages\":\"One page per stamp required\"}}"
}}}
The problem is we can't seem to get the Item.data field resolver to return a JSON object (even when we attach a separate field-level resolver to it on top of the general Query resolver). It always returns a String and, weirdly, if we change the expected field type to String!, the response will replace all : in data with =. We've tried everything with our response resolvers, including suggestions like How return JSON object from DynamoDB with appsync?, but we're completely stuck at this point.
Our current response resolver for our query has been reverted back to the standard response after none of the suggestions in the aforementioned post worked:
## 'Before' response mapping template on genericItemQuery query; same result as the 'After' listed below **
#set($result = $ctx.result)
#set($result.data = $util.parseJson($ctx.result.data))
$util.toJson($result)
## 'After' response mapping template **
$util.toJson($ctx.result)
We're trying to avoid a situation where we need to include supporting types for each nest level in data (since it changes based on parent Item type and in cases like the example I gave it can have three or four tiers), and we thought changing the schema type to AWSJSON! would do the trick. I'm beginning to worry there's no way to get around rebuilding our base schema, though. Any suggestions to the contrary would be helpful!
P.S. I've noticed in the CloudWatch logs that the appropriate JSON response exists under the context.result.data response field, but somehow there's the following transformedTemplate (which, again, I find very unusual considering we're not applying any mapping template except to transform the result into valid JSON):
"arn": ...
"transformedTemplate": "{data={tourist={reqs={sourceURL=https://travel.state.gov/content/passports/en/country/brazil.html, visaFree=false, type=eVisa required, stayLimit=30 days from date of entry}, pages=One page per stamp required}}, resIds=USA:BRA, cardType=visa, id=info/en/usa/bra/visa}",
"context": ...
Apologies for the lengthy question, but I'm stumped.
AWSJSON is a JSON string type so you will always get back a string value (this is what your type definition must adhere to).
You could try to make a type for data field which contains all possible fields and then resolve fields to a corresponding to a parent type or alternatively you could try to implement graphQL interfaces

Is this valid JSON for parsing?

I've got a task to write a JSON parser in java with a little help.
I'm already able to parse this:
{
"ArrayWithOneString" : [ "ArrayContent" ],
"Array" : [
{
"ArrayinArray" : [
{
"NumberInArray" : 1337,
"StringInArray" : "String"
}
]
}
]
}
I've got only one last problem:
"string" : { // The bracket
"string" : "valueString"
},
My problem is that I expect a value and not another object for this opening bracket ({).
I wanted to ask if this is valid json before trying to parse it.
Yes it is valid. Well without your highlighting attempts, and assuming it is part of a parent object.
Just because you have a property called "string" doesn't mean it has to be a string value. I suggest perhaps whoever made it just isn't being very consistent, but it is still valid.
The question is, why are you expecting a value? Either the person who constructed the JSON has not done it to specification, or it is you that is not understanding the specification.
Also, you can easily validate JSON here.
Look here for specifications. Your example is valid according to this.
Yes it is valid JSON. You can now parse in your code.
You can check Valid JSON
See below screenshot.

Flat csv data to Json

I am trying to process a Json data in Java. I have the data in below format (it is nested data structure with arrays etc.)
person.name,person.friend[0],person.friend[1],person.address.city,person.address.country
1,x,y,kolkata,india
2,a,b,london,uk
The first line is header denoting the nested object hierarchy. I want a json in below format,
{
"data" : [
{
"name" : "1",
"friend" : ["x","y"],
"address" : { "city" : "kolkata", "country" : "india" }
},
{
"name" : "2",
"friend" : ["a","b"],
"address" : { "city" : "london", "country" : "uk" }
} ]
}
The object structure is dynamic and I dont know the columns or header in advance, i.e. I can not use any predefined POJO to get populated with the data. In this example, it "Person" object but it may be any object structure.
I have gone through Jackson or Gson API, but none seems to fulfill this requirement. Is there any API that can help? or any other wayout?
Thanks
You need to do it in 2 steps.
First, you have to parse your CSV. I recommend superCSV. Parsing CSV may be fancy sometimes, so I really recommend you to use a library for that.
Second, you can serialize into JSON. Then you can use GSON, jackson, flexjson, whatever.
After a long Google...I found that the only option is to represent a collection based object structure in flat file is repeated rows,
person.name,person.friends,person.address.city,person.address.country
1,x,kolkata,india
1,y,kolkata,india
2,a,london,uk
2,b,london,uk
where the non-array elements repeats. We need to form a json from this, then need to filter or club the same object by its ID (here person.name)

Extract array to JSON

I have a query that extracts a document with a username and password as a filter. My return value is an array (It will return the elements in phoneBook). How do I turn this into a JSON object? Just returning a JSON from a query would be ideal.
db.users.find({userName:"mark", passWord:"test1234"}, {phoneBook:1,_id:0})
{ "phoneBook" : [ { "firstName" : "Rupert", "lastName" : "Styx", "phoneNumber" : "9147388152", "email" : "ruperstyx#gmail.com" } ] }
I'm still playing around with this string. I can't extract the attributes inside of phoneBook and turn it into a JSON
If you use php then you can use jsonencode($your_array) function for converting an array into json object and if you working on other language then just search function for converting an array into json.
This is snipt from my code (my app in Node.js)
collection.find({
"word": req.query.word
}).toArray(function(err, results) {
var res = JSON.stringify(results);
});
Simply use JSON.stringify(results)
I hope it works for you
By using Robomongo tool you will be able to see query results in list, table and json view!
Using robomongo:
db.getCollection('ModelName')
.find({})
.limit(20)
.map(function(model){
return model.toSource()
})

Parsing JSON in Erlang

I have a piece of JSON string, which I want to parse in Erlang. It looks like:
({ id1 : ["str1", "str2", "str3"], id2 : ["str4", "str5"]})
I looked at mochijson2, and a couple of other JSON parsers, but I really could not figure out how to do it. Any help greatly appreciated!
I once used the erlang-json-eep-parser, and tried it on your data.
7> json_eep:json_to_term("({ id1 : [\"str1\", \"str2\", \"str3\"], id2 : [\"str4\", \"str5\"]})").
** exception error: no match of right hand side value
{error,{1,json_lex2,{illegal,"("}},1}
in function json_eep:json_to_term/1
Right, it doesn't like the parentheses.
8> json_eep:json_to_term("{ id1 : [\"str1\", \"str2\", \"str3\"], id2 : [\"str4\", \"str5\"]}").
** exception error: no match of right hand side value
{error,{1,json_lex2,{illegal,"i"}},1}
in function json_eep:json_to_term/1
And it doesn't like the unquoted keys:
18> json_eep:json_to_term("{ \"id1\" : [\"str1\", \"str2\", \"str3\"], \"id2\" : [\"str4\", \"str5\"]}").
{[{<<"id1">>,[<<"str1">>,<<"str2">>,<<"str3">>]},
{<<"id2">>,[<<"str4">>,<<"str5">>]}]}
That looks better.
So it seems that your data is almost JSON, at least as far as this parser is concerned.
you can work on your JSON at the JSONLint validator: http://www.jsonlint.com/
Your input is not quite JSON -- the keys need to be quoted, like this:
{ "id1" : ["str1", "str2", "str3"], "id2" : ["str4", "str5"]}
A good Erlang library for manipulating JSON is jsx
Have you looked at http://www.json.org/ ?
or download "json4erlang" from here: json-and-json-rpc-for-erlang
Your JSON keys are not valid according to https://www.ietf.org/rfc/rfc4627.txt. Once you correct it, there are plenty of JSON libraries for Erlang, my favorite is JSX(https://github.com/talentdeficit/jsx/):
MyJSON = { "id1" : ["str1", "str2", "str3"], "id2" : ["str4", "str5"]},
jsx:decode(MyJSON, [return_maps]).
And it will return an Erlang map data structure that can be manipulated to your needs http://learnyousomeerlang.com/maps