I've got the following document named "clients" which includes id, name and list of projects (array of objects):
{
"_id": {
"$oid": "572225d997bb651819f379f7"
},
"name": "ppg",
"projects": [
{
"name": "aaa",
"job_description": "",
"projectID": 20
},
{
"name": "bbbb",
"job_description": "",
"projectID": 21
}
]
}
I would like to update "job_description" of project with given "projectID" like this:
module.exports.saveJobDesc = function(client, idOfProject, textProvided) {
db.clients.update({ name: client},
{ $set: {'projects.0.job_description': textProvided }});
};
But instead of hardcoded index "0" of array I want to find specific project using "projectID". Is there a way to achieve this without changing the structure of collection and/or document?
If you want to update the "job_description" where name="ppg" and project_id=20 then you can use below mongo query:-
db.clients.update({ "name":"ppg","projects.projectID":20 },{$set: {"projects.$.job_description": "abcd"}})
Please let me know if any thing else is required
You cannot update multiple array elements in single update operation, instead you can update one by one which takes time depends upon number of elements in array and number of such documents in collection. see New operator to update all matching items in an array
db.test2.find().forEach( function(doc) {
var projects = doc.projects;
for(var i=0;i<projects.length;i++){
var project = projects[i];
if(project.projectID == 20){
var field = "projects."+i+".job_description";
var query = {};
query[field] = "textasdsd";
db.test2.update({ _id: doc._id},{ $set:query});
}
}
})
Related
I want to update a single Object in my localStorage. I made a detail page, where I can submit new values (progress and value)
When I want to update the value, it changes the value in both objects. How can I change just one object.
Here is my deployment link.(its work in progress)
https://mastery-app.herokuapp.com/
This is my localStorage array:
skills[
{
"title": "Sewing",
"imageSrc": "images.unsplash.com",
"description": "Make your own clothes",
"category": "crafting",
"progress": 500,
"isDone": false,
"rank": 0,
"value": 0
},
{
"title": "Crocheting",
"imageSrc": "images.unsplash.com",
"description": "Interlock loops of yarn",
"category": "crafting",
"progress": 500,
"isDone": false,
"rank": 0,
"value": 0
}
]
This is how I update the localStorage:
const update = skills.map((skills) => {
skills.title === skills.title;
const updateProgress = skills.progress - value;
const rankNumber = parseInt(ranking);
const updateRank = skills.rank + rankNumber;
console.log(updateRank);
const updateValue = skills.value + value;
return {
title: skills.title,
rank: updateRank,
description: skills.description,
progress: updateProgress.toFixed(1),
imageSrc: skills.imageSrc,
category: skills.category,
isDone: false,
value: updateValue,
};
});
localStorage.setItem('skills', JSON.stringify(update));
You may consider using the find method to find the object you want to update. map is not the right function to be used for your use case.
Also skills.title === skills.title; has no effect at all (Maybe you wanted to use an if statement to do some kind of filtering by using title but that always would return true). Please remove that.
Now, I don't exactly know which field are you going to use to search for the object you want to update, but it has to be unique. If none of the fields in the objects are unique you should consider adding an unique id field in the skills objects. But if title is unique you can use the title to search. Then you can do something like the pseudo code below:
const toUpdate = skills.find(skill => skill.title === your_title_here)
toUpdate.field_to_update_1 = some_value_1
toUpdate.field_to_update_2 = some_value_2
localStorage.setItem('skills', JSON.stringify(skills))
Please also check the MDN docs to see how map, find and other array methods work and some of their use cases.
I was given an existing project where the data structure is below:
[
{
"key": "username",
"value": ""
},
{
"key": "password",
"value": ""
},
{
"key": "cars",
"value": [
{"ABC-1234-1234": "s4LmoNzee9Xr6f7uu/"},
{"ABC-5678-5678": "s5LmoNzee9Xr5f9uu/"}
]
}
]
Cars' value is an array of objects.
To create the initial object in the cars' array, I do the following:
var encryptedStuff = json.data;
var carkey = carid;
var entry = {};
entry[carkey] = encryptedStuff;
var carArray = [];
key="cars";
carArray.push(entry);
I need to push the array into another function that turns it into a string in a stored variable.
My problem...and I'm really rusty on embedded objects...is to do the following:
1.) Get the string
2.) JSON.parse back into an object (I got this far as I'm using a jQuery grep but I'd prefer to use JavaScript).
Here's my problem...
3.) locate the cars key in the object and get its value.
4.) Turn the value into an array to either delete an item or to add one (as per the code above where I'm writing the object into the array.
In the case of adding, I would have to copy the cars' value into the carArray[] and then push the new item into it.
In the case of deleting, I would have to remove the item and push back everything back into the carArray[].
I would do things differently but I can't change the structure of the data as this is approved company-wide.
Any help would be appreciated.
Thanks
You don't need to make a copy of the car's value array to add new entries nor make a copy then "push back" to remove an entry - you can reference it directly in the parsed object.
You can use
JSON.parse
array.find
array.push
array.splice
JSON.stringify
Giving:
var source = `[
{
"key": "username",
"value": ""
},
{
"key": "password",
"value": ""
},
{
"key": "cars",
"value": [
{"ABC-1234-1234": "s4LmoNzee9Xr6f7uu/"},
{"ABC-5678-5678": "s5LmoNzee9Xr5f9uu/"}
]
}
]`
// convert json to an object
var data = JSON.parse(source);
console.log(data, data.find(e=>e.key=="cars").value)
// add an item to the cars.value
data.find(e=>e.key=="cars").value.push({"ABC-": "s6..." });
// remove an item from the cars.value
data.find(e=>e.key=="cars").value.splice(1,1);
// confirm items added/removed
console.log(data, data.find(e=>e.key=="cars").value)
// convert back to a strng to send back to the service
var result = JSON.stringify(data);
console.log(result);
I want to add a new object for each nested array. I'm calling this function any time I add a product to my orderintake:
add2order(productID, productName, productRatePlans) {
this.orderIntake.push({ productID, productName, productRatePlans });
let i = 0;
this.orderIntake[0].productRatePlans[0].productRatePlanCharges.forEach(element => {
i++;
this.orderIntake[0].productRatePlans[0].productRatePlanCharges[
i
].quantity = this.orderIntake[0].productRatePlans[0].productRatePlanCharges[
i
].defaultQuantity;
});
}
this is an example response from the server:
{
"id": "8adc8f996928b9a4016929c59b943a8f",
"sku": "SKU-00006778",
"Partner_Account_ID__c": null,
"productRatePlans": [
{
"id": "8adce4216928c28d016929c59bff3372",
"status": "Active",
"name": "Enterprise",
"description": null,
"effectiveStartDate": "2016-02-26",
"effectiveEndDate": "2029-02-26",
"productRatePlanCharges": [
{
"id": "8adc8f996928b9a4016929c59d183a92",
"name": "USAGE_COUNTER_2",
"type": "Usage",
"model": "Volume",
"uom": "Each",
"pricingSummary": [
"Up to 5000 Each: USD0 flat fee"
],
"pricing": [
{
...
}
],
"defaultQuantity": null,
"applyDiscountTo": null,
"discountLevel": null,
"discountClass": null,
...
"financeInformation": {
..,
}
}
]
}
],
"productFeatures": [
{
...
}
]
}
The data is being retrived this way from an external REST backend so unfortunately I can't initialize the data including the new property...
so in every productRatePlanCharges there should be 1 new object 'quantity'.
How can I add this field to every productRatePlanCharges?
Right now I'm getting: ERROR
TypeError: Cannot read property 'productRatePlanCharges' of undefined
And how can I make sure I'm always adding this to the last orderIntake element? Don't mind productRatePlans there is only 1 in each orderintake...
thanks for your support!
Here you have to create productDetails object with inititalised array like below so that you won't get the error.
add2order(productID, productName, productRatePlans) {
// Create object like below
let productDetails = { productID : productID, productName : productName, productRatePlans : productRatePlans
}
this.orderIntake.push(productDetails);
let i = 0;
this.orderIntake[0].productRatePlans[0].productRatePlanCharges.forEach(element => {
i++;
this.orderIntake[0].productRatePlans[0].productRatePlanCharges[
i
].quantity = this.orderIntake[0].productRatePlans[0].productRatePlanCharges[
i
].defaultQuantity;
});
}
Hope this will help!
as you used Angular you probably use Typescript too. I recommend that you create a model like your incoming model and there define your quantity: number inside productRatePlanCharges object. then map the incoming data to your own model. therefore you will have a quantity=0 in your model that you can change it later in a loop.
If you want to continue with your own way take a look at this:
Add new attribute (element) to JSON object using JavaScript
there is no problem to add an element to current model almost like you did, and the problem might be somewhere else as your error refers to existence of productRatePlanCharges!
as you used forEach I prefer to use that 'element' and double iterating with i++; is not a good idea to me.
this might be better:
element.quantity = element.defaultQuantity;
I am trying to figure out how to update a nested array that is within an array with Mongoose. In my User collection, I have a customer array that contains customer info, along with a nested fleet array that holds the customer's fleet equipment. I am trying to update the fleet array via a PUT request, but am having difficulties.
I partially think it is not possible to update a nested array within an array like this, and maybe I should create a separate Schema for the customer and fleet. Anyways, here is what my User Schema looks like currently:
{
"username": "xps_maint",
"password": "0000",
"registerDate": "2018-10-24T13:37:12.093Z",
"_id": "5bd07612d63de74932734d92",
"customer": [
{
"name": "Freight Service ",
"email": "info#fsllc.com",
"dotInterval": "90 days",
"fleet": [
{
"unitType": "Box Truck",
"unitNumber": "BT-61318",
"vinNumber": "1XXXYYYUUUZZ3222",
"_id": "5bd0aef1e2abd64b12e0ab42"
},
{
"unitType": "Cargo Van",
"unitNumber": CV-78453",
"vinNumber": "4ZZYYYTTUZZ3JK2",
"_id": "5bd0aef1e2arg64b15e0ab43"
}
],
"_id": "5bd0821f79f9454b06b2c2bf"
}
],
"__v": 0
}
Here is my PUT route to update the fleet array:
router.put('/customers/fleet/:equipmentid', customer_controller.customer_update_fleet);
And finally here is the what the fleet update controller looks like:
exports.customer_update_fleet = (req, res) => {
const { body, params } = req;
const { unitType, unitNumber, vinNumber } = body;
const { equipmentid } = params;
const updatedEquipment =
{
unitType: unitType,
unitNumber: unitNumber,
vinNumber: vinNumber,
}
User.updateOne({ 'customer.$.fleet': { _id: equipmentid }}, { $set: { 'customer.$.fleet': { updatedEquipment} } }, (err) => {
if (err)
throw err;
else
res.send('Success!!');
});
}
I thought this might of worked, because I have a similar PUT route that updates just the customer array in the User Schema via Model.updateOne(). However this does not seem to work the same way when trying to go deeper into the nested fleet array within each customer.
I may be approaching this all wrong, so I am all ears on a better way to model the User Schema. I do partially think that it is not too good to have arrays nested deep in Schemas like this, they seem like a pain to update. Thanks in advance for reading!
I have the following array of objects. Currently it have one object containing several inside of it.
let arr =
[
{
"data": {
"Score": {
"score": [
"87",
"21"
],
"Player": [
"Wiki",
"Tim"
]
},
"Designation": {
"By": [
"0",
"0",
"1",
"0",
"0"
],
"Position": [
"31/07/17",
"31/07/17",
"31/07/17",
"31/07/17",
"31/07/17"
]
},
"Address": {
"Location": "London",
"House_No": "43-B",
}
}
}
]
The above data will go in one table.
I have tried looping it and inserting but did't got any way out. The above data is not constant means will change like Position have 5 elements, It can be 6 next time, So i cannot simply insert it via its indexes.
I have tried things but no success.
Mysql can store json data, and you can parse after you fetch, even you can parse json data from mysql queries but thats little complex if data changes, so its better to store it, fetch and parse.
You can select feild type JSON and store json in it.
CREATE TABLE `book` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(200) NOT NULL,
`tags` json DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
you can insert json data in it by using php function:-
$json_data = json_encode($json_data);
insertion command will be:-
INSERT INTO `book` (`title`, `tags`)
VALUES (
'ECMAScript 2015: A SitePoint Anthology',
'$json_data'
);
For manipulating json data via mysql queries there are several function like JSON_ARRAY(), JSON_OBJECT() and so on, which you can prefer to use. Please refer to below article for details:-
https://www.sitepoint.com/use-json-data-fields-mysql-databases/
In Mongodb if you have dynamic data you can use mixed type schema like below:-
details:Schema.Types.Mixed,
Sample schema:-
// grab the things we need
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var mongoosePaginate = require('mongoose-paginate');
// create a schema
var casesSchema = new Schema({
sku: {type:String, unique:true},
details:Schema.Types.Mixed,
created_at: {type:Date, default: Date.now},
images: Schema.Types.Mixed,
ebay_hosted_images: Schema.Types.Mixed,
cloudinary_hosted_images: Schema.Types.Mixed,
dropbox_hosted_images: Schema.Types.Mixed,
is_listed:Boolean,
user_id : {type: String, ref:'User'}
});
casesSchema.plugin(mongoosePaginate);
var cases = mongoose.model('cases', casesSchema);
module.exports = cases;
In ES6 you can simply get all keys and value of an object like this:Object.keys(myObj).forEach(key => {
console.log(key); // the name of the current key.
console.log(myObj[key]); // the value of the current key.
});
If it is an array for each use to get the all values
arr.forEach(function(element) {
console.log(element);
});
arr.push(element) is used to push the element to as last index of array.