NiFi EvaluateJSONPath loop through array to get correct value - json

here is an example of some JSON that I need to deal with:
{
"name": "John Smith",
"active": "yes",
"cpair": [
{
"title": "ADDRESS",
"charVal": "1234 Fulcrum lane"
},
{
"title": "phone",
"charVal": "555-7600"
}
]
}
So I'm using the evaluateJsonPath processor to add these values as attributes in my flowfile. thats easy for some. I can just set name equal to $.name and active to $.active. But lets say I need to give the attribute 'address' the value of "1234 Fulcrum lane". How do I assign that attribute the proper charVal value that matches up with the correct title?

according to Jayway JsonPath documentation
this should work:
$.cpair[?(#.title == 'ADDRESS')].charVal

Related

JSONSchema - Element can appear alone or within a group

I have a JSON that looks like this:
{
"name": "Jane",
"company_name": "BrandNewStartup",
"designation": "DesignLead"
}
The name element can appear alone in the JSON as well, so the following JSON is valid too.
{
"name": "Jane"
}
But company_name and designation cannot appear if name is missing. So the following JSON should be invalid:
{
"company_name": "BrandNewStartup",
"designation": "DesignLead"
}
I have tried the following rule:
"oneOf": [
{
"required": [
"name",
"company_name",
"designation"
]
},
{
"required": [
"name"
]
}
]
However this does not seem to work (e.g this validation library raises error that the JSON should be valid to only one schema but it is valid against all).
If I change this to anyOf, the first JSON with all the 3 fields works, but when name appears alone, an error is raised that the company_name designation fields are missing.
How do I define this rule?
JSON Schema is a constraints based language. Anything you don't specify is allowed.
The required keyword means a key is required in an object, but doesn't inherintly prevent any other keys from being included.
Breaking down the schema in your question, when you have all three keys in your object, as in your first example instance, then both subschemas in oneOf would be valid.
In order to restrict the allowed properties, you need to use the additionalProperties keyword, which in your case also means you need to use the properties keyword. required has no effect on additionalProperties.
The second subschema needs to only be valid when the instance has ONLY name and no other keys. Here's a live demo using the below modified JSON Schema: https://jsonschema.dev/s/7JcUa
{
"$schema": "http://json-schema.org/draft-07/schema",
"oneOf": [
{
"required": [
"name",
"company_name",
"designation"
]
},
{
"required": [
"name"
],
"properties": {
"name": true
},
"additionalProperties": false
}
]
}

Get value from exact JSONpath level

I want to extract values from an JSON document with using the path operators.
For example I get all the product IDs included in the file via $..product_id.
But for getting the "id" when I use $..id I get an output for each id element, no matter on which level of the JSON the variable is.
For example in my output I get an row for the id "12345678" as well as for "11223344" which should not be because it is a subset of the first ID.
{
"next_offset": 20,
"records": [
{
"id": "12345678",
"date": "2020-02-14",
"product_id": "asdf1234",
"product_name": "Product_test^_1",
"template_link": {
"name": "aassddff",
"id": "11223344",
"_acl": {
"fields": [],
"_hash": "345thvz356b56v456b"
}
},
....
}
]
}
How can I set the path operator to only access the "id" fields of one specific level?
For the JSON shown in your question, use $.records.*.id.

N1QL - query multilevel nested JSON data in CouchBase

How do I select the whole JSON document by querying for multi level nested values? Here is example of my JSON:
{
"id": "6316194187233559482",
"type": "Hotel",
"attributes": [
{
"country": "Germany",
"officialNames": [
{
"name": "The Ritz-Carlton, Berlin",
"language": "GER"
}
],
"streetsAndCities": [
{
"city": "Berlin",
"cityLanguage": "GER",
"street": "Potsdamer Platz ",
"streetLanguage": "GER"
}
]
}
]
}
And I want to query it for "name" attribute. I have experimented with UNNEST function and I have no problem to acces first level of nested data i.e. "officialNames". But I don't know how to access "name" attribute. Referencing it by position e.g.:
SELECT * FROM document
UNNEST attributes as attributes
WHERE attributes[0].officialNames[0].name = "The Ritz-Carlton, Berlin"
Is not going to work as position of each attribute in JSON can change.
What do you mean by "position of each attribute in JSON can change"? Do you mean that the "attributes" and "officialNames" and "streetsAndCities" arrays can have additional entries and you want to search through all the entries?
If yes, then have a look at the ANY operator here:
https://docs.couchbase.com/server/6.0/n1ql/n1ql-language-reference/collectionops.html

Binding embedded Json in ember

How does bind values of embedded JSON data to input elements in EmberJS as I cannot seem to find a straight forward way to get that done.
update
It doesn't seem to work for a JSON object with this structure
{
"users": [
{
"_id": "534550428047526419000002",
"Name": "admin",
"Code": "admin",
"Age": 12,
"Sex": "Male",
"Ethnicity": "admin",
"EventTime": "",
"Accident": [
{
"value": true,
"risk": "Medium"
}
]
}
]
}
In the template you use the property name
{{foo}}
{{input value=foo}}
Example
http://emberjs.jsbin.com/wufegaca/1/edit
nested properties are handled the same way they are in most languages with the dot operator
{{foo.bar}}
{{input value=foo.bar}}
Example
http://emberjs.jsbin.com/wufegaca/2/edit
Using an array you need to iterate over the array. If you didn't how would Ember know which item you were referring to? Additionally upper case property names are problematic in handlebars, since it usually denotes a global namespace, so be wary if things don't appear to be working.
Example
http://emberjs.jsbin.com/wufegaca/3/edit

jqGrid JSON notation on objects

there!
I´ve one column in my jqGrid that is empty.
But i checked the object on chrome console and thats fine.
colModel definition
colModel:[
{name:'id',index:'id', width:55,editable:false,editoptions:{readonly:true,size:10},hidden:true},
{name:'firstName',index:'firstName', width:100,searchoptions: { sopt: ['eq', 'ne', 'cn']}},
{name:'lastName',index:'lastName', width:100,editable:true, editrules:{required:true}, editoptions:{size:10}},
{name:'books[0].nome',index:'books[0].nome', width:100,editable:true, editrules:{required:true}, editoptions:{size:10}},
{"formatter":"myfunction", formatoptions:{baseLinkUrl:'/demo/{firstName}|view-icon'}}
]
JSON response
{
"total": "10",
"page": "1",
"records": "3",
"rows": [
{
"id": 1,
"firstName": "John",
"lastName": "Smith",
"books": [{"nome": "HeadFirst"}]
},
{
"id": 2,
"firstName": "Jane",
"lastName": "Adams",
"books": [{"nome": "DalaiLama"}]
},
{
"id": 35,
"firstName": "Jeff",
"lastName": "Mayer",
"books": [{"nome": "Bobymarley"}]
}
]
}
chrome console inspect object
rowdata.books[0].nome
"HeadFirst"
Any one know where theres are possibles trick?
Tks!
You should use as the value of name property of colModel only the names which can be used as property name in JavaScript and as CSS id names. So the usage of name:'books[0].nome' is not good idea.
To solve your problem you can use jsonmap. For example you can use dotted name conversion:
{name: 'nome', jsonmap: 'books.0.nome', ...
In more complex cases you can use functions as the value of jsonmap. For example
{name: 'nome', jsonmap: function (item) {
return item.books[0].nome;
}, ...
You can find some more code examples about the usage of jsonmap in other old answers: here, here, here, here, here.
name is intended to be a unique name for the row, not a reference to a JSON object. From the jqGrid colModel options documentation:
Set the unique name in the grid for the column. This property is required. As well as other words used as property/event names, the reserved words (which cannot be used for names) include subgrid, cb and rn.
You can also observe how .name is used within grid.base.js - for example:
var nm = {},
...
nm = $t.p.colModel[i].name;
...
res[nm] = $.unformat.call($t,this,{rowId:ind.id, colModel:$t.p.colModel[i]},i);
Anyway, to get back to your question I think you will have better luck by passing down the book name directly - as strings and not objects - and referencing it by name as something like bookName.