How to add an array of objects in JSON - json

My question is entirely related to the structure of JSON. I've this:
{
"cars": {
"rows": [
{
"name": "Mercedes",
"color": "Black",
"make": "Mercedes"
},
{
"name": "BMW",
"color": "Black",
"make": "BMW Germany"
},
{
"name": "Innova",
"color": "Red",
"make": "Toyota"
}
]
}
}
Till now, row is an array of objects that contains information of different cars. I want two such row arrays. Only two are required. Like this:
{
"staticKpi": {
"rows": [
{
// 1st row 1st object
},
{
// 1st row 2nd object
},
{
// 1st row 3rd object
}
],
[
{
// 2nd row 1st object
},
{
// 2nd row 2nd object
},
{
// 2nd row 3rd object
}
]
}
}
You can see this JSON here.
But this is giving me JSON error. I just want to keep two lines of objects so there will be only two arrays in rows. hope I was able to explain the problem. Please correct my mistake.
PS: I've run forEach loop later on this JSON. So I've to take care of that too.

Try like this:
{
"staticKpi":{
"rows":[
[
{
"name":"Mercedes",
"color":"Black",
"make":"Mercedes"
},
{
"name":"BMW",
"color":"Black",
"make":"BMW Germany"
},
{
"name":"Innova",
"color":"Red",
"make":"Toyota"
}
],
[
{
"name":"Mercedes",
"color":"Black",
"make":"Mercedes"
},
{
"name":"BMW",
"color":"Black",
"make":"BMW Germany"
},
{
"name":"Innova",
"color":"Red",
"make":"Toyota"
}
]
]
}
}
rows needs to be one object/array, it can't be two. To have more than one element, you need to put those two elements in an array.
EDIT:
To loop through these using forEach in JavaScript, you could do this:
data = {"staticKpi":{"rows":[[{"name":"Mercedes","color":"Black","make":"Mercedes"},{"name":"BMW","color":"Black","make":"BMW Germany"},{"name":"Innova","color":"Red","make":"Toyota"}],[{"name":"Mercedes","color":"Black","make":"Mercedes"},{"name":"BMW","color":"Black","make":"BMW Germany"},{"name":"Innova","color":"Red","make":"Toyota"}]]}};
data.staticKpi.rows.forEach((row) => console.log(row));

Related

update value of a map of objects

With jq, how can I transform the following:
{
"root": {
"branch1": {
"leaf": 1
},
"branch2": {
"leaf": 2
},
"branch3": {
"leaf": 3
}
},
"another-root": {
"branch": 123
},
"foo": "bar"
}
to this:
{
"root": {
"branch1": {
"leaf": "updated"
},
"branch2": {
"leaf": "updated"
},
"branch3": {
"leaf": "updated"
}
},
"another-root": {
"branch": 123
},
"foo": "bar"
}
🤦 Apparently [] can be used on object too. I had though it was only for lists.
The following was all I needed.
.root[].leaf="updated"
First you need to parse the json and then modify the resulting object as required using for ... in statement (example below)
const flatJSON = '{"root":{"branch1":{"leaf":1},"branch2":{"leaf":2},"branch3":{"leaf":3}},"another-root":{"branch":123},"foo":"bar"}';
const parsedJSON = JSON.parse(flatJSON);
const root = parsedJSON.root;
for (let property in root) {
root[property].leaf = "updated"; (or root[property]["leaf"] = "updated";)
}
If you want to use jquery you have to replace for ... in statement with jQuery.each() method that iterates over both objects and arrays.
Don't forget to convert it back to json with JSON.stringify() method (if required).
Hope that this helps.
All the best.

jmespath :select json object element based on other (array) element in the object

I have this JSON
{
"srv_config": [{
"name": "db1",
"servers": ["srv1", "srv2"],
"prop": [{"source":"aa"},"destination":"bb"},{"source":"cc"},"destination":"cc"},]
}, {
"name": "db2",
"servers": ["srv2", "srv2"],
"prop": [{"source":"dd"},"destination":"dd"},{"source":"ee"},"destination":"ee"},]
}
]
}
I try to build a JMESPath expression to select the prop application in each object in the main array, but based on the existence of a string in the servers element.
To select all props, I can do:
*.props [*]
But how do I add condition that says "select only if srv1 is in servers list"?
You can use the contains function in order to filter based on a array containing something.
Given the query:
*[?contains(servers, `srv1`)].prop | [][]
This gives us:
[
{
"source": "aa",
"destination": "bb"
},
{
"source": "cc",
"destination": "cc"
}
]
Please mind that I am also using a bit of flattening here.
All this run towards a corrected version of you JSON:
{
"srv_config":[
{
"name":"db1",
"servers":[
"srv1",
"srv2"
],
"prop":[
{
"source":"aa",
"destination":"bb"
},
{
"source":"cc",
"destination":"cc"
}
]
},
{
"name":"db2",
"servers":[
"srv2",
"srv2"
],
"prop":[
{
"source":"dd",
"destination":"dd"
},
{
"source":"ee",
"destination":"ee"
}
]
}
]
}

Mongodb query on triple nested array of object

I'm having some problem to write a query to return a triple nested value from a document. The documents I'm using are structured like this
{
"areaname": "name1",
"places": [
{
"placename": "place1",
"objects": [
{
"objname": "obj1",
"tags": [
"tag1",
"tag2"
]
},
{
"objname": "obj2",
"tags": [
"tag6",
"tag7"
]
}
]
},
{
"placename": "place2",
"objects": [
{
"objname": "obj45",
"tags": [
"tag46",
"tag34"
]
},
{
"objname": "obj77",
"tags": [
"tag56",
"tag11"
]
}
]
}
]
}
It is quite simple actually but I can't find a solution to a simple query like:
"return the objname of the object that contains tag1 inside their tag"
So for the give document if I use "tag1" as a parameter it is expected for the query to return "obj1"
It should give me the same result if I use "tag2" as a parameter
Other example: using "tag56" it should return only "obj77"
Right now i have no problem returning the whole document using the dot-notation or top level field such as areaname or others
db.users.find( {"places.objects.tags":"tag1"}, { areaname: 1, _id:0 } )
Is this even possible?
Keeping it simple:
[
{
"$match" : {
"places.objects.tags" : "tag1"
}
},
{
"$unwind" : "$places"
},
{
"$unwind" : "$places.objects"
},
{
"$match" : {
"places.objects.tags" : "tag1"
}
},
{
"$group" : {
"_id" : "$_id",
"obj_names" : {
"$push" : "$places.objects.objname"
}
}
}
],
You should add any other fields you want to keep to the group stage,
this can also be done without the double $unwind stage but i choose this for read-ability.

Return selected JSON object from mongo find method

Here is the sample JSON
Sample JSON:
[
{
"_id": "123456789",
"YEAR": "2019",
"VERSION": "2019.Version",
"QUESTION_GROUPS": [
{
"QUESTIONS": [
{
"QUESTION_NAME": "STATE_CODE",
"QUESTION_VALUE": "MH"
},
{
"QUESTION_NAME": "COUNTY_NAME",
"QUESTION_VALUE": "IN"
}
]
},
{
"QUESTIONS": [
{
"QUESTION_NAME": "STATE_CODE",
"QUESTION_VALUE": "UP"
},
{
"QUESTION_NAME": "COUNTY_NAME",
"QUESTION_VALUE": "IN"
}
]
}
]
}
]
Query that am using :
db.collection.find({},
{
"QUESTION_GROUPS.QUESTIONS.QUESTION_NAME": "STATE_CODE"
})
My requirement is retrive all QUESTION_VALUE whose QUESTION_NAME is equals to STATE_CODE.
Thanks in Advance.
If I get you well, What you are trying to do is something like:
db.collection.find(
{
"QUESTION_GROUPS.QUESTIONS.QUESTION_NAME": "STATE_CODE"
},
{
"QUESTION_GROUPS.QUESTIONS.QUESTION_VALUE": 1
})
Attention: you will get ALL the "QUESTION_VALUE" for ANY document which has a QUESTION_GROUPS.QUESTIONS.QUESTION_NAME with that value.
Attention 2: You will get also the _Id. It is by default.
In case you would like to skip those issues, you may need to use Aggregations, and unwind the "QUESTION_GROUPS"-> "QUESTIONS". This way you can skip both the irrelevant results, and the _id field.
It sounds like you want to unwind the arrays and grab only the question values back
Try this
db.collection.aggregate([
{
$unwind: "$QUESTION_GROUPS"
},
{
$unwind: "$QUESTION_GROUPS.QUESTIONS"
},
{
$match: {
"QUESTION_GROUPS.QUESTIONS.QUESTION_NAME": "STATE_CODE"
}
},
{
$project: {
"QUESTION_GROUPS.QUESTIONS.QUESTION_VALUE": 1
}
}
])

Loading TreeStore with JSON that has different children fields

I am having a JSON data like below.
{
"divisions": [{
"name": "division1",
"id": "div1",
"subdivisions": [{
"name": "Sub1Div1",
"id": "div1sub1",
"schemes": [{
"name": "Scheme1",
"id": "scheme1"
}, {
"name": "Scheme2",
"id": "scheme2"
}]
}, {
"name": "Sub2Div1",
"id": "div1sub2",
"schemes": [{
"name": "Scheme3",
"id": "scheme3"
}]
}
]
}]
}
I want to read this into a TreeStore, but cannot change the subfields ( divisions, subdivisions, schemes ) to be the same (eg, children).
How can achieve I this?
When nested JSON is loaded into a TreeStore, essentially the children nodes are loaded through a recursive calls between TreeStore.fillNode() method and NodeInterface.appendChild().
The actual retrieval of each node's children field is done within TreeStore.onNodeAdded() on this line:
dataRoot = reader.getRoot(data);
The getRoot() of the reader is dynamically created in the reader's buildExtractors() method, which is what you'll need to override in order to deal with varying children fields within nested JSON. Here is how it's done:
Ext.define('MyVariJsonReader', {
extend: 'Ext.data.reader.Json',
alias : 'reader.varijson',
buildExtractors : function()
{
var me = this;
me.callParent(arguments);
me.getRoot = function ( aObj ) {
// Special cases
switch( aObj.name )
{
case 'Bill': return aObj[ 'children' ];
case 'Norman': return aObj[ 'sons' ];
}
// Default root is `people`
return aObj[ 'people' ];
};
}
});
This will be able to interpret such JSON:
{
"people":[
{
"name":"Bill",
"expanded":true,
"children":[
{
"name":"Kate",
"leaf":true
},
{
"name":"John",
"leaf":true
}
]
},
{
"name":"Norman",
"expanded":true,
"sons":[
{
"name":"Mike",
"leaf":true
},
{
"name":"Harry",
"leaf":true
}
]
}
]
}
See this JsFiddle for fully working code.