How to update if exists otherwise insert new document? - mongodb

How to update if exists otherwise insert new document in javascript/node.js?
I am getting as parameter to function dictionary,if dictionary contains _id should update, otherwise insert on remote server (I have connection with remote server through mongoose and I have Person schema which I want to insert/update).

In Mongoose, you'd use Person.update per the documentation. In order to create a document if it doesn't already exist, you need to pass { upsert : true } in the options hash as it defaults to false.
i.e.
Person.update( { name : 'Ted' }, { name : 'Ted', age : 50 }, { upsert : true }, callback );

collection.update with upsert:true. See also here.

[db.collection.replaceOne(filter, replacement, options)] with upsert:true
E.g. from here:
try { db.restaurant.replaceOne(
{ "name" : "Pizza Rat's Pizzaria" },
{ "_id": 4, "name" : "Pizza Rat's Pizzaria", "Borough" : "Manhattan", "violations" : 8 },
{ upsert: true }
);
}
catch (e){ print(e); }

For python:
import pymongo
client = pymongo.MongoClient("mongodb_address")
db = client.db_name
collection = db[collection_name]
# update 'data' if 'name' exists otherwise insert new document
collection.find_one_and_update({"name": some_name},
{"$set": {"data": some_data}},
upsert=True)

Related

Mongodb: update an object inside an array

I have the current mongo collection and need to find and specific id inside an array and update its value.
{
"_id" : ObjectId("111fe6813abdeb1505f5111"),
"objectIdUser" : ObjectId("111fe6813abdeb1505f5111"),
"objectIdClasses" : [
{
"objectIdClass" : ObjectId("111fe6813abdeb1505f5111")
}
],
}
I tried to use the following query but It never updates.
db.classes.findOneAndUpdate(
{
objectIdUser: ObjectId("111fe6813abdeb1505f5111"),
"objectIdClasses.objectIdClass": ObjectId('111fe6813abdeb1505f5111')
},
{
$set:
{
"objectIdClasses.$.objectIdClass": ObjectId('111fe6813abdeb1505f5111')
}
}
);
The records exists, but I always get a null value and the value is never updated.
Follow the below steps carefully;
db.<collectionName>.updateOne(filter, updateDoc, options);
the filter go defines the document you want to change, just like the find.
the updateDoc defines the new changes
the options instruct the method to create a document if no documents match the filter
Example:
I have a database of shop collection with the following data in a products collection
{ "_id" : 1, "name" : "Pen", "price" : 1.2 }
If I want to change the "price" to of "Pen" to 5.0 then:
db.products.updateOne({name: "Pen"}, {$set: {price: 5.0}}, {upsert: true});
Note: all your changes should be inside the <$set> object

mongodb update field a to be value of field b

I am trying to run a mongo query to update the value of one field with the value of another field. I have the following documents:
{ "_id" : ObjectId("56e0a3a2d59feaa43fba49d5"), "old" : 16, "new" : 17 }
{ "_id" : ObjectId("56e0a3a2d59feaa43fba49d3"), "old" : 11, "new" : 12 }
I would like to make it look like this after update:
{ "_id" : ObjectId("56e0a3a2d59feaa43fba49d5"), "old" : 16, "new" : 16 }
{ "_id" : ObjectId("56e0a3a2d59feaa43fba49d3"), "old" : 11, "new" : 11 }
I've tried the following with no luck
db.runCommand(
{
findAndModify: "testData",
query: { $where: "this.new != this.old" },
update: { old : this.new },
upsert: true
}
)
and
db.testData.update( { $where: "this.new != this.old" }, { $set: { old: this.new } } );
Is this even possible with mongoDb?
I would like to do it in a single query and not iterate through each document.
Any ideas would be greatly appreciated.
Thank you
You can try something like this and probably change _id when you want to update other document:
db.testData.find().forEach(function(elem) {
db.testData.update({
"_id": "56e0a3a2d59feaa43fba49d5"
}, {
$set: {
new: elem.old
}
});
});
You can't do that in MongoDB yet (note to visitors from the future: I'm referring to V3.2).
You have to iterate on the documents.
NB there's a trick in case you don't mind deleting the old field: use rename to rename old to new.
NB2 for some SQLike-fu actions (not this one) the aggregation framework can be useful.

db.collection.find returns multiple records after addToSet

I use addToSet command (to add UpdatedData):
MyTable.update({ "UrlLink": "http://www.someurl.com"}, {
$addToSet: {
UpdatedData: {
TheDate: ThisDate,
NewInfo: ThisInfo
}
}
},
function (err, result) {
next(err,result)
}
);
But then, when I do the query (after UpdatedData is added to my document), I see that it returns two documents. Instead of only one updated document:
db.MyTable.find( {"UrlLink": "http://www.someurl.com"})
{ "_id" : ObjectId("56485922143a886f66c2f8bb"), "UrlLink" : "http://www.someurl.com", "Stuff" : "One", "UpdatedData" : [ { "TheDate" : "11/15/2015", "NewInfo" : "Info1", "_id" : ObjectId("5648599a71efc79c660f76d3") } ] }
{ "_id" : ObjectId("5648599f71efc79c660f76d4"), "UrlLink" : "http://www.someurl.com", "Stuff": "One", "UpdatedData" : [ ] }
So it seems that addToSet creates a new document with new _id, instead of updating the old record (ObjectId("5648599f71efc79c660f76d4")). But I only see the updated document in robomongo (ObjectId("56485922143a886f66c2f8bb")). Any ideas why this happens and how I could prevent that behaviour?
update cannot create a new document, it can only update existing.
This looks like you have created two documents with the same url.. Then when you update it just updates the first one..
To prevent the creation of a document with an already existent url you can create an index and set it to unique
db.collection.createIndex({ UrlLink: 1 }, { unique: true })
This will prevent creation of new documents with the same url, and it will also make queries by UrlLink as fast as possible.

update query in mongo db

I am using mongodb database to save the records.
This is one sample record:
"_id" : ObjectId("53870ed7e4b00e612650c1b8"),
"_class" : "mkcl.os.transformer.PayloadObject",
"formId" : NumberLong(50),
"dataMap" : {
"240" : "ramanbaug",
"241" : "1234",
"242" : "12345678",
"243" : "mr.joshi",
"244" : "8308009391 ",
"245" : "anuja2487#gmail.com",
"280" : "456",
"287" : "1234",
"276" : "29/05/14",
"247" : "No",
"248" : "No",
"249" : "Yes",
"250" : "No",
"251" : "Yes",
"252" : "No"
}
Now I want to update the value of field "241". I read about the Update and FindAndModify Query. But There is no error and records are not getting updated.
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
in the place of enter same query as you use to find that record(s), which you want to update
in the place of enter new values, like doing during insert query
and there are 3 more options:
upsert = Optional. If set to true, creates a new document when no document matches the query criteria. The default value is false, which does not insert a new document when no match is found. So if your doc will not be found you will create a new one
multi = Optional. If set to true, updates multiple documents that meet the query criteria. If set to false, updates one document. The default value is false. For additional information, see Multi Parameter.
writeConcern = Optional. A document expressing the write concern. Omit to use the default write concern.
you can read more about write concern here: http://docs.mongodb.org/manual/core/write-concern/
Single document update example:
db.people.update(
{ name: "Andy" },
{
name: "Andy",
rating: 1,
score: 1
},
{ upsert: true }
)
check out for upsert: true, so it will create new doc if none found by name=Andy
Multi documents update example:
db.books.update(
{ stock: { $lte: 10 } },
{ $set: { reorder: true } },
{ multi: true }
)
Example with your data:
db.people.update(
{ _id: ObjectId("53870ed7e4b00e612650c1b8") },
{
dataMap: {
"241": "321"
}
}
)
that should work.
It's all in official documentation:
http://docs.mongodb.org/manual/reference/method/db.collection.update/
db.payloadObject.update({"dataMap.241":'1234'},{$set :{"dataMap.241":'123456'}});

MongoDB Update for array of object

I am having following document in mongodb
{
"_id" : ObjectId("521aff65e4b06121b688f076"),
"uuid" : "160597270101684",
sessionId" : "160597270101684.1",
"stamps" :
{
"currentVisit" : "1377500985",
"lastVisit" : "1377500985"
},
visits : [
{
"page":"google.com",
"method": "GET"
}
]
}
Requirement:
If uuid and sessionId is not present i will insert the document as above otherwise i have to push only the object to visits array.
Any help will be greatful.
MongoDB supports an upsert option on update that updates the matching document if it exists, and inserts a new document if it doesn't exist. In MongoDB 2.4+ you can use the $setOnInsert operator to further tweak this to set certain fields only if the upsert performs an insert.
db.test.update({
uuid: "160597270101684",
sessionId: "160597270101684.1"
}, {
$setOnInsert: {
stamps: {
currentVisit: "1377500985",
lastVisit: "1377500985"
}
},
$push:{
visits: {
page: "google.com",
method: "GET"
}
}
}, { upsert:true })
So in the above example, the $push to visits will always occur but the $setOnInsert to stamps will only occur if the matching document doesn't already exist.
You can achieve this by following upsert query:
db.session.update({"uuid" : "160597270101684", sessionId : "160597270101684.1"},
{$set:"stamps" :{"currentVisit" : "1377500985","lastVisit" : "1377500985"}},
$push :{visits:{"page":"yahoo.com","method": "POST"}}},
{upsert:true})
You can use $addToSet instead of $push if you want to avoid duplicates