I want to update the results of find query on certain conditions.now what i was thinking it that will mongodb will search whole collection for find and update or use pointer from the previous find query.I just wanted to optimism my queries that's why i was thinking about it.so is there anyway to achieve this?
update:I also want the documents.
ex-collection.find({conditions}).foreach({some condition based on which update will be called})
now what i want is that update query which will be called from foreach function uses pointer from previous find query rather than searching through the collection again.
my point is when we first use find query we search the collection and a cursor is returned which is a pointer to collection in memory.now that we have that pointer why can't we use that to update the document rather than again searching the collection and then updating it.
If you want to keep your code you can use:
collection.find({conditions}).foreach((doc) => {
if (some_conditions) {
return collection.findOneAndUpdate({_id: doc._id}, {$set: {updated_fields});
}
})
but as mentioned in the comments i'm not sure exactly what conditions need to be met but you probably can just use the update method to save time.
Related
I have a mongoDB database and have restructured how I store my date/times.
However I would like to update any old documents that are not stored in this format.
Using NodeJS how could I use the previous value of a field and update it using its previous value.
I'm looking for something along the lines of:
function modifyDateFormat(oldDate){...}
let filter = {}
let update = {
$set: {date_time: modifyDateFormat(previousValue)}
}
db.collection("collection").updateMany(filter, update)
First find the old document, then update using data from this document. No other way.
In this case, first of all, you need to find all of them. Then you can work on that items and whatever you want.
To dig deeper have a look.
I call the Elements with find() method and after than i want to update all. For example:
db.collection.find().limit(10).update({$set: {'column' : 'value'}});
how can i fix this?
If you want to apply update to every document in collection, use {multi:true} option
db.collection.update({},{$set: {'column' : 'value'}},{multi:true});
For more detail, see collection.update
However, if you want to update selected number of documents, you'll be taking longer route.
db.collection.find().limit(10).forEach(function(o){
o.column = some_value; // replace some_value with real one.
db.collection.update({_id:o._id},o);
});
By default it updates only the first 1 document it found. You need to add multi = true as an option to update() to update all. Unfortunately, update() doesn't have limit option so you can limit it to 10.
You might have to do find() with limit first and then update each document separately like mentioned in this post:
How to limit number of updating documents in mongodb
I am working on a node.js app, and I've been searching for a way around using the Model.save() function because I will want to save many documents at the same time, so it would be a waste of network and processing doing it one by one.
I found a way to bulk insert. However, my model has two properties that makes them unique, an ID and a HASH (I am getting this info from an API, so I believe I need these two informations to make a document unique), so, I wanted that if I get an already existing object it would be updated instead of inserted into the schema.
Is there any way to do that? I was reading something about making concurrent calls to save the objects, using Q, however I still think this would generate an unwanted load on the Mongo server, wouldn't it? Does Mongo or Mongoose have a method to bulk insert or update like it does with insert?
Thanks in advance
I think you are looking for the Bulk.find(<query>).upsert().update(<update>) function.
You can use it this way:
bulk = db.yourCollection.initializeUnorderedBulkOp();
for (<your for statement>) {
bulk.find({ID: <your id>, HASH: <your hash>}).upsert().update({<your update fields>});
}
bulk.execute(<your callback>)
For each document, it will look for a document matching the {ID: <your id>, HASH: {your hash}} criteria. Then:
If it finds one, it will update that document using {<your update fields>}
Otherwise, it will create a new document
As you need, it will not make a connection to the mongo server on each iteration of the for loop. Instead a single call will be made on the bulk.execute() line.
I want to delete all documents where foo equals x. Seems like a pretty basic operation, but I just can't figure it out.
I know how to delete an individual document, but that's not good enough - I may have to delete a few thousand at a time.
How do I bulk delete documents in CouchDB?
I don't know if it's the right way but make a view that exposes the foo field, query the view for the doc._ids of all your documents that you want to delete, and make a bulk update against all your documents. So two (ideally) calls to couch.
http://comments.gmane.org/gmane.comp.db.couchdb.user/11222
Has a similar way to go about it.
Do a bulk update on all the documents you want to delete and update doc._deleted=true following the example in Bulk deletion of documents
It's quite easy with bulk delete: https://wiki.apache.org/couchdb/HTTP_Bulk_Document_API
Just POST to _all_docs a list of JSONs that look like:
{"_id": "0", "_rev": "1-62657917", "_deleted": true}
I also needed something to handle that and, since there was nothing at the time, I decided to make my own implementation.
You can find it here.
Update
Since it was very helpful to me and in order to protect myself from mistakes, I added a backup/restore feature to this tool that can now be found on version 0.2
I tried a somewhat long method to delete documents. I first created a view called map_fun that called the documents i wanted to get deleted. I then iterated through the view and stored the keys of allt he documents and used del db['_id'] to delete them
map_fun = function(doc){
if (doc.doc_type == 'classic'){
emit(doc._id, doc)
}}
deldoclist = []
for row in db.query(map_fun):
deldoclist.append(row.key)
for item in deldoclist:
del db[item]
I have a Tags collection which contains documents of the following structure:
{
word:"movie", //tag word
count:1 //count of times tag word has been used
}
I am given an array of new tags that need to be added/updated in the Tags collection:
["music","movie","book"]
I can update the counts all Tags currently existing in the tags collection by using the following query:
db.Tags.update({word:{$in:["music","movies","books"]}}, {$inc:{count:1}}), true, true);
While this is an effective strategy to update, I am unable to see which tag values were not found in the collection, and setting the upsert flag to true did not create new documents for the unfound tags.
This is where I am stuck, how should I handle the bulk insert of "new" values into the Tags collection?
Is there any other way I could better utilize the update so that it does upsert the new tag values?
(Note: I am using Node.js with mongoose, solutions using mongoose/node-mongo-native would be nice but not necessary)
Thanks ahead
The concept of using upsert and the $in operator simultaneously is incongruous. This simply will not work as there is no way to different between upsert if *any* in and upsert if *none* in.
In this case, MongoDB is doing the version you don't want it to do. But you can't make it change behaviour.
I would suggest simply issuing three consecutive writes by looping through the array of tags. I know that's it's annoying and it has a bad code smell, but that's just how MongoDB works.