Mongodb how to insert or update all? [duplicate] - mongodb

This question already has answers here:
Spring Data Mongo: upsert with various fields updated
(1 answer)
Spring Data MongoDB and Bulk Update
(3 answers)
Closed 3 years ago.
Spring boot mongo repository support saveAll,but it cause unique index insert error ,so I want use update.
In my case,I want to insert or update 10 documents together.
how to use updateAll?

Though I'm not crystal clear on your question, it sounds like you need to append { multi: true } to your update query. Please see Update Multiple Documents.
Setting the multi option updates all documents found by match.
To update multiple documents, set the multi option to true. For
example, the following operation updates all documents where stock is
less than or equal to 10:
db.books.update(
{ stock: { $lte: 10 } },
{ $set: { reorder: true } },
{ multi: true }
)

you can use updateMany:
db.collections.updateMany({ query }, {"$set":{ update }}

Related

Robo3T delete one element inside a key in a document? [duplicate]

This question already has answers here:
How to remove array element in mongodb?
(6 answers)
Closed 2 years ago.
I have been searching all day to figure out how to do a simple delete for one element inside a document that is inside a collection. I am fairly new to mongo scripts so bear with me.
I am currently using this script to see a certain document:
db.getCollection('roles').deleteOne({"_id": "e9b4afad-cb5c-4588-9560-161867faa5b7"})
This is what the document shows in Robo3T after the it is executed:
{
"_id" : "e9b4afad-cb5c-4588-9560-161867faa5b7",
"appIds" : [
"rpt",
"wc",
"bw"
],
}
I am simply wanting to remove "rpt" from appIds. I have tried this so far and it doesn't work:
db.getCollection('roles').find({"_id": "e9b4afad-cb5c-4588-9560-161867faa5b7"}).remove({"appIds": "rpt"})
Any documentation that'll point me in the right direction?
Thanks!
It is not an easy task but I believe $pull will do the work.
The $pull operator removes from an existing array (in a doc) all instances of a value or values that match a specified condition.
I would try,
db.roles.update(
{ },
{ $pull: { appIds: "rpt"}},
{ multi: true }
)
Let me know if it works...
If you want to update a specific id just add it in the first part {}, -> {_id: *****},
See the great documentation of MongoDB at https://docs.mongodb.com/manual/reference/operator/update/pull/

Do not add document to collection if already exist in MongoDB [duplicate]

This question already has answers here:
MongoDB atomic "findOrCreate": findOne, insert if nonexistent, but do not update
(4 answers)
Closed 3 years ago.
Is there a way to omit adding/updating document if it was found in the collection without doing two requests to Mongo server? It would be perfect if this can be done in bulk, but I would appreciate to hear other options or workarounds.
What I'm looking for is sort of opposite of upsert option:
var bulk = MyCollection.initializeUnorderedBulkOp();
bulk.find({ x: val }).upsertOnlyIfNotFound({ x: newVal });
bulk.execute();
What you are looking for is $setOnInsert.
db.MyCollection.update(
{ x: val },
{
$setOnInsert: { x: "newVal" }
},
{ upsert: true }
)
From the documentation :
If an update operation with upsert: true results in an insert of a
document, then $setOnInsert assigns the specified values to the fields
in the document. If the update operation does not result in an insert,
$setOnInsert does nothing.

MongoDB : Add field in each array elements [duplicate]

This question already has answers here:
How to Update Multiple Array Elements in mongodb
(16 answers)
Closed 5 years ago.
I'm starting with mongoDB and I want to update a nested array in my documents to add some initial value, but I can't find a way to do it with mong.
here is my document :
{
"_id":"cTZDL7WThChSvsvBT",
"name":"abc",
"players":[
{
"playerName":"Name1"
},
{
"playerName":"Name2"
}
]
}
What I want to do :
{
"_id":"cTZDL7WThChSvsvBT",
"name":"abc",
"players":[
{
"playerName":"Name1",
"NewField1":0,
"NewField2":0
},
{
"playerName":"Name2",
"NewField1":0,
"NewField2":0
}
]
}
Does anyone have a solution for this kind of situation?
This adds the new fields to the player array ...
db.collection.update({_id: 'cTZDL7WThChSvsvBT', players: {$exists: true}}, {$set: {'players.$.NewFieldOne': 0, 'players.$.NewFieldTwo': 0}})
... but since Mongo will only update the first element of an array which matches the query you are a bit stuffed. You can, of course, choose which array element to update by using the positional operator (as in my example) or by choosing a specific element (as the previous poster suggested) but until Mongo supports 'array updates' on all elements I think you're left with a solution such as: find the relevant documents and then update each one (i.e. a client side update solution).
I finally found a way by editing directly the document in JS like this :
db.doc.find({_id: myDocId}).forEach(function (channel) {
channel.players.forEach(function (player) {
player.newField1 = 0;
player.newField2 = 0;
});
db.doc.update({_id: myDocId}, channel);
});
considering you want to update an element which is an object also,
how about this?
db.collections.updateOne({_id: "cTZDL7WThChSvsvBT"}, {$set: {"players.0.NewField1": 0, "players.0.NewField2: 0}});

Updating Every Record in Mongo [duplicate]

This question already has answers here:
Update MongoDB field using value of another field
(12 answers)
Closed 6 years ago.
How would I update every record in the "title" collection for mongo, to make a field named LastReturnedName set to Name for every single record?
Thought it would be something like this:
db.title.update(
{ "LastNameReturned" : "" },
{ $set:{ "LastNameReturned" : Name } },
{ multi : true }
);
You can use foreach iteration:
db.title.find({ "LastNameReturned" : "" }).snapshot()
.forEach(function(t) {
db.title.update({_id: t._id}, {$set: {"LastNameReturned" : t.Name}});
});
NOTE: You can use snapshot() only with unsharded collections. Also you can speed up updating if you'll use bulk operation.

mongodb: upserting: only set value if document is being inserted

Considering a simple mongo document structure:
{ _id, firstTime, lastTime }
The client needs to insert a document with a known ID, or update an existing document. The 'lastTime' should always be set to some latest time. For the 'firstTime', if a document is being inserted, then the 'firstTime' should be set to current time. However, if the document is already created, then 'firstTime' remain unchanged. I would like to do it purely with upserts (to avoid look ups).
I've crawled the http://www.mongodb.org/display/DOCS/Updating, but I just don't see how that particular operation can be done.
I don't believe this is something unreasonable, there are $push and $addToSet operations that effectively do that on array fields, just nothing that would do the same on simple fields. It's like there should be something like $setIf operation.
I ran into the exact same problem and there was no simple solution for <2.4 however since 2.4 the $setOnInsert operator let's you do exactly that.
db.collection.update( <query>,
{ $setOnInsert: { "firstTime": <TIMESTAMP> } },
{ upsert: true }
)
See the 2.4 release notes of setOnInsert for more info.
I ran into a very similar problem when attempting to upsert documents based on existing content--maybe this solution will work for you also:
Try removing the _id attribute from your record and only use it in the query portion of your update (you'll have to translate from pymongo speak...)
myid = doc.get('_id')
del doc['_id']
mycollection.update({'_id':myid}, {'$set':doc}, upsert=True)
If you will trigger the following code 2 subsequent times, it will first set both firstVisit and lastVisit on document insert (and will return upsertedId in the response) and on the second it will only update lastVisit (and will return modifiedCount: 1).
Tested with Mongo 4.0.5 though I believe should be working with older versions.
db.collection.updateOne(
{_id: 1},
{
$set: {
lastVisit: Date.now()
},
$setOnInsert: {
firstVisit: Date.now()
}
},
{ upsert: true }
);
There's no way to do this with just one upsert. You'd have to do it as 2 operations - first try to insert the document, if it already exists the insert will fail due to duplicate key violation on the _id index. Then you do an update operation to set the lastTime to now.