insert element into db only if it doesnt exist - mongodb

Hy i am using mongoose.
I have this query that inserts about 30 elements into my database:
await Code.insertMany(information);
Information looks like:
[
{
discount: 20,
url: '...',
code: "...",
sponsorUrl: "...",
sponsorAccount: "..."
},
]
The url is unique. I want to add again 30 items into the database but it could be that 10 items from 30 are already saved in the database
How can i achieve that? I could loop it but is there an better solution?
I dont want to have duplicated urls

The upsert = true option creates the object if the url does not already exist in a document in the collection.
for (var i of information){
Code.update(
{'url' : i.url },
{$set : i},
{upsert : true, multi : true},
function(err, doc){
if(err) throw err;
console.log(doc);
}
)
}

Related

Mongoose remove _id and __v before sending to the front end

When I get data from mongo via mongoose with...
const allAssets = await assets
.find({ company })
.sort([['createdAt', -1]])
.exec();
res.status(200).json({ assets: allAssets });
I always get _id and __v but I dont want to send these to the front end, is there a way I can easly say I dont want these values or remove them before sending them?
{
"indistructable": true,
"_id": "5e345c2dc84be8995a5b4cf2",
"baseUri": "https://api.website.com/nameco8/",
"company": "jnameco8",
"description": "asset",
"image": "myimage.png",
"name": "jim",
"supply": 100,
"createdAt": "2020-01-31T16:56:13.816Z",
"updatedAt": "2020-01-31T16:56:13.816Z",
"__v": 0
},
I have tried adding
__v: {type: Number, select: false},
_id: { type: mongoose.Schema.Types.ObjectId, select: false },
to my schema but when saving to the schema I then get an error
"document must have an _id before saving"
As far as I believe schemas are for writes to restrict unknown fields from being written to documents which make your documents look similar across your collection, but if you need to remove few fields in read then try projection in .find() :
const allAssets = await assets
.find({ company }, {_id :0, __v:0})
.sort([['createdAt', -1]])
.exec();
res.status(200).json({ assets: allAssets });
Schema.find()
.select("-_id -__v")
.exec()
.then(result =>{
console.log(result);
})
In addition to #whoami - fakeFaceTrueSoul's answer, you can also add multiple <" -fieldName "> to your select statement in find()

How to save / update multiple documents in mongoose

I am reading all documents of a specific schema from Mongoose. Now in my program I am doing some modifications to the results I got from Mongoose over time. Something like this:
var model = mongoose.model("Doc", docSchema);
model.find(function(err, result){
// for each result do some modifications
});
How can I send all the results back to the database to be saved? Currently I am iterating the documents and doing a save() on every document. I think there must be a better way. But currently I only find information on updating documents IN the database without returning them. Or bulk updates which do the SAME to update to each document.
You can use update query with multi:true which update all documents in your db.
please find below reference code,
model.update({ "_id": id }, { $set: { "Key": "Value" } }, { multi: true }, function (err, records) {
if (err || !records) {
return res.json({ status: 500, message: "Unable to update documents." });
} else {
return res.json({ status: 200, message: "success" });
}
});
If you are trying to make the same change to each document in the results, you could do something like this:
model.update({ _id: { $in: results.map(doc=>doc._id) }}, { yourField: 'new value' }, { multi: true })

How to get all matching subdocuments in mongoose?

In my mongodb (using Mongoose), I have story collection which has comments sub collection and I want to query the subdocument by client id, as
Story.find({ 'comments.client': id }, { title: 1, 'comments.$': 1 }, function (err, stories) {
...
})
})
The query works except that it only returns the first matched subdocument, but I want it to return all matching subdocuments. Did I miss an option?
EDIT:
On Blakes Seven's tip, I tried the answers from Retrieve only the queried element in an object array in MongoDB collection, but I couldn't make it work.
First tried this:
Story.find({'comments.client': id}, { title: 1, comments: {$elemMatch: { client: id } } }, function (err, stories) {
})
It also returns the first match only.
Then, I tried the accepted answer there:
Story.aggregate({$match: {'comments.client': id} }, {$unwind: '$comments'}, {$match : {'comments.client': id} }, function (err, stories) {
})
but this returns nothing. What is wrong here?
UPDATE:
My data structure looks like this:
{
"_id" : ObjectId("55e2185288fee5a433ceabf5"),
"title" : "test",
"comments" : [
{
"_id" : ObjectId("55e2184e88fee5a433ceaaf5"),
"client" : ObjectId("55e218446033de4e7db3f2a4"),
"time" : ISODate("2015-08-29T20:16:00.000Z")
}
]
}

How to dynamically $set a subdocument field in mongodb? [duplicate]

This question already has answers here:
Nodejs Mongo insert into subdocument - dynamic fieldname
(2 answers)
Closed 8 years ago.
I've run into a situation where I need to dynamically update the value of a field in a subdocument. The field may or may not already exist. If it doesn't exist, I'd like mongo to create it.
Here's an example document that would be found in my Teams collection, which is used to store members of any given team:
{
_id : ObjectId('JKS78678923SDFD678'),
name : "Bob Lawblaw",
status : "admin",
options : {
one : "One",
two : "Two"
}
}
And here's the query I'm using (I'm using mongojs as my mongo client) to try and update (or create) a value in the options subdocument:
var projectID = 'JKS78678923SDFD678';
var key = 'Three';
var value = 'Three';
Teams.findAndModify({
query: {
projectID:mongojs.ObjectId(projectID)
},
update: {
$set : { options[key] : value }
},
upsert: true,
multi: false,
new: true
},
function(error, result, lastErrorObject){
console.log(result);
});
But I can't get it to 'upsert' the value.
I also found this similar question, but that method didn't work either:
Nodejs Mongo insert into subdocument - dynamic fieldname
Thanks in advance for any help.
Figured this out.
Essentially, you need to construct a 'placeholder' object of the sub-document you're trying to update before running the query, like so:
var projectID = 'JKS78678923SDFD678';
var key = 'Three';
var value = 'Three';
var placeholder = {};
placeholder['options.' + key] = value;
Teams.findAndModify({
query: {
projectID:mongojs.ObjectId(projectID)
},
update: {
$set : placeholder
},
upsert: true,
multi: false,
new: true
},
function(error, result, lastErrorObject){
console.log(result);
});
This updates any fields that already exist, and creates the field/value pair if it didn't already exist.

How to get string value inside a Mongodb document?

I have this document stored in mongodb document:
{
"_id":ObjectId("4eb7642ba899edcc31000001")
"hash":"abcd123"
"value":"some_text_here"
}
I am using NodeJS to access the database:
collection.findOne({'hash' : req.param('query') },
function(err, result){
console.log(res);
});
The result of this query is the whole document, however I need to get only the "value" text: "some_text_here"
How can this be done?
You can specify the fields that you are interested in (_id will always be returned, though):
collection.findOne({'hash': req.param('query') },
{fields: ['value'] },
callbackFunction );
You can do it such way:
collection.findOne({'hash' : req.param('query') },
function(err, result){
console.log(result.value);
});