I'm trying to delete an object inside an array in my DB using the $pull in Mongoose but does not work.
This is my attempt:
const listSchema = new Schema({
name: String,
items: []
});
const List = mongoose.model("list", listSchema);
const itemDeleted = req.body.checkbox;
//I get here the ID of the object inside the array
const itemListDeleted = req.body.listDeleted;
// Here the name of the object that contains the array
List.findOneAndUpdate({name:itemListDeleted},{$pull:{items:{_id: itemDeleted}}},function (err,foundList) {
if (foundList){
res.redirect("/"+ itemListDeleted);
} else {
console.log(err);
}
})
I searched for solutions and everybody recommends using $Pull but in my case, it doesn't work. I log the const and all things appear to be right.
Do you have any suggestions?
Related
I have a Collection called Notes which has a document that is an UID of the user that consists of collection of an Array of objects which look something like this
obj {[
{title:"Note 1",desc:"description 1"},
{title:"Note 2",desc:"description 2"},
{title:"Note 3",desc:"description 3"},
]}
this is the actual Firestore collection where is now allowing me to store objects with the same key using the code I wrote but If I'm trying to add it manually then I
I'm using React with Firebase and using Firestore as a database
the problem I'm facing is that if I add more objects to the array mentioned above with the same key it's not creating a duplicate Firestore is not letting me add more objects with the same key. Other than that it is running just fine.
Below is the code for adding a new Notes Collection
// this function create a new Notes Collection
const createNotes = async (title, description) => {
const uid = auth.currentUser.uid; // For document name
const notesRef = doc(db, "Notes", uid);
const data = {
note: [{ title: title, description: description }],
};
try {
await setDoc(notesRef, data);
} catch (error) {
console.log(error);
}
};
Below is the code for updating the array of objects, this was the only way I could find to add multiple objects into an array on firestore
const updateNotes = async (title, description) => {
const uid = auth.currentUser.uid;
const notesRef = doc(db, "Notes", uid);
const data = {
note: arrayUnion({ title: title, description: description }),
};
try {
await updateDoc(notesRef, data, { merge: true });
} catch (error) {
console.log(error);
}
};
Is there a solution to this?
According to your last comment:
If suppose I have added an array field such as {title:”a”,desc:”b”} in the array and if again try to add the same object it will not create a duplicate of the same object how will I be able to have multiple same objects in an array?
Please note that you cannot add duplicate elements in an array using arrayUnion. According to the official documentation:
arrayUnion() adds elements to an array but only elements not already present.
So if you need to have duplicate elements, then the single option that you is to read the document, add the duplicate element in the array, and then write the document back to Firestore.
I Have an array of String which I want to save in Mongodb in Node/express, it is saving Empty array in Mongodb
const multiImagesSchema = mongoose.Schema({
names:Array
})
import ImgArray from '../../Model/multiImages.js'
let imgNames = req.files.map(imgName=>{
return imgName.originalname
})
// console,log(imgNames)
//result in console: ['Apple,png', 'Grapes.png','Ornage.png','Banana.png']
const imageArray = new ImgArray(imgNames)
await imageArray.save()
You have to pass the object with properties defined in schema Model to the creation function (in your case the object with names property). You are passing the imgNames array. Change you code like this:
await ImgArray.create({ names: imgNames });
your model need to have a field that accepts array like this:
const ImgArraySchema = mongoose.Schema({
names: [{
type: String,
required: true
}]
})
then to save an array, do it like this:
const imageArray = new ImgArray({names: imgNames})
const imgarray = await imageArray.save()
.catch((err) => (res.status(500).send({err: err.message})))
if (imgarray) {
return res.status(200).send({success: true, imgarray})
}
return res.status(400).send({success: false, error: ""})
This is my ObjectIds array -
obj_ids = [
"5ee71cc94be8d0180c1b63db",
"5ee71c884be8d0180c1b63d9",
"5ee71c494be8d0180c1b63d6",
"5ee71bfd4be8d0180c1b63d4"
]
I am using these objectids to serach whether they exist in the db or not and based on that I want to send the response to server.
This is the code I am trying but I dont know how to populate the array and send it to the server.
var msg = [];
obj_ids.map((ele) => {
Lead.find({ _id: ele._id }, async function (error, docs) {
if (docs.length) {
msg.push(
`Lead already exist for Lead id - ${ele._id} assgined to ${docs[0].salesPerson}`
);
} else {
msg.push(`Lead doesn't exist for Lead id: ${ele._id}`);
const newDuty = new AssignedDuty({
duty: ele._id,
salesPerson: req.body.salesPerson,
});
await newDuty.save();
}
});
});
res.json(msg);
By doing this approach I am getting an empty array. I cannot put res.json(msg) inside the loop. If it is possible by using async-await, please guide me through.
You don't need to make multiple queries to find whether given object ids exist in the database.
Using $in operator, you can make one query that will return all the documents where the _id is equal to one of the object id in the list.
const docs = await Lead.find({
_id: {
$in: [
"5ee71cc94be8d0180c1b63db",
"5ee71c884be8d0180c1b63d9",
"5ee71c494be8d0180c1b63d6",
"5ee71bfd4be8d0180c1b63d4"
]
}
});
After this query, you can check which object id is present in the docs array and which is absent.
For details on $in operator, see $in comparison operator
Your code can be simplified as shown below:
const obj_ids = [
"5ee71cc94be8d0180c1b63db",
"5ee71c884be8d0180c1b63d9",
"5ee71c494be8d0180c1b63d6",
"5ee71bfd4be8d0180c1b63d4"
];
const docs = await Lead.find({
_id: { $in: obj_ids }
});
const msg = [];
obj_ids.forEach(async (id) => {
const doc = docs.find(d => d._id == id);
if (doc) {
msg.push(
`Lead already exist for Lead id - ${doc._id} assgined to ${doc.salesPerson}`
);
}
else {
msg.push(`Lead doesn't exist for Lead id: ${id}`);
const newDuty = new AssignedDuty({
duty: id,
salesPerson: req.body.salesPerson
});
await newDuty.save();
}
});
res.json(msg);
I have a mongoDB database containing Events. Each event is defined by a number of fields, including an array of genres (which are subdocuments consisting of a {genre and subGenre}).
For example: an event could be of {genre: "music", subGenre: "jazz"}, and {genre: "music", subGenre: "blues"}. See event.js - the model. In this case, 2 "genre" sub documents are added to the "genres" array in the Event document in the database.
Back in my node application - see query.ts - I am trying to work out how to run a query that lets the user search for all events that match their genre preferences.
So:
the Event is defined by an array of genres (in the database), and
the user's preferences are defined by an array of genres (in the
application).
I am looking to define a mongoDB query that returns all Events where there is a match of any 1 {genre, subGenre} combination between the 2 arrays.
I looked into $in Query Selector in the mongoDB documentation and suspect it might need to be used... but programmatically, how do I write a query that expands to include all the values in the variable "searchGenres" in query.ts?
Thanks a lot in advance for your thoughts.
event.js: mongoDB Model for 'Events" defined using Mongoose - snippet:
let mongoose = require('mongoose');
let EventSchema = new mongoose.Schema({
genres: [
{
genre: String,
subGenre: String
}
]
)};
module.exports = mongoose.model('Event', EventSchema);
query.ts:
import mongoose = require('mongoose');
let Event = require ('../models/event');
class Genre {
genre: string;
subGenre: string;
constructor (gen: string, sub: string) {
this.genre = gen;
this.subGenre = sub;
}
}
async function runQuery()
{
let searchGenres : Array<Genre> = new Array<Genre>();
// populate searchGenres with some data here... e.g.
const searchGenre1 : Genre = new Genre ('music', 'jazz');
const searchGenre2 : Genre = new Genre ('music', 'rock');
searchGenres.push(searchGenre1);
searchGenres.push(searchGenre2);
// Query logic here:
// Return all events from the database, if the 'genres' array
// in the document matches any element in the searchGenres array
// defined above..
const events = await Event.find ({
'genres': {?help? }
});
}
```
After some self-education today, I have come up with a solution, which I am happy with - to append to end of query.ts:
type GenreQuerySelector = { genres: { $elemMatch: { 'genre': string; 'subGenre': string; }; }; };
let querySelectors : Array< GenreQuerySelector > = new Array< GenreQuerySelector >();
for (let genre of searchGenres) {
const genreQuery : GenreQuerySelector = {
genres: {
$elemMatch: {
'genre': genre.genre,
'subGenre': genre.subGenre
}
}
};
querySelectors.push(genreQuery);
};
const events = await Event.find ({ $or: querySelectors }).exec();
I want to access the content of array of document in my model, but I can't and return undefined.
here is my model(Project.js):
var mongoose = require('moongoose');
var Schema = mongoose.Schema;
var User = require("./Users");
var ProjectSchema = new Schema({
name: String,
description: String,
owner: {
type: mongoose.SchemaTypes.ObjectId,
ref: "User"
},
contributor: [{
type: mongoose.SchemaTypes.ObjectId,
ref: "User"
}]
});
module.exports = mongoose.model('Project', ProjectSchema);
and my Api:
var Project = require('./Project')
await Project.find({owner: userId, name: name})
.then(project => {
console.log(project);
console.log(project.contributor);
}).catch(err => {
res.status(500).send({
message: err.message
});
});
when i try console.log(project); return expected output but in console.log(project.contributor); return undefined
I've also searched the web but couldn't find anything right and clear solution
I appreciate any help :)
As you are expecting to find only one project, change find by findOne method. Other case you are searching for several projects and you are going to receive an array instead of an object.
Your output from Project.find() (See) will be an array of objects from the database.
If you will only have 1 object as a result then you can use project[0].contributor because project is an array with 1 object inside it, which is on the index 0.
If the result might have many objects in the array then you should iterate through the result to get each of the data individually.
project.forEach(p => console.log(p.contributor))