Trouble updating last document from a query - mongodb

Hello I'm new to Mongodb, I am currently trying to update the last document in a query result but having trouble doing so.
I know how to get the last document using
db.collection.find().sort({$natural:-1}).limit(1)
but how do I update this? I tried doing:
db.collection.update(db.collection.find().sort({$natural:-1}).limit(1))
But that didn't work. And I don't think:
db.collection.update(query,update,option).sort({$natural:-1}).limit(1))
would do what i want. I checked the official documentation but couldn't find anything on querying only for the last document.

You can use findAndModify to perform an update that requires sorting to identify the document to update:
db.test.findAndModify({
query: {},
sort: {$natural: -1},
update: {$set: {foo: 'bar'}}
})

You can also do it this way:
var id = db.collection.find().sort({$natural:-1}).limit(1)[0]['_id'];
db.collection.update({_id: id},{...})

Related

MongoDB - get documents between dates using ObjectID

As the title said, I want to get documents between 2 dates using the ObjectID. In mongoose I use _id: { $gte: ObjectID.createFromTime(new Date("2019-01-01")) } but I can't figure it out how to construct this query on mongo shell. There is a post on StackOverflow which lists different queries on mongo shell and mongoose but I can't seem to find that post. Does anyone know how to do the same query on mongo shell? Thanks.
UPDATED
Since I have already found the solution, does anyone know why the method names are different in mongo shell and mongoose? This really causes confusion sometimes.
Figured it out, it's _id: { $gte: new ObjectId.fromDate(new Date("2019-01-01")) } on mongo shell

Meteor React - Why is findOne on a single document not found in miniMongo when it does exist?

This is such a weird problem. I think it has to do with how I am querying the document. It seems like the Meteor API has changed to query documents but the docs on the website are the same.
Here is a document in the database:
meteor:PRIMARY> db.studies.findOne()
{ "_id" : ObjectId("56c12e6537014a66b16771e7"), "name" : "Study 1" }
I have subscribed to get all documents and here is what I am trying in the console to get the documents.
var study = Studies.findOne() // This works.
It returns:
_id: MongoID.ObjectID
_str: "56c12e6537014a66b16771e7"
name: 'Study 1'
I just started a new Meteor project with React. I see that my collection is returning _id: MongoId.ObjectId
This is different, I have been using Meteor for awhile with Blaze and I can't remember it returning MongoID.ObjectID instead of just the string
But now if I try and find just that one document, it does not work.
var study = Studies.findOne("56c12e6537014a66b16771e7");
or
var study = Studies.findOne({_id: "56c12e6537014a66b16771e7"});
I am positive I am queuing for the right _id field. I have double checked the ID. Why does trying to find this one document not work?
Please let me know how I can query for a document. Has something changed with Meteor? The documentation still says you can search by id string.
You need to explicitly cast object id string to an ObjectID
var study = Studies.findOne({_id: new Meteor.Collection.ObjectID("56c12e6537014a66b16771e7")});
#Jaco has the correct answer, but I wanted to answer here to clarify what the higher level issue was.
The reason why my find query was not following syntax in Meteor docs is because I inserted the document into MongoDB directly, instead of through the Meteor API.
If you insert the document directly into MongoDB, you have to query the document using the syntax #Jaco mentioned in his answer.
Similar question: Meteor - Find a document from collection via Mongo ObjectId
So instead of changing my query code, I just deleted the document I inserted directly into MongoDB, and inserted a documented using the console in the browser.
Now I can query the document like normal.
So the root of the issue is that if you insert the document directly into MongoDB, you don't get the same type of document as you would if you insert the document using the Meteor API.

Group / MapReduce in moongoose 3.6.15

I have model Record which looks like this:
{
_id: '52278952a4bb5a7415000002',
owner_id: '52278952a4bb5a7415000001',
state: 'some_string'
}
I want to GROUP records collection by owner_id where Record.state = 'some_string' and count them for each owner. In other words I want to count all records with state = 'some_string' for each owner (specified in record as owner_id). How I can accomplish this? I searched in google for mongoose group and mongoose map/reduce but couldnt find anything that I would understand - and map reduce as I know puts results to new collection and I dont want to do this. I cant find any information in mongoose docs. Other examples contains some strange keywords in query like $project etc. Can anyone provide me good working example to this problem? It should be simple to do this I guess... I found out that there is method Model.agregate(...) method but cant find how to use it.
I use mongoose 3.6.15.
To do this with aggregate and Mongoose:
Record.aggregate([
// Filter the docs to just those you want to include
{$match: {state: 'some_string'}},
// Group by owner_id and count them per owner
{$group: {_id: '$owner_id', count: {$sum: 1}}}
], function (err, results) { ... });
Docs on aggregate can be found here. It can be intimidating at first, but spend an hour or so reading over the docs and understanding the examples and you'll get the hang of it fairly quickly.

Updating multiple documents in mongodb using _id field

I have sample products table and would like to update multiple documents using _id field. Every time, I try this it only updates the first doc in the $in clause I mentioned , not updating all.
db.products.update({_id:{$in:[ObjectId("507d95d5719dbef170f15bff"),
ObjectId("507d95d5719dbef170f15c01"), ObjectId("507d95d5719dbef170f15c00")]}},
{$set:{'monthly_price':7865}}, {multi:true})
You can first try running find on the products table to make sure that all the object ids actually exist.
You can also try explain command
give this a try:
db.<collection>.update( { query }, {$set: {monthly_price:7865}}, false, true)
I think the object id's which you have given doesn't exist in the collection.
I tried using the following query and it worked for me.
db.test.update({_id:{$in:[ObjectId("57b33483e5b9ce24f4910855"),
ObjectId("57b33483e5b9ce24f4910856"),
ObjectId("57b33489e5b9ce24f4910857"),
ObjectId("57b33491e5b9ce24f4910858")
]
}
},
{$set{'isCurrentStatus':true}},
{multi:true}
)

Mongo remove last documents

I would like to know how to delete, for example, the last 100 documents inserted in my collection.
How is it possible from the shell?
You should be able to use the _id to sort on last inserted, as outlined in the answer here:
db.coll.find().sort({_id:-1}).limit(100);
It looks like using limit on the standard mongo remove operation isn't supported though, so you might use something like this to delete the 100 documents:
for(i=0;i<100;i++) {
db.coll.findAndModify({query :{}, sort: {"_id" : -1}, remove:true})
}
See the docs for more on findAndModify.