Update database entry using mongoose - javascript

Hello i am using mongoose.
I have built this query that finds my desired project :
const projects = await ClientManagers.findOne({'project.contactPerson.work_email' : 'testing#email.com'} , { 'project.$.companyName': 1 });
this returns an object from my database like this :
{
'projectName' : 'x',
'companyName' : 'x bv'
}
How can i update the company name to be 'Y bv' instead of 'x bv'.

Assuming this is your document structure,
{
"_id" : ObjectId("5f2ae5a4b1549ac0460920dd"),
"projectName" : "A",
"project" : [
{
"companyName" : "T1",
"contactPerson" : {
"work_email" : "t1#gmail.com"
}
},
{
"companyName" : "T2",
"contactPerson" : {
"work_email" : "t2#gmail.com"
}
}
]
}
Single Update updateOne()
If you know email will be unique and want to update single document then use updateOne().
first is query part to find condition, email t1#gmail.com
second is set/update part, here $ is for array because project is an array, update companyName to T1 Company
await ClientManagers.updateOne(
{ 'project.contactPerson.work_email': 't1#gmail.com' },
{
$set: { "project.$.companyName": "T1 Companmy" }
}
)
Multiple Update updateMany()
If email is not unique and want to update everywhere then use updateMany(), it will update every matching documents.
await ClientManagers.updateMany(
{ 'project.contactPerson.work_email': 't1#gmail.com' },
{
$set: { "project.$.companyName": "T1 Company" }
}
)
Not suggesting update() method to use, because its deprecated in mongoose and will give Deprecation Warnings
, this function is replaced with updateOne(), updateMany() and replaceOne() methods.

Good start. Mongo has better documentation with examples. I suggest you to refer that also.
use update
db.collection.update({companyName:'x bv'}, {"$set":{"companyName":y}})
Mongo is case sensitive. So name should match exactly.
update updates one document. To update multiple, use updateMany or multi:true option with update or findOneAndMondify for one update for find and update case.

Related

Using multiple query conditions in MongoDB's UpdateOne statement

I am trying to update a query using 'updateOne' with multiple conditions.
when I put a single Codition it works fine.
or when I ordered the highly unique identifier first in condition, then it works fine.
but when I change it's order it seems jammed and inserting multiple document with different _id.
follwoing is my Javascript code code.
const posts = await loadPostsCollection();
await posts.updateOne(
{
"timestamp" : jsoned_body.timestamp ,
"transactionID" : jsoned_body.transactionID ,
"deviceSN" : jsoned_body.deviceSN ,
},
{
$set:
{
"transactionID": jsoned_body.transactionID,
"deviceName": jsoned_body.deviceName,
"deviceSN": jsoned_body.deviceSN,
"userID": jsoned_body.userID
}
},
{ upsert: true }
)
async function loadPostsCollection() {
const client = await
mongodb.MongoClient.connect(`mongodb://${config.DB_IPAddr}:${config.DB_PortNo}/tms`, {
});
return client.db('tms').collection('transactionLogs');
}
what am I missing?

MongoDB How to filter db.adminCommand output

does anybody know how to filter mongodb db.adminCommand output? Because if I run this command db.adminCommand({ "currentOp": true, "op" : "query", "planSummary": "COLLSCAN" }) I get a huge JSON output but I'm only interested in some fields ( like secs_running, op, command, $db)
Many thanks!
You can add the filters straight to the command object like the following:
var commandObj = {
"currentOp" : 1,
"waitingForLock" : true,
"$or" : [
{
"op" : {
"$in" : [
"insert",
"update",
"remove"
]
}
},
{
"command.findandmodify" : {
"$exists" : true
}
}
]
};
db.adminCommand(commandObj);
You can see some filter examples on the MongoDB docs: https://docs.mongodb.com/manual/reference/method/db.currentOp/#examples
Just re-read your question and I think you might of meant just projecting fields back from the database that you care about? if that's the case you can just execute a map on top of the current results so you only see what you care about?
db.adminCommand(commandObj).inprog.map(x => x.opid};

Firebase orderByValue().equalTo() is not a function (Node JS)

My database has the following structure:
"groupA" : {
"applications" : {
"applicationID_132" : {
"status" : "accepted"
},
"applicationID_423" : {
"status" : "declined"
},
"applicationID_562" : {
"status" : "accepted"
}
}
}
I am trying to retrieve the snapshot of applications with "accepted" status (to be able to skip fetching all applications) by:
return admin.database().ref('groupA').child('applications').orderByValue('status').equalTo('accepted')
.once('value')
.then(acceptedApplicationsSnapshot => {
Doesn't seem to work, tried orderBy and orderByValue as well. What might be missing or what is the better way to handle this case?
Thank you for any help!
Try using child.orderByChild().value()
In your case:
return admin.database().ref('groupA').child('applications').orderByChild('status').equalTo('accepted')
.once('value')
.then(acceptedApplicationsSnapshot => {
You could use orderByValue() as well, but first you would need to get the Reference which you want to order - function does not accept parameter.
How to use orderByValue()?
.child(..) returns a Reference in your case that is applications if you want to use orderByValue than you would need to get reference to 'status' before doing that, eg:
admin.database().ref('groupA').child('applications').child('status').orderByValue() and then you would apply one of the data filtering methods eg.
.equalTo('accepted')...

Update method returns weird data, not updated data

I have a problem with update method which returns this object when I run my endpoint
{ n: 1, nModified: 1, ok: 1 }
This is the code which I tried, and I tried with { new: true } but that doesnt help, i want to get updated data back.
router.put('/:username/experience/edit/:id', function(req, res) {
const { title, company, location, from, to, workingNow, description } = req.body;
User
.update({'experience._id': req.params.id},
{'$set': {
'experience.$.title': title,
'experience.$.company': company,
'experience.$.location': location,
'experience.$.from': from,
'experience.$.to': to,
'experience.$.workingNow': workingNow,
'experience.$.description': description,
}},
function(err, model) {
console.log(model);
if(err){
return res.send(err);
}
return res.json(model);
});
})
If you are on MongoDB 3.0 or newer, you need to use the .findOneAndUpdate() and use projection option to specify the subset of fields to return. You also need to set returnNewDocument to true. Of course you need to use the $elemMatch projection operator here because you cannot use a positional projection and return the new document.
As someone pointed out:
You should be using .findOneAndUpdate() because .findAndModify() is highlighed as deprecated in every official language driver. The other thing is that the syntax and options are pretty consistent across drivers for .findOneAndUpdate(). With .findAndModify(), most drivers don't use the same single object with "query/update/fields" keys. So it's a bit less confusing when someone applies to another language to be consistent. Standardized API changes for .findOneAndUpdate() actually correspond to server release 3.x rather than 3.2.x. The full distinction being that the shell methods actually lagged behind the other drivers ( for once ! ) in implementing the method. So most drivers actually had a major release bump corresponding with the 3.x release with such changes.
db.collection.findOneAndUpdate(
{
"_id": ObjectId("56d6a7292c06e85687f44541"),
"rankings._id" : ObjectId("46d6a7292c06e85687f55543")
},
{ $inc : { "rankings.$.score" : 1 } },
{
"projection": {
"rankings": {
"$elemMatch": { "_id" : ObjectId("46d6a7292c06e85687f55543") }
}
},
"returnNewDocument": true
}
)
From MongoDB 3.0 onwards, you need to use findAndModify and the fields options also you need to set new to true in other to return the new value.
db.collection.findAndModify({
query: {
"_id": ObjectId("56d6a7292c06e85687f44541"),
"rankings._id" : ObjectId("46d6a7292c06e85687f55543")
},
update: { $inc : { "rankings.$.score" : 1 } },
new: true,
fields: {
"rankings": {
"$elemMatch": { "_id" : ObjectId("46d6a7292c06e85687f55543") }
}
}
})
Both queries yield:
{
"_id" : ObjectId("56d6a7292c06e85687f44541"),
"rankings" : [
{
"_id" : ObjectId("46d6a7292c06e85687f55543"),
"name" : "Ranking 2",
"score" : 11
}
]
}

Sequelize "WHERE" Clause in subqueries

I'am trying to build my query using sequelize, in the where clause I need to give the conditional value from my front-end so i did it like this :
getResults(req) {
return parm
.findAll({
attributes: [
sequelize.literal('DISTINCT "id"')
],
where : {
name: req.query.parm.replace(/"/g, '').split(',')
} ,
raw: true
});
}
and it's working!
but now I need to write a subquery including where clause:
something like this :
SELECT tab1.name FROM
(SELECT name FROM "MYTABLE"
WHERE id = (value from the front-end) AND name IN (values from front-end)
) as tab1
Here is what i have tried :
getTest(req) {
if (req.query.parm != null) {
return parm .sequelize.query('SELECT id FROM "table_base" where id = $mid ); ',
{ type: sequelize.QueryTypes.SELECT ,
bind: { mid: [req.query.parm.replace(/"/g, '').split(',')] }} );
}
},
i tried to use raw query and i tested the binding parameters but i get this error when i execute this testing query :
Executing (default): SELECT id FROM "table_base" where id = $1 );
The answer to your question is YES it is indeed possible! SQL can pretty much do anything even if you are using sequelize. If you write the subquery and it doesn't work just post it back here so people can take a look and debug. Thanks

Categories

Resources