Read data from arrays in javascript - javascript

I'm trying to read data from an array in JSON with javascript but I can't get it working. This is the segment of the JSON file from wich I want to read the data, I want to read the age variable from different arrays:
{
"failCount" : 1,
"skipCount" : 15,
"totalCount" : 156,
"childReports" :
[
{
"result" :
{
duration : 0.97834,
empty : false,
suites :
[
cases :
[
{
"age" : 0,
"status" : Passed
}
{
"age" : 15,
"status" : Passed
}
{
"age" : 3,
"status" : failed
}
]
]
}
}
]
}
I've tried this:
for (var i = 0; i < jsonData.childReports.suites.cases.length; i++)
{
var age = jsonData.childReports.suites.cases[i];
}
But it doesn't work. What would be the best way to do this?
Thanks in advance,
Matthijs.

Try the following code:
for (var i = 0; i < jsonData.childReports[0].result.suites[0].cases.length; i++) {
var age = jsonData.childReports[0].result.suites[0].cases[i].age;
}

Correct Json:
{
"failCount" : 1,
"skipCount" : 15,
"totalCount" : 156,
"childReports" : [
{
"result" : {
duration : 0.97834,
empty : false,
suites : [{
cases : [
{
"age" : 0,
"status" : "Passed"
},
{
"age" : 15,
"status" : "Passed"
},
{
"age" : 3,
"status" : "failed"
}
]}
]
}
}]
}

This way you can achieve that :
var data = {
"failCount" : 1,
"skipCount" : 15,
"totalCount" : 156,
"childReports" : [
{
"result" : {
duration : 0.97834,
empty : false,
suites : [{
cases : [
{
"age" : 0,
"status" : "Passed"
},
{
"age" : 15,
"status" : "Passed"
},
{
"age" : 3,
"status" : "failed"
}
]}
]
}
}]
};
for (var i = 0; i < data.childReports[0].result.suites[0].cases.length; i++) {
console.log(data.childReports[0].result.suites[0].cases[i].age);
}
DEMO

Related

How can I access(and convert) 'date' to Javascript?

Here is MongoDB scheme.
{
"_id" : ObjectId("222222"),
"active" : false,
"amount" : "15%",
"description" : "15% discount",
"name" : "20200628-test",
"policies" : {
"apply" : [
{
"name" : "expiryDate",
"params" : {
"date" : ISODate("2020-07-06T14:59:59.999Z")
}
},
{
"name" : "isApplyCategoryExist"
}
],
"discount" : [],
"conflict" : [
{
"name" : "exclusive"
}
],
"grant" : []
},
"target" : {
"sku" : "",
"products_ids" : [],
"category_ids" : [
ObjectId("11111111")
]
},
"title" : "15% coupon"
}
I want to access date.
For example, "policies.apply.params.date"...
I don't know how to access 'date' to Javascript.
Please let me know...
apply is an array, so you have to give it index which you want to get.
var num = 0; // pick up an array number you want
var date = policies.apply[num].params.date;
Your policies.apply is an array so if you want to access "2020-07-06T14:59:59.999Z", you should do this:
policies.apply[0].params.date
But the "policies.apply[1]" doesn't have params (params.date also) so you can write a function to get date like this:
function get_apply_date(index) {
if(policies.apply[index].params && policies.apply[index].params.date)
return policies.apply[index].params.date;
return undefined; // or null
}

javascript update mongodb documents multiple fields by looking up from another collection

I have several hundred thousands of documents in mongoDB to update.
here is an example of existing documents from collection Users:
{
"_id" : "549120bcf5115900124fb6e1",
"user" : "Tom",
"country" : "United Kingdom",
"province" : "North Yorkshire",
"city" : "York",
"organization" : ""
},
{
"_id" : "143184fbf5482260184ac6e2",
"user" : "Jack",
"country" : "Not Listed",
"province" : "",
"city" : "",
"organization" : "United Nations"
},
{
"_id" : "1234567890123456748979",
"user" : "Sarah",
"country" : "Not Listed",
"province" : "",
"city" : "",
"organization" : ""
},
{
"_id" : "98765432411654987654",
"user" : "Mat"
}
Each document has the possibility to have values in these fields :
a country, a province, and a city
or a country and a state
and here is the sample from another collection Countries:
{
"_id" : "123456789",
"key" : "Not Listed",
"uuid" : "ca55b53a-ef5b-43ed-90ed-b857f45ddb6d",
"organization" : [
{
"key" : "United Nations",
"uuid" : "1c4ae4c6-00c5-405d-98fa-ca7cc9edc72a"
},
{
"key" : "FIFA",
"uuid" : "11cfe606-821f-40fb-b1d0-bb7f9abb21dc"
}
],
"province" : [],
},
{
"_id" : "1123465498742",
"key" : "United Kingdom",
"uuid" : "d756e167-25ec-4aa9-b231-4dbf6d4bfce4",
"organization" : [],
"province" : [
{
"key" : "North Yorkshire",
"uuid" : "73d07c77-eba4-4dfa-9ada-e0ba8d8a2d55",
"city" : [
{
"key" : "York",
"uuid" : "80fd18a6-c4eb-4fb9-b591-6cca62319ba7"
},
{
"key" : "Middlesbrough",
"uuid" : "26a277c4-8640-4959-a64a-00f3727975f4"
}
],
},
{
"key" : "Oxfordshire",
"uuid" : "f7b5a570-df42-4520-ba3a-8bdcdd00e7d4",
"city" : [
{
"key" : "Oxford",
"uuid" : "b931865c-a363-4958-b7e7-5503fe674eb0"
},
{
"key" : "Banbury",
"uuid" : "b8d4c63a-75a9-4c3c-a4cd-d315f06a92e0"
}
],
}
]
}
The idea is to look up the country/organization/province/city field value from documents in Users collection and update them based on the uuid value of the Countries collection.
So the result will look like something like this:
{
"_id" : "549120bcf5115900124fb6e1",
"user" : "Tom",
"country" : "d756e167-25ec-4aa9-b231-4dbf6d4bfce4", // uuid of United Kingdom
"province" : "73d07c77-eba4-4dfa-9ada-e0ba8d8a2d55", // uuid of North Yorkshire
"city" : "80fd18a6-c4eb-4fb9-b591-6cca62319ba7", // uuid of York
"state" : ""
},
{
"_id" : "143184fbf5482260184ac6e2",
"user" : "Jack",
"country" : "ca55b53a-ef5b-43ed-90ed-b857f45ddb6d", // uuid of Not Listed
"province" : "",
"city" : "",
"state" : "1c4ae4c6-00c5-405d-98fa-ca7cc9edc72a" // uuid of United Nations
},
{
"_id" : "1234567890123456748979",
"user" : "Sarah",
"country" : "ca55b53a-ef5b-43ed-90ed-b857f45ddb6d", // uuid of Not Listed
"province" : "",
"city" : "",
"state" : ""
},
{
"_id" : "98765432411654987654",
"user" : "Mat"
}
The dependency of the fields are the following:
Country > Province > City
Or:
Country > Organization
It is possible that a parent field exists, but its child field doesn't exist or is empty.
How can I update these multidimensional arrays using mongo script rules?
Here is my attempt, but this is a lot of for loops, and not sure how to do the mongodb find/update/save part.. could somebody help to achieve it?
var usrCountry, uuidcountry, usrProvince, uuidprovince, usrOrg, uuidorg, usrCity, uuidcity;
for (var i = 0; i < users.length; i++) {
usrCountry = users[i].country;
usrProvince = users[i].province;
usrOrg = users[i].organization;
usrCity = users[i].city;
for (var j = 0; j < countries.length; j++) {
if (countries[j].key === usrCountry) {
uuidcountry = countries[j].uuid;
console.log('uuidcountry: ', uuidcountry)
if (countries[j].province.length){
for (var k = 0; k < countries[j].province.length; k++) {
if (countries[j].province[k].key === usrProvince){
uuidprovince = countries[j].province[k].uuid;
console.log('uuidprovince', uuidprovince)
for (var l = 0; l < countries[j].province[k].city.length; l++) {
if (countries[j].province[k].city[l].key === usrCity){
uuidcity = countries[j].province[k].city[l].uuid
console.log('uuidcity: ', uuidcity)
}
}
}
}
}
}
}
}
You can try do this with aggregation pipeline, and use that info to update
db.u.aggregate(
[
{
$lookup: {
from : "c",
localField : "country",
foreignField : "key",
as : "countryInfo"
}
},
{
$project: {
"_id" : 1,
"user" : 1,
"province" : 1,
"country" : 1,
"city" : 1,
"organization" : 1,
"country_uuid" : {$arrayElemAt : ["$countryInfo.uuid",0]},
"province_uuid" : { $arrayElemAt : [{ $map : { input : { $filter : { input : {$arrayElemAt : ["$countryInfo.province" ,0 ]} , as : "pro", cond : { $eq : [ "$$pro.key", "$province" ] } } } , as : "pr", in : "$$pr.uuid" } }, 0 ] },
"city_uuid" : {$arrayElemAt : [{$map : { input : { $arrayElemAt : [ {$filter : { input : { $map : { input : { $arrayElemAt : ["$countryInfo.province.city" ,0 ] }, as : "ct", in : { $filter : { input : "$$ct" , as : "ctyy", cond : { $eq : ["$$ctyy.key", "$city"] } } } } }, as : "o", cond : {$ne : [ {$size : "$$o"} , 0 ] } } } , 0]}, as : "o", in :"$$o.uuid"}}, 0]}
}
}
]
)
result
> db.u.aggregate( [ { $lookup: { from : "c", localField : "country", foreignField : "key", as : "countryInfo" } }, { $project: { "_id" : 1, "user" : 1, "province" : 1, "country" : 1, "city" : 1, "organization" : 1, "country_uuid" : {$arrayElemAt : ["$countryInfo.uuid",0]}, "province_uuid" : { $arrayElemAt : [{ $map : { input : { $filter : { input : {$arrayElemAt : ["$countryInfo.province" ,0 ]} , as : "pro", cond : { $eq : [ "$$pro.key", "$province" ] } } } , as : "pr", in : "$$pr.uuid" } }, 0 ] }, "city_uuid" : {$arrayElemAt : [{$map : { input : { $arrayElemAt : [ {$filter : { input : { $map : { input : { $arrayElemAt : ["$countryInfo.province.city" ,0 ] }, as : "ct", in : { $filter : { input : "$$ct" , as : "ctyy", cond : { $eq : ["$$ctyy.key", "$city"] } } } } }, as : "o", cond : {$ne : [ {$size : "$$o"} , 0 ] } } } , 0]}, as : "o", in :"$$o.uuid"}}, 0]} } } ] ).pretty()
{
"_id" : "549120bcf5115900124fb6e1",
"user" : "Tom",
"country" : "United Kingdom",
"province" : "North Yorkshire",
"city" : "York",
"organization" : "",
"country_uuid" : "d756e167-25ec-4aa9-b231-4dbf6d4bfce4",
"province_uuid" : "73d07c77-eba4-4dfa-9ada-e0ba8d8a2d55",
"city_uuid" : "80fd18a6-c4eb-4fb9-b591-6cca62319ba7"
}

Compare,add,update,delete elements on array of mongodb

Need help on operation like update,delete,add,upsert,delete on below document of MongoDB.
Below is MongoDB document that exists in temp collection.
{
"local_id" : "1841",
"name_first" : "tiger",
"name_last" : "lion",
"address" : [
{
"id" : 1,
"address_type" : "Home",
"city" : "Delhi",
"country" : "",
"po_box" : ""
},
{
"id" : 2,
"address_type" : "Work",
"city" : "",
"country" : "",
"po_box" : ""
}
],
"email" : [
{
"email_id" : "blah#gmail.com",
"id" : 1,
"type" : "Home"
},
{
"email_id" : "Pearl1#gmail.com",
"id" : 2,
"type" : "Work"
}
],
"phone_number" : [
{
"id" : 1,
"no" : "+911234567890",
"type" : "Mobile"
},
{
"id" : 2,
"no" : "+917894561230",
"type" : "work"
}
]
}`
Now I have some document like below, i want query that will compare,add,update,delete on my above document.
`
{
"local_id" : "1730",
"name_first" : "lion",
"name_last" : "king",
"address" : [
{
"id" : 1,
"address_type" : "Home",
"city" : "Delhi",
"country" : "India",
"po_box" : "110041"
},
{
"id" : 2,
"address_type" : "Work",
"city" : "Delhi-NCR",
"country" : "India",
"po_box" : "110048"
},
{
"id" : 3,
"address_type" : "Work",
"city" : "Delhi-NCR",
"country" : "Indai",
"po_box" : "110048"
}
],
"email" : [
{
"email_id" : "updatethis#gmail.com",
"id" : 1,
"type" : "Home"
},
{
"email_id" : "Pearl1#gmail.com",
"id" : 2,
"type" : "Work"
},
{
"email_id" : "addthisarray#gmail.com",
"id" : 3,
"type" : "personal"
}
],
"phone_number" : [
{
"id" : 1,
"no" : "+911234567890",
"type" : "Mobile"
}
/*second array not here so remove that array from that document*/
]
}`
You can save function on server as you can call that function to get the differences, as below.
db.system.js.save({
_id: "getupdatedArray",
value: function(obj1, obj2) {
var VALUE_CREATED = 'created';
var VALUE_UPDATED = 'updated';
var VALUE_DELETED = 'deleted';
var VALUE_UNCHANGED = 'unchanged';
function map(obj1, obj2) {
if (isValue(obj1) || isValue(obj2)) {
return {
type: compareValues(obj1, obj2),
old: obj1,
new: obj2
};
}
var diff = {};
for (var key in obj1) {
if (isFunction(obj1[key])) {
continue;
}
var value2 = undefined;
if ('undefined' != typeof(obj2[key])) {
value2 = obj2[key];
}
diff[key] = map(obj1[key], value2);
}
for (var key in obj2) {
if (isFunction(obj2[key]) || ('undefined' != typeof(diff[key]))) {
continue;
}
diff[key] = map(undefined, obj2[key]);
}
return diff;
}
function compareValues(value1, value2) {
if (value1 === value2) {
return VALUE_UNCHANGED;
}
if ('undefined' == typeof(value1)) {
return VALUE_CREATED;
}
if ('undefined' == typeof(value2)) {
return VALUE_DELETED;
}
return VALUE_UPDATED;
}
function isFunction(obj) {
return {}.toString.apply(obj) === '[object Function]';
}
function isArray(obj) {
return {}.toString.apply(obj) === '[object Array]';
}
function isObject(obj) {
return {}.toString.apply(obj) === '[object Object]';
}
function isValue(obj) {
return !isObject(obj) && !isArray(obj);
}
return map(obj1, obj2);
}
})
Then you can call function as below..
db.loadServerScripts();
getupdatedArray({"a": "abc"}, {"a": "a111", "b": "bbb"});
This will give you result as below:
{
"a" : {
"type" : "updated",
"old" : "abc",
"new" : "a111"
},
"b" : {
"type" : "created",
"old" : undefined,
"new" : "bbb"
}
}
Thanks
Satish Lakhani

Sorting a JSON objects' child-keys by their child-keys' values

I am looking for a way to sort my three main JSON keys (neutral, positive, negative) using their children y-keys' values.
This is how the JSON object is set up:
{
"chartSeries" : {
"negative" : [ {
"y" : 1505,
"url" : "http://www.test.com/1"
}, {
"y" : 425,
"url" : "http://www.test.com/2"
}, {
"y" : 1046,
"url" : "http://www.test.com/3"
} ],
"neutral" : [ {
"y" : 10,
"url" : "http://www.test.com/4"
}, {
"y" : 1,
"url" : "http://www.test.com/5"
}, {
"y" : 2,
"url" : "http://www.test.com/6"
} ],
"positive" : [ {
"y" : 230,
"url" : "http://www.test.com/7"
}, {
"y" : 50,
"url" : "http://www.test.com/8"
}, {
"y" : 483,
"url" : "http://www.test.com/9"
} ]
}
}
Let's say I want to sort the negative values descending by y's value, then my JSON should look like this:
{
"chartSeries" : {
"negative" : [ {
"y" : 1505,
"url" : "http://www.test.com/1"
}, {
"y" : 1046,
"url" : "http://www.test.com/3"
}, {
"y" : 425,
"url" : "http://www.test.com/2"
} ],
"neutral" : [ {
"y" : 10,
"url" : "http://www.test.com/4"
}, {
"y" : 2,
"url" : "http://www.test.com/6"
}, {
"y" : 1,
"url" : "http://www.test.com/5"
} ],
"positive" : [ {
"y" : 230,
"url" : "http://www.test.com/7"
}, {
"y" : 483,
"url" : "http://www.test.com/9"
}, {
"y" : 50,
"url" : "http://www.test.com/8"
} ]
}
}
note how the negative elements are ordered by their descending y-values and neutrals' and postives' values are ordered exactly in the same sequence.
I tried parsing it as Javascript object using JSON.parse() and then using a sort function:
function sortResults(data, prop, asc) {
sorted_data = data.sort(function(a, b) {
if (asc) return (a[prop] > b[prop]);
else return (b[prop] > a[prop]);
});
return sorted_data;
}
But I just get "TypeError: data.sort is not a function" in my debugger.
Any explanations or advices are kindly appreciated!
And do not forget to add a paseInt() to ensure all the keys are integers. I had somy funny time figuring that back in the days.
I'll stick with JSON.sortify (https://www.npmjs.com/package/json.sortify) as it perfectly suits my needs.
The code behind that magical function:
function sortKeys(o) {
if (Array.isArray(o)) {
return o.map(sortKeys)
} else if (o instanceof Object) {
var _ret = function() {
var numeric = [];
var nonNumeric = [];
Object.keys(o).forEach(function(key) {
if (/^(0|[1-9][0-9]*)$/.test(key)) {
numeric.push(+key)
} else {
nonNumeric.push(key)
}
});
return {
v: numeric.sort(function(a, b) {
return a - b
}).concat(nonNumeric.sort()).reduce(function(result, key) {
result[key] = sortKeys(o[key]);
return result
}, {})
}
}();
if (typeof _ret === "object") return _ret.v
}
return o
};
And that's it.

mongodb update on JSON array

I have this data in Mongo:
{'_id':1,
'name':'Root',
'taskId':1,
'parentId':"",
'path':[1],
'tasks':[ {"taskId":3,parentId:1,name:'A',type:'task'},
{"taskId":4,parentId:1,name:'D',type:'task'},
{"taskId":5,parentId:4,name:'B',type:'task'},
{'type':'project' , 'proRef':2},
{"taskId":6,parentId:3,name:'E',type:'task'},
{"taskId":7,parentId:6,name:'C',type:'task'}]
}
Now I want to update taskId 6 with new Json data .
var jsonData = {"taskId":6,"name":'Sumeet','newField1':'Val1','newField2':'Val2'}
query should update if field is available else add new key to existing .Output Like
{"taskId":6,parentId:3,name:'Sumeet',type:'task','newField1':'Val1','newField2':'Val2'}]
I have tried few query but it is completely replacing json .
db.projectPlan.update({_id:1,'tasks.taskId':6},{$set :{'tasks.$':jsonData }});
Thanks in advance for your helps!
Sumeet
You need to transform the jsonData variable into something that can be passed to update. Here's an example that does exactly what you want with your sample document:
var updateData = {};
for (f in jsonData) {
if (f != "taskId") updateData["tasks.$."+f]=jsonData[f];
};
db.projectPlan.update({_id:1, 'tasks.taskId':6}, {$set:updateData})
Result:
{ "_id" : 1,
"name" : "Root",
"taskId" : 1,
"parentId" : "",
"path" : [ 1 ],
"tasks" : [
{ "taskId" : 3, "parentId" : 1, "name" : "A", "type" : "task" },
{ "taskId" : 4, "parentId" : 1, "name" : "D", "type" : "task" },
{ "taskId" : 5, "parentId" : 4, "name" : "B", "type" : "task" },
{ "type" : "project", "proRef" : 2 },
{ "taskId" : 6, "parentId" : 3, "name" : "Sumeet", "type" : "task", "newField1" : "Val1", "newField2" : "Val2" },
{ "taskId" : 7, "parentId" : 6, "name" : "C", "type" : "task" }
] }
You will need to merge the document manually:
var jsonData = {"taskId":5,"name":'Sumeet','newField1':'Val1','newField2':'Val2'};
db.projectPlan.find({ _id: 1 }).forEach(
function(entry) {
for (var taskKey in entry.tasks) {
if (entry.tasks[taskKey].taskId === jsonData.taskId) {
printjson(entry.tasks[taskKey]);
for (var taskSubKey in jsonData) {
entry.tasks[taskKey][taskSubKey] = jsonData[taskSubKey];
}
printjson(entry.tasks[taskKey]);
}
}
db.projectPlan.save(entry);
}
);
Obviously you can leave away the printjson statements. This is simply to see that the merging of the original tasks with the new tasks works. Note that this query will only update a single document as long as the _id field is unique.

Categories

Resources