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
}
I'd like to update the value of the key shouldSendAlert in the following document:
{
"_id" : ObjectId("5c61c4db46d18e1092c5b024"),
"service" : "SRVPVD",
"menu" : [
{
"sub" : [
{
"options" : [
{
"item" : [
{
"name" : "",
"actions" : [
{
"name" : "communicateClient",
"value" : true
},
{
"name" : "shouldSendAlert",
"value" : false
}
]
}
],
"name" : "Technology Support"
},
{
"item" : [
{
"name" : "",
"actions" : [
{
"name" : "communicateClient",
"value" : true
}
]
}
],
"name" : "Company Support"
}
],
"name" : "Support"
},
{
"name" : " FAQ"
}
],
"name" : "Help"
}
]
}
I've managed to do this, querying the document using a multiple $elemMatch query, and using forEach to run through the nested arrays in order to alter the value of shouldSendAlert:
{
let menuItems = db.getCollection('menumodels').find({menu: {$elemMatch: {name: 'Help',sub: {$elemMatch: {name: 'Support',motivos: {$elemMatch: {name: 'Technology Support'}}}}}}});
menuItems.forEach((r) => {
r.menu.forEach(menuItem => {
if (menuItem.name == 'Help') {
menuItem.sub.forEach(sub => {
if (sub.name == 'Support') {
sub.motivos.forEach(motivo => {
if (motivo.name == "Technology Support") {
motivo.item[0].actions.forEach(action => {
if (action.name == 'shouldSendAlert') {
action.value = true;
db.getCollection('menumodels').update({_id: r._id}, {$set: {menu: r.menu}})
}
})
}
})
}
})
}
})
});
}
Is it - regarding performance - necessary, to code this MongoDB query
or update logic into a smarter form? Does the multiple use of $elemMatch affect performance?
I have an array of data that is being used for some visualisation and is in the below format
var Dataset1 = [
{
"commentBy" : "saurabh",
"comment" : "Testing",
"datestamp" : "07/07/2017",
"weekcount" : 1
},
{
"commentBy" : "raman",
"comment" : "Planning",
"datestamp" : "07/07/2017",
"weekcount" : 1
},
{
"commentBy" : "Execution",
"comment" : "Alfa Beta",
"datestamp" : "07/07/2017",
"weekcount" : 2
},
{
"commentBy" : "Execution",
"comment" : "Zseta Gama",
"datestamp" : "07/07/2017",
"weekcount" : 2
}
]
//although i have tried writing this function but this is not giving me the desired result.
var groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
var groubedByTeam=groupBy(Dataset1, 'weekcount')
console.log(groubedByTeam);
I want to grouped the dataset by the weekcount so that the desired result should be like this.
[
{ "weekcount" : 1
"grouped" : [
{ "commentBy" : "saurabh",
"comment" : "Testing",
"datestamp" : "07/07/2017"
},
{
"commentBy" : "raman",
"comment" : "Planning",
"datestamp" : "07/07/2017"
}
]
}, {
"weekcount" : 2
"grouped" : [
{
"commentBy" : "Execution",
"comment" : "Alfa Beta",
"datestamp" : "07/07/2017",
},
{
"commentBy" : "Execution",
"comment" : "Zseta Gama",
"datestamp" : "07/07/2017",
}
]
}
]
const formatted = [];
Dataset1.forEach((data) => {
const { weekcount, comment, commentBy, datestamp } = data;
let obj = formatted.find((item) => item.weekcount === weekcount);
if (!obj) {
formatted.push({
weekcount,
grouped: [{
comment,
commentBy,
datestamp
}]
})
} else {
obj.grouped.push({
comment,
commentBy,
datestamp
});
}
});
const Dataset1 = [{
"commentBy": "saurabh",
"comment": "Testing",
"datestamp": "07/07/2017",
"weekcount": 1
}, {
"commentBy": "raman",
"comment": "Planning",
"datestamp": "07/07/2017",
"weekcount": 1
}, {
"commentBy": "Execution",
"comment": "Alfa Beta",
"datestamp": "07/07/2017",
"weekcount": 2
}, {
"commentBy": "Execution",
"comment": "Zseta Gama",
"datestamp": "07/07/2017",
"weekcount": 2
}];
const formatted = [];
Dataset1.forEach((data) => {
const { weekcount, comment, commentBy, datestamp } = data;
let obj = formatted.find((item) => item.weekcount === weekcount);
if (!obj) {
formatted.push({
weekcount,
grouped: [{
comment,
commentBy,
datestamp
}]
})
} else {
obj.grouped.push({
comment,
commentBy,
datestamp
});
}
});
console.log(formatted);
Here is a clean way to group the data, you should be able to figure out how to format it the way you want with this as a starting point.
grouped = {}
Dataset1.forEach(function(item, index){
if (!grouped[item.weekcount]) grouped[item.weekcount] = [];
grouped[item.weekcount].push(item);
});
grouped is an object keyed with the weekcount. If a certain weekcount doesn't exist as a key in the object, an empty array is created and then the data is pushed to it. On later iterations data with the same weekcount is added to the existing array.
You could check each weekcount from 0 to max, and filter your array. It could be something like this:
var Dataset1 = [
{
"commentBy" : "saurabh",
"comment" : "Testing",
"datestamp" : "07/07/2017",
"weekcount" : 1
},
{
"commentBy" : "raman",
"comment" : "Planning",
"datestamp" : "07/07/2017",
"weekcount" : 1
},
{
"commentBy" : "Execution",
"comment" : "Alfa Beta",
"datestamp" : "07/07/2017",
"weekcount" : 2
},
{
"commentBy" : "Execution",
"comment" : "Zseta Gama",
"datestamp" : "07/07/2017",
"weekcount" : 2
}
]
var maxWeekCount = 3;
var result = []
for(var i=0; i<maxWeekCount; i++){
var group = Dataset1.filter(obj => obj.weekcount === i)
if(group.length) {
result.push({
weekCount: i,
grouped: group
})
}
}
console.log(result)
Use a helper object, that maintains a reference to the weekcount objects, to reduce the array to the grouped structure.
var Dataset1 = [{"commentBy":"saurabh","comment":"Testing","datestamp":"07/07/2017","weekcount":1},{"commentBy":"raman","comment":"Planning","datestamp":"07/07/2017","weekcount":1},{"commentBy":"Execution","comment":"Alfa Beta","datestamp":"07/07/2017","weekcount":2},{"commentBy":"Execution","comment":"Zseta Gama","datestamp":"07/07/2017","weekcount":2}];
var helperMap = {};
var result = Dataset1.reduce(function(arr, obj) {
var current = helperMap[obj.weekcount];
if(!current) {
current = {
weekcount: obj.weekcount,
grouped: []
};
helperMap[obj.weekcount] = current;
arr.push(current);
}
current.grouped.push({
commentBy: obj.commentBy,
comment: obj.comment,
datestamp: obj.datestamp
});
return arr;
}, []);
console.log(result);
var groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
if(rv[x[key]] == undefined){
rv[x[key]] = {"weekcount": x[key], "grouped": []}
}
stripped = {}
for(var k in x) if(k!=key) stripped[k]=x[k]; //strip "key" property
rv[x[key]]["grouped"].push(stripped);
return rv;
}, []);
};
By stripping the "key" property, this solution works with any input without modification, so if you add/remove some properties from the input, it will still work as expected, reflecting the changes.
I am using for loop to get the units onebyone and inside loop I am getting the array of volumes like below. now I want to push that array to respective unit so I used push but here I am getting error.
My code is below
$scope.UnitDetails = [{
UnitId : "001"
Unit1 : "A"
Fields: [{"one" : "true","Isactive" : true },
{"two" : "false","Isactive" : true }
]
},
{
UnitId : "002"
Unit1 : "B"
Fields: [{"one" : "true","Isactive" : true },
{"two" : "false","Isactive" : true }
]
}]
for(i= 0; i < $scope.UnitDetails.length ; i++){
var volume = [];
volume.Volume_AL = eval($scope.VolumeFormula.AL);
volume.Volume_BL = eval($scope.VolumeFormula.BL);
volume.Volume_CL = eval($scope.VolumeFormula.CL);
volume.Volume_DL = eval($scope.VolumeFormula.DL);
$scope.UnitDetails[i].push(volume);
}
Can anyone find where i am doing mistake
EDIT
When I try as below then it is creating another array in object as below
for(i= 0; i < $scope.UnitDetails.length ; i++){
var volume = {};
volume.Volume_AL = eval($scope.VolumeFormula.AL);
volume.Volume_BL = eval($scope.VolumeFormula.BL);
volume.Volume_CL = eval($scope.VolumeFormula.CL);
volume.Volume_DL = eval($scope.VolumeFormula.DL);
$scope.UnitDetails.push(volume);
}
What I got
$scope.UnitDetails = [{
UnitId : "001"
Unit1 : "A"
Fields: [{"one" : "true","Isactive" : true },
{"two" : "false","Isactive" : true }
]
},
{
UnitId : "002"
Unit1 : "B"
Fields: [{"one" : "true","Isactive" : true },
{"two" : "false","Isactive" : true }
]
},
{
Volume_CL:0,
Volume_EQ:12,
Volume_PH:54,
Volume_RW: 24
}]
My Expected :
$scope.UnitDetails = [{
UnitId : "001"
Unit1 : "A"
Fields: [{"one" : "true","Isactive" : true },
{"two" : "false","Isactive" : true }
]
volume : [ {
Volume_CL:0,
Volume_EQ:12,
Volume_PH:54,
Volume_RW: 24
}]
},
{
UnitId : "002"
Unit1 : "B"
Fields: [{"one" : "true","Isactive" : true },
{"two" : "false","Isactive" : true }
]
volume : [ {
Volume_CL:0,
Volume_EQ:12,
Volume_PH:54,
Volume_RW: 24
}]
},
]
To achieve the desired result you could append the volume array dynamically to each element of $scope.UnitDetails:
for (var i = 0; i < $scope.UnitDetails.length; i++) {
$scope.UnitDetails[i].volume = [{
Volume_AL: eval($scope.VolumeFormula.AL),
Volume_BL: eval($scope.VolumeFormula.BL),
Volume_CL: eval($scope.VolumeFormula.CL),
Volume_DL: eval($scope.VolumeFormula.DL)
}];
}
Remark: The eval statement allows for execution of arbitrary javascript code and if the input is coming from your users you might want to ensure that it doesn't contain any malicious code before passing it to this function. Or even better do not use eval at all. Depending on your requirements you might find a more appropriate and restrictive function to achieve your goal. For example if you are expecting to evaluate only mathematical expressions written from your clients you might find a library designed exactly for this purpose rather than using the general purpose eval statement.
I have a Json array which has the elements below:
"adjacencies", "data", "id", "name".
In some elements, "adjacencies" does not exist.
This is an example:
var JsonArray = [
{
"id" : "id1",
"name" : "name1",
"data" : {
"$type" : "circle",
"$color" : "#AEC43B"
}
}, //Without "adjacencies"
{
"id" : "id2",
"name" : "name2",
"data" : {
"$type" : "circle",
"$color" : "#AEC43B"
}
}, //Without "adjacencies"
{
"adjacencies": [
{
"nodeTo": "id1",
"nodeFrom": "id3",
"data": {
"$color": "#416D9C"
}
}
],
"id" : "id3",
"name" : "name3",
"data" : {
"$type" : "circle",
"$color" : "#AEC43B"
}
} //With "adjacencies"
];
The first and the second elements doesn't contain "adjacencies", but the third element does.
In the loop for (i = 0; i < JsonArray.length; i++) how do I access the third element?
Is there a .contain property for example?
Thanks in advance:)
One way to do it is by checking if the value is of type undefined:
for (i = 0; i < JsonArray.length; i++) {
var item = JsonArray[i];
if (typeof item.adjacencies !== "undefined") {
// item has adjacencies property
}
}
As an aside: this is not a JSON array -- it's a Javascript array. There are no JSON objects, no JSON arrays, no JSON nothing. The only JSON-y thing that exists is plain JSON, which is a serialization format.
use hasOwnProperty
So you can do this
for (i = 0; i < JsonArray.length; i++){
if( JsonArray[i].hasOwnProperty('adjacencies') ){
//Do something here
}
}