MongoDB migrate Array to Dictionary - mongodb

I have an array inside my document that has no key right now. I want to add keys to the array.
So what I have is:
{
"arrayToConvert":[43.323,32.1223]
}
What I want to get as a result is:
{
"arrayToConvert":{"a":43.323,"b":32.1223}
}
Thanks for some help :)

Here is one way to do it with forEach:
db.collection.find().snapshot().forEach( function(document) {
db.collection.update(document, { $set: { arrayToConvert: { a: document.arrayToConvert[0], b: document.arrayToConvert[1] } } });
});

Related

Mongodb add an object to an object

Say I have a mongodb document I'm trying to update. The schema is level1 (object)> level2 (object) > "objects".
If I want to add another object to the end, what is the method to do that? Do I use findoneandupdate?
I'm trying to append an object to an object
As of right now, it overwrites whatever is in the object
await base.findOneAndUpdate({ baseURL: contentObject.basURL },
{
"links.subPageURLs": {
[contentObject.subPage]: contentObject.links.subPageurls[contentObject.subPage]
},
"content.subPageContent": {
[contentObject.subPage]: contentObject.content.subPageContent[contentObject.subPage]
}
}
}
},
{ upsert: true }, (err, doc) => {
console.log(err)
db.close()
})
My final product would look something like this:
subPages: {
contactus: ["www.example.com", "www.website.com/subpage", "etc..."],
aboutus: ["www.example.com", "www.website.com/subpage", "etc..."],
news: ["http://news.example.com", "www.newsexample.com", "etc..."]
}
}
Then if i had another page to add, i would add it to the subPages object
login: ["login.example.com", "signup.example.com"]
To append an object to another object you can try to do this.
const a = { name:`Bob`, age:30 }
const b = { gender:`M`, age:45 }
const c = { ...a, ...b } //this will merge "a" with c
console.log(c) // will print { name:`Bob`, age:45, gender:`M` }
So it will work like that all properties in right object will overridden by left object and the left object properties does n't exists in right object will be appended.

How can I return the element I'm looking for inside a nested array?

I have a database like this:
[
{
"universe":"comics",
"saga":[
{
"name":"x-men",
"characters":[
{
"character":"wolverine",
"picture":"618035022351.png"
},
{
"character":"cyclops",
"picture":"618035022352.png"
}
]
}
]
},
{
"universe":"dc",
"saga":[
{
"name":"spiderman",
"characters":[
{
"character":"venom",
"picture":"618035022353.png"
}
]
}
]
}
]
and with this code I manage to update one of the objects in my array. specifically the object where character: wolverine
db.mydb.findOneAndUpdate({
"universe": "comics",
"saga.name": "x-men",
"saga.characters.character": "wolverine"
}, {
$set: {
"saga.$[].characters.$[].character": "lobezno",
"saga.$[].characters.$[].picture": "618035022354.png",
}
}, {
new: false
}
)
it returns all my document, I need ONLY the document matched
I would like to return the object that I have updated without having to make more queries to the database.
Note
I have been told that my code does not work well as it should, apparently my query to update this bad, I would like to know how to fix it and get the object that matches these search criteria.
In other words how can I get this output:
{
"character":"wolverine",
"picture":"618035022351.png"
}
in a single query using filters
{
"universe": "comics",
"saga.name": "x-men",
"saga.characters.character": "wolverine"
}
My MongoDB knowledge prevents me from correcting this.
Use the shell method findAndModify to suit your needs.
But you cannot use the positional character $ more than once while projecting in MongoDb, so you may have to keep track of it yourself at client-side.
Use arrayFilters to update deeply nested sub-document, instead of positional all operator $[].
Below is a working query -
var query = {
universe: 'comics'
};
var update = {
$set: {
'saga.$[outer].characters.$[inner].character': 'lobezno',
'saga.$[outer].characters.$[inner].picture': '618035022354.png',
}
};
var fields = {
'saga.characters': 1
};
var updateFilter = {
arrayFilters: [
{
'outer.name': 'x-men'
},
{
'inner.character': 'wolverine'
}
]
};
db.collection.findAndModify({
query,
update,
fields,
arrayFilters: updateFilter.arrayFilters
new: true
});
If I understand your question correctly, your updating is working as expected and your issue is that it returns the whole document and you don't want to query the database to just to return these two fields.
Why don't you just extract the fields from the document returned from your update? You are not going to the database when doing that.
var extractElementFromResult = null;
if(result != null) {
extractElementFromResult = result.saga
.filter(item => item.name == "x-men")[0]
.characters
.filter(item => item.character == "wolverine")[0];
}

Mongoose, change value in array

I am trying to update a value in an array, i tried doing it this way:
Mongoose, update values in array of objects
But it doesn't seem to work for me:
let myLessonDB = await myLessonSchema.findById(req.params.id);
myLessonDB.update(
{ 'lessons.lesson': req.body.lessonID },
{ $set: { 'lessons.$.present': true } }
);
myLessonDB return this:
{"_id":"5eafff00726616772ca852e2",
"lessons":[{"level":"1","present":false,"lesson":"5eb00211154ac86dc8459d6f"}],
"__v":0}
I am trying to change a value in lessons by the lesson ID as shown but it doesn't work.
No errors or anything it looks like it cant find the object in the array
Anyone know what I am doing wrong?
let myLessonDB = await myLessonSchema.findById(req.params.id);
myLessonDB.lessons.map(oneLes => {
if(oneLes.lesson == req.body.lessonID){
oneLes.present = true;
}
})
myLessonDB.save().then( finalLesson => {
console.log(finalLesson);
})

how to find all if the array is empty, mongodb

i am trying to do some queries to my db... but i am new in mongodb and i dont know what operator i have to use, or maybe i just do not know how to do it.
i have a collection like this.
const userSchema= new Schema({
user: { type: String },
object: { type: String }
})
then i receive in my server a query like this
{
users: ['John', 'Michael', 'Peter'],
objects: ['Object1','Object2','Object3','Object4', 'Object5']
}
so.. in my controller i do this to find...
userModel.find({ user: { $in: req.body.users}, object: { $in: req.body.objects})
.then((users)=>{
res.json(users)
})
Ok, this is working... but, in the case that one of the arrays Users or Objects is empty, it doesn't find nothing... so, how i can handle it? there is any operator that can find all if the array is empty or something?
for example.. if the query comes like this.
{
users: ['John', 'Michael', 'Peter'],
objects: []
}
i would like to find the users in my Users array even if i dont receive any object.
Any help? thank you in advance
You have to create custom match criteria
const query = {
fieldName: { $gte: ..., $lte: ... }
}
if (req.body.users.length > 0) {
query.users = req.body.users
}
if (req.body.objects.length > 0) {
query.objects = req.body.objects
}
userModel.find(query).then((users) => {
console.log(users)
})

Mongoose remove one object from array of array

I have Mongoose schema like this:
{
......
project: [
{
Name: String,
Criteria:[
{
criteriaName:String,
}
]
}
]
......
}
And I want to remove one of the objects of criteria array which is in the array of project based on the object id
I tried the code following
criteria.findOneAndUpdate({
"_id": uid,
},{ $pull: { "project.Criteria": { _id: cid } } }, (err) => {
......
}
However this cannot work, it said "Cannot use the part (Criteria) of (project.Criteria) to traverse the element"
Do you need to do it in one query to the database? If not, the following solution may work for you:
criteria.findOne({ _id: uid })
.then((obj) => {
// Filter out the criteria you wanted to remove
obj.project.Criteria = obj.project.Criteria.filter(c => c._id !== cid);
// Save the updated object to the database
return obj.save();
})
.then((updatedObj) => {
// This is the updated object
})
.catch((err) => {
// Handle error
});
Sorry if the .then/.catch is confusing. I can rewrite with callbacks if necessary, but I think this looks a lot cleaner. Hope this helps!