mongoose post without duplications - mongodb

I am trying to look at a post/create that does not allow multiple instances in the database(so no duplicates). I looked at the updateOne with an {upsert:true} and this won't work for me because that only works if you have a specific set of data.
example data:
cat:{
name: "jim",
age: 8
}
example model :
cat:{
name: String
}
the code I had :
object.updateOne(req.body,req.body,{upsert:true},function(err,object){
if(err) console.log(err);
res.json(object);
})
}else{
res.json('error: type: '+ req.params.type + 'not found !');
}
but this only works if I add 'age' to my model. due to the {strict:true} policy on the updateOne. and when I use a post I get multiple instances of the same object.
so hopefully someone can help me. ( and if someone knows a better title for this problem , please comment it below). I didn't know how to describe my problem with 1 sentence.
(keep in mind that in reality I have a dataset of 100+ attributes and only need 60). so simply adding age wouldn't help for my dataset. because then I have 40 unused values in my document.
Edit:
after looking at code posted as an answer below i noticed that i made an error in my own code. this is how the code is supose to be :
object.updateOne({},req.body,{upsert:true},function(err,object){
if(err) console.log(err);
res.json(object);
})
}else{
res.json('error: type: '+ req.params.type + 'not found !');
}

Please try using strict:false in update query. They may help to solve your problem.
var data = { fieldOne: 'Test2', fieldTwo: 'Test3' };
var opts = {
upsert: true,
runValidators: false,
strict: false
};
Model.update({}, data, opts)
.then((success) => {
//success
}).catch(() => {
//error
})

Related

How to delete items by _id using mongodb

I have a problem trying to delete data by providing an array of id's (got error).
I guess it has something to do with ObjectId. Could you help me fix it?
User.deleteMany({
_id: { $in: ['638207a8b9ebc3ea8f276684',
'63823ffe310abc61b4ee11a0',
'63822a71319517d196af6d59' }
})
.then(() => res.status(200).json({ success }))
.catch(error => console.error('Error deleting users'))
I tried to map this array to prepend every item of it with ObjectId but got ObjectId is not found.
Try this..
let userIds = ['638207a8b9ebc3ea8f276684',
'63823ffe310abc61b4ee11a0',
'63822a71319517d196af6d59']
let userObjectIds = userIds.map(e=>Types.ObjectId(e))
User.deleteMany({
_id: { $in: userObjectIds }
})
.then(() => res.status(200).json({ success }))
.catch(error => console.error('Error deleting users'))
If the code you pasted above is the exact code you are running, the problem is likely your input ids array syntax. It seems as though you are missing a close square bracket (]). Try this instead:
const userIds = ['638207a8b9ebc3ea8f276684', '63823ffe310abc61b4ee11a0', '63822a71319517d196af6d59']
User.deleteMany({
_id: { $in: userIds }
})
.then(() => res.status(200).json({ success }))
.catch(error => console.error(`Error deleting users: ${error}`))
If that doesn't work, you may need to follow Alex's advice by mapping them to ObjectId types. As a side note, it's always good practice to save your input into a variable rather than hard code it. It's also helpful for debugging to log the contents of the error from your catch callback
console.error(`this is my error: ${error}`)
Hope that helps you out, happy coding :)

How to find all the matches in a nested array with the _id with mongoose

This question may be easy for some of you but I can't get how this query works.
In the attached picture: https://i.stack.imgur.com/KzK0O.png
Number 1 is the endpoint with the query I can't get it to work.
Number 2 is the endpoint where you can see how I am storing the object match in the database.
Number 3 is the data structure in the frontend.
Number 4 is the Match mongoose model.
I am trying to get all the matches that have the _id I am sending by param in any of its members array.
I am trying it with $in, but I am not sure how this nested object array property query works.
I am very new at web development and this is quite difficult to me, any help would be highly appreciated, even some documentation for dummies, since I can't understand the one in the official site.
Thanks in advance
router.get("/profile/:_id", (req, res) => {
const idFromParam = req.params._id;
console.log("params", req.params._id);
Match.find({ match: [ { teams: [{ members: $in: [_id: idFromParam ] } ] ] }}).populate("users")
.then((response) => {
res.json(response);
console.log("response", response);
}) })
.catch((err) =>
res.status(500).json({ code: 500, message: "Error fetching", err })
);
});

mongoose query return empty array if filter has a field name that is camel cased

The following issue was with some code written in express/nodejs.
I experienced something I could not find any material in regards,
I encountered an issue whereas making a find query with mongoose returned an empty array.
After tinkering I discovered it was due to the key used (customerRef) being camel cased
I tried to tweak other fields from and to camelcase and got the same issue.
see example here:
const lastCart = await Cart.findOne({ customerRef: customer._id }, function(err, docs) {
if (err) {
console.log('TCL: err', err);
}
console.log('TCL: docs', docs); //result = []
});
then went and tweaked my database objects from:
{
....
"customerRef" : "5dfcd194ca19972b888d66c2",
....
}
to:
{
....
"customerref" : "5dfcd194ca19972b888d66c2",
....
}
then the query worked as expected:(customerRef >>> customerref)
const lastCart = await Cart.findOne({ customerref: customer._id }, function(err, docs) {
if (err) {
console.log('TCL: err', err);
}
console.log('TCL: docs', docs); //result is now ok = [...]
});
Now to top this off here's another bit of info:
I use studio 3T for mMongoDB and over there I do not have this issue when making queries.
I would appreciate any and all explanation on this behavior aswell as alternatives if possible.
See my full repo here:
(My skills are novice at best so I apologize in advanced and welcome any feedback)
https://github.com/Darkmift/MEAN-SuperMarket/blob/master/backend/app/controllers/userController.js#L121
So after some time I have concluded the issue was with my use of the mongo shell program (Studio 3t)
at the time I was not aware how to properly insert an ObjectId.
When using the built in query one must add:
{
...
"customerRef" : ObjectId(RefId)
...
}
and NOT:
{
...
"customerRef" : "RefId"
...
}

WaterlineJs find() with no criteria and fields/select provided does not work

I am trying to fetch all the records but with selected fields, I have tried the following ways but none works:
Post.find(
{
where: {},
select: ['title']
}
);
Post.find(
{},
{
fields: {
title: 1
}
}
);
As this answer points out, the fields param "WILL work as long as you pass other params with it such as limit or order."
Alternatively, if you want this throughout your application, you could define a custom toJSON function for your model, under attributes. If not, you could still define it under some other (e.g. filter) and use map to return the custom objects instead of the default model. Remember to take care of the control flow while using map though. Use async/promises/raw logic to avoid returning before all objects are processed.
The issue has been resolved in sails-mongo latest version:
https://github.com/balderdashy/waterline/issues/1098
Thanks
I've played with trying to get above answer to use limit or order to kick in the projection to no avail.
I did see this in the docs located here:
http://sailsjs.org/documentation/reference/waterline-orm/models/native
With an out of the box solution for exactly what you're doing (pasted here for ease of use).
Pet.native(function(err, collection) {
if (err) return res.serverError(err);
collection.find({}, {
name: true
}).toArray(function (err, results) {
if (err) return res.serverError(err);
return res.ok(results);
});
});
Swap out the response base things and change Pet to Post and, this ought to work in the sails console:
Post.native(function(err, collection) {
if (err) throw new Error(err);
collection.find({}, {
title: true
}).toArray(function (err, results) {
if (err) throw new Error(err);
console.log(results);
});
});
You'll still get the _id field, and if you don't want that then hit the Mongo docs on not getting those hint(title: true, _id: false)hint
Hope this helps!

Mongoose findByIdAndUpdate not working

I have a fairly straight forward method below to update a document based on its ObjectId. It does not return an error but it fails to make the required updates to the document. I think it is failing because, according to my research, findByIdAndUpdate() takes only plain Javascript whereas job._id is an ObjectId from the document that I want to update. Can someone tell me how to make this work correctly?
function handleEncoderResponse(xmlResponse, job) {
var r = et.parse(xmlResponse);
var mediaID = r.findtext('./MediaID');
var message = r.findtext('./message');
EncodingJob = mongoose.model('EncodingJob');
EncodingJob.findByIdAndUpdate( job._id, {
"MediaID": mediaID,
"Status": message
}, function(err, result) {
if (err) console.log(err);
console.log(result);
});
}
Edit: Per this question Mongoose update document Fail with findByIdAndUpdate
I also tried the following code to no avail.
job.MediaID = mediaID;
job.Status = message;
job.save(function(err, res) {
if(err) console.log(err);
});
This approach yields the issue. It does not update the document and it does not return an error.
As it turns out, my mistake was forgetting to define MediaID and Status in the Schema as follows:
var encodingJobSchema = new mongoose.Schema({
...
MediaID: String,
Status: String
});