Insert a whole json Without creating different node in mongodb - node.js

i have a collection named drop down and i want to insert all the drop down static JSON values in a single collections without creating different node
for eg this is my json
"education": [
"Master",
"Bachelor"
],
"diet": [
"Veg",
"Non Veg"
]
Later on if i need to add more drop down values i don't have to alter the mongoose schema ,i could directly insert the json list
Is it possible or not? Sorry i am new to the Mongodb

Finally an idea strike on my mind and got the appropriate answer of my own question and like to share here. What i did is , I create the Schema as
const mongoose = require('mongoose');
const dropDownSchema = new mongoose.Schema({dropDown : mongoose.Schema.Types.Mixed})
module.exports.DropDownList =mongoose.model("DropDownList",dropDownSchema);
later on while passing data from the client
{
"dropDown":
{
"education": [
"Master"
,"Bachelor"
],
"diet": [
"Veg"
,"Non Veg"
]
}
}
While inserting data i first delete all data and insert the fresh one from the API

First find the document in that collection. Assume that we are requesting with the document _id and we are using mongoose model named Dropdown.
Example:
const document = await Dropdown.findOne({_id});
//Once you have found the document
// Add or change the existing fields
document[new_value_name] = new_values.map(val => val);
await document.save();

If you want to store it in array of object in mongodb then you can also create a schema with Array of dropdowns
var DropdownSchema = new mongoose.Schema({
dropdowns:[{
dropdown_key: { type: String },
dropdown_values: [{type: String}]
}]});
While inserting data you will need to loop through Object.keys of your json list and insert into as array . You can add number of dropdown as it is stored as array of object.
Please let me know if it helps.

Related

How to add new fields to the last object in an array in MongoDB?

I have an Array of objects in mongoDB as follow
Initially there is only the heartRate field inside the object. Now I want to add new fields to this object along with the existing heartRate field.
Also there can be multiple objects inside the dailyReadings array. Therefore, I need to add new fields only to the last object using nodejs and expressjs
I tried using the $push method but ended up adding new object intead of adding the fields to the last object. Is there a way to achieve this? Thanks in advance!
Why I am doing this (For further understanding):-
I have developed a mobile app to read the heart rate. Initially it will save the heart rate in the database as a new object (As in the image). Then, there are several other data sent through a desktop application which needs to add to the same object (Which is the last object in the dailyReadings array)
There is no straight way to do this, you can try update with aggregation pipeline starting from MongoDB 4.2,
$size to get total elements in dailyReadings array
$subtract to minus 1 from above total elements
$slice to get elements other than the last object element
$slice to get last object element by -1 from dailyReadings
$arrayElemAt to select first object element from array
$mergeObjects to merge existing object fields of the last object and new fields that you want to insert
$concatArrays to concat first slice array and second updated object
db.collection.update(
{}, // put your query condition
[{
$set: {
dailyReadings: {
$concatArrays: [
{
$slice: [
"$dailyReadings",
0,
{ $subtract: [{ $size: "$dailyReadings" }, 1] }
]
},
[
{
$mergeObjects: [
{ $arrayElemAt: [{ $slice: ["$dailyReadings", -1] }, 0] },
{
newField: "1"
}
]
}
]
]
}
}
}]
)
Playground
In order for you to add fields to the last object, the heartRate should be an object with a schema containing the following
Array (for you to add to)
any other necessary data type you'd want the object to have
you must define a complex schema using mongoose, perform the following changes to your file of model
const mongoose = require('mongoose');
const childSchema = mongoose.Schema({
heartRate: {type: Array, required: true}
array: {type: Array, required: false}, //change the required parameter based on your requirement
});
const parentSchema = mongoose.Schema({
dailyReadings: {
type: childSchema,
required: false //change the required parameter based on your requirement
},
});
module.exports = mongoose.model('modelCollection', parentSchema);
So basically you need to define the child schema, and change the type of dailyReadings to that schema and add to the array of different objects.

How do I use upsert and $addToSet in conjunction?

I would like to insert a document that looks like this:
{
name: "app1",
theArray: [...unique string elements...]
}
I tried to do an upsert using the query below but it somehow creates an array within an array if the document does not exist. If I use $push when the document does not exist, then the array is created fine. However I need to use $addToSet to maintain array element uniqueness.
Current query:
collection1.upsert({
name: "app1",
}, {
$addToSet: {
theArray: data // data is an array of ip addresses eg. ["1.1.1", "2.2.2.2"] which is not unique
}
});
Executing the above query when there is no existing document in the db creates:
{
name: "app-1",
theArray: [
//another array that contains the actual data.
]
}
Is there a way I can get this behavior with just a single query?

node.js to check out duplication value in mongoose

Now I'd like to save my json data into mongoose but the duplicate value had to be filtered.
my_json = [
{"name":"michael","age":21,"sports":"basketball"},
{"name":"nick","age":31,"sports":"golf"},
{"name":"joan","age":41,"sports":"soccer"},
{"name":"henry","age":51,"sports":"baseball"},
{"name":"joe","age":61,"sports":"dance"},
];
Database data is :
{
"name":"joan","age":41,"sports":"soccer"
}
Is there some specific method to avoid duplicate data insert to mongoose directly? It might be saved 4 of values except "joan" value.
Once I suppose to try to use "for statement", it was fine.
However I just want to make a simple code for that what could happen in a variety possible code.
for(var i = 0; i < my_json.length; i++){
// to check out duplicate value
db.json_model.count({"name":my_json[i].name}, function(err, cat){
if(cat.length == 0){
my_json_vo.savePost(function(err) {
});
}
})
};
As you see I need to use count method whether the value is duplicated or not. I don't want to use count method but make it more simple..
Could you give me an advice for that?
You can mark field as unique in mongoose schema:
var schema = new Schema({
name: {type: String, required: true, unique: true}
//...
});
Also, you can add unique index for name field into your database:
db.js_model.createIndex( {"name": 1}, { unique: true, background: true } );
then, if new entity with the same name will be asked to save - mongo won't save it, and respond an error.
In Addition to #Alex answer about adding unique key on the name field.
You can use insertMany() method with ordered parameter set to
false. Like this...
let my_json = [
{"name":"michael","age":21,"sports":"basketball"},
{"name":"nick","age":31,"sports":"golf"},
{"name":"joan","age":41,"sports":"soccer"},
{"name":"henry","age":51,"sports":"baseball"},
{"name":"joe","age":61,"sports":"dance"},
];
User.insertMany(my_json ,{ordered :false});
This query will successfully run and insert unique documents, And also
produces error later after successful insertion. So You will come to
know that there were duplicate records But now in the database, all
records are unique.
Reference InsertMany with ordered parameter

DynamoDB update inside an array of objects (nodejs)

I noticed that DynamoDB can add and remove items from an array but how do you search for an specific item inside an object if you want to update that one specifically?
For example:
In MongoDB you can search for someitem.$.subitem and update that specific item.
Is there a way on how to do this with DynamoDB?
Item: {
someitem: [
{
subitem: "id",
somevalue: "something"
}
]
}
I would say this is basic functionality but seems not easy to find (or even unsupported)
AWS does not permit to modify it in a single update request more info was found in the following answers:
updating-a-json-array-in-aws-dynamodb.
The solution that they propose is to change the schema from array to {}, or to implement a custom functions and iterate through each array and find your new id to update, so to speak to programatically update your json and then insert whole object.
TableName : 'tablename',
Key : { id: id},
ReturnValues : 'ALL_NEW',
UpdateExpression : 'set someitem['+`index`+'].somevalue = :reply_content',
ExpressionAttributeValues : { ':reply_content' : updateddata }
array element edit via array index

MongoDB not updating subdocument within double-nested array (using Mongoose FindByIdAndUpdate) - EXACT POSITION KNOWN

I have a document structure that's roughly similar to the following:
{
"_id": "theIdOfThisObject",
"subdoc": {
"array": [
[
{
"parameters": {},
"winner": null,
"participants": [
"Person1",
"Person2"
]
},
{
"parameters": {},
"winner": null,
"participants": [
"Person3",
"Person4"
]
}
],
[]
]
},
}
I am entirely trying to replace one of the subdocuments within the nested array. I do not need to search for it - i know the exact position.
For example, I am trying to replace the first subdocument with
"parameters": {"frog":20},
"winner": "Person1",
"participants": [
"Person1",
"Person2"
]
which we'll say is saved as an object called newObject.
I expect the following code to work (and Model is a real Mongoose Model):
Model.findByIdAndUpdate('theIdOfThisObject',{$set: {'subdoc.array.0.0':newObject}}, function(err,doc){
console.log('doc is returned, but nothing is updated')
});
I have no idea what is going on and why this isn't working. Does anybody have any suggestions? I have been using MongoDB's native node driver for a very long time (3 years), but Mongoose is fairly new to me.
EDIT - adding schema as per comment request
The schema is pretty straightforward. looks as follows:
var Schema = new mongoose.Schema({
subdoc: {
array: [{}]
}
});
There's other fields in there, but this is the only one that matters in this case. My understanding is that having the Schema have a [{}] means that there will be an array of any kind of JSON arrangement. The Schema also lets me initially set the subdocument in question - it just doesn't let me update it for whatever reason.
I have figured out the issue. Apparently when using the Mixed Schema type, (which is the same as {}) with Mongoose, updating a subfield within the object is a 2 step process. You can't just use findByIdAndUpdate().
You must first use fineById(), grab the document in the callback, run markModified() on the document in question (passing in the path to the subdocument), and then finally save said document. Here's the code:
Model.findById('theIdOfThisObject', function(err,doc){
//update the proper subdocument
doc.subdoc.array[0][0] = newObject;
//then mark it as modified and save it
doc.markModified('brackets.rounds');
//save the model
doc.save(callback);
});
Maybe there are two things here.
First, in your sheme i recommend that you use
var Schema = new mongoose.Schema({
subdoc: {
array: [{type: Schema.Types.Mixed}]
}});
so that it is rightly defined as there can be anything.
Or the second thing that might could be missing. If the existing entry doesn't exist you have to set the option upsert :true that new entrys will also get inserted.
Model.findByIdAndUpdate('theIdOfThisObject',{$set: {'subdoc.array.0.0':newObject}}, {upsert : true},console.log);
I had the same problem and I can confirm, this line was the fix:
doc.markModified('brackets.rounds');

Resources