Query by position in mongodb collection - mongodb

I need to fetch the document in a mongodb collection using its position. I know the position of the document inside the collection exactly but could not figure out a way to pull those documents from collection. Is there any way to achieve this?
db.daily.find({'_id': {'$in': 0,5,8}})
This is what i tried but _id is not inserted as 1,2,3... but it has some random num Eg:57d8fd62f2a9d913ba0d006d. Thanks in advance.

You can use skip and limit to query based on the position in the natural order
db.collection.find().skip(10).limit(1) // get 10th document in natural order
As the natural order link points out, the document order need not match the order that documents are inserted (with an exception for capped collections). If you use the default ObjectId as the _id field for your documents you can sort by _id to order based on insertion in the collection (up to the resolution of the timestamp in the ObjectId)
db.collection.find().sort([("_id",1)]).skip(10).limit(1) // get 10th document in inserted order
You may also consider using your own _id or adding a field to be able to sort on in order to query based on the position you define.

Related

store documents in descending order(mongodb-insert)

I am trying to add and retrieve documents from collection.I went through mongodb manual and didn't find ways to add documents in descending order by date. Is it possible to add documents to collection in descending order by date while inserting the document as i don't want to query and return the top 50 documents.
TIA.
MongoDB does not guarantee the retrieval order of documents. Even if you insert them in descending order, there is no guarantee the records will be returned in this order. As suggested by BatScream you could add an descending index on your date field and the order your result when querying the data.

updating and quering rating in mongodb document

I have mongodb collection users.
Each user have field called rating which is between 1 and 5. It means that when user votes on another user he 'gives' him his vote which is a number between 1 and 5. I have a problem with storing this data in mongo document beacause I have to query user collection by rating field and I have to update it atomicly...
If I store both rating and number of votes when I can update votes_number with $inc operator but I cant atomicly set rating = ((rating*votes) + vote_val)/(votes+1)
I could just keep sum of votes and votes number in document and update both using $inc but then I cant query like WHERE votes_sum/votes_num > 3...
Is there any solution to this problem?
What you can do is use option two from above and then combine it with a cached result field. You can set up the data flow so the result field remains consistent with the rest of the document by using the filter predicate on your update.
Step one is to add a new field to your schema which will be your cached rating field. This will allow you to perform your range query without having to do the dynamic division. The problem you'll run into there is that you can't atomically increment the votes_sum & votes_num fields AND in the same atomic operation set the cached rating fields. So here's what you do.
1) Atomically increment the votes_sum and votes_num fields
2) Grab the _id, votes_sum & votes_num for the updated document
3) Update the rating but, as part of the filter predicate, include the _id, expected votes_sum and expected votes_num fields.
db.collection.update({_id: $id, votes_sum: $votes_sum, votes_num: $votes_num}, {$set: {rating: $votes_sum / $votes_num}});
This will ensure that nothing has changed since you updated the doc. If someone else comes along and updates those fields in between you updating them and generating the rating then the doc will not be returned in the find part of the update statement and thus it will not be updated with stale data
This pattern takes advantage of the fact that writes are atomic at the document level in MongoDB so you don't have to worry about the consistency of data within a document. The nice thing is that the rating will be set correctly because every operation to update the votes_sum and votes_num fields is followed by an update to rating.
See here for some sample code: http://docs.mongodb.org/manual/tutorial/isolate-sequence-of-operations/

Mongodb store and select order

Basic question. Does mongodb find command will always return documents in the order they where added to collection? If no how is it possible to implement selection docs in the right order?
Sort? But what if docs where added simultaneously and say created date is the same, but there was an order still.
Well, yes and ... not exactly.
Documents are default sorted by natural order. Which is initially the order the documents are stored on disk, which is indeed the order in which the documents had been added to a collection.
This order however, is not deterministic, as document may be moved on disk once these documents grow after update operations, and can't be fit into current space anymore. This way the initial (insert) order may change.
The way to guarantee insert order sort is sort by {_id : 1} as long as the _id is of type ObjectId. This will return your documents sorted in ascending order.
Write operations do not take place simultaneously. Write locks are imposed in database level (V 2.4 and on). The first four bytes of _id is insert timestamp, and 3 last digits is a random counter used to distinguish (and sort) between ObjectId instances with same timestamp.
_id field is indexed by default

Mongodb - geospacial _id?

I currently have a collection of small documents. Each document has an indexed geospacial field and *the default _id is never used in any query*. There will never be more than one document related to a particular geo location. I think it makes sense to override the default _id, and use the geospacial data for this somehow.
Question is, how do you use geospacial data as the unique id? Is it a case of creating a flat string from the geo field? E.g. 'x123456y123456'?
The _id field is the unique identifier for each document and thus is a needed field. The _id field is generated on document creation automatically if one is not provided. If you can provide this geospaital value when creating the document you should be able to use the string as you suggested, you cannot use an array as the _id value. However please be aware that once a document is created the _id becomes unchangeable. This means that using the _id field as a meaningful index of geospatial data may not be of much value.
Have a look here for more info on the _id field and here for some information about creating geospatial indexes in Mongo

Does newly inserted document in MongoDB surely has "bigger" _id than older document?

What's the algorithm for MongoDB to calculate the "_id" field. It looks it is incremental.
I'm wondering if it is safe to sort by "_id" field as sort by time the document inserted.
The way ids are generated is described here. Turns out leading bytes are given to the timestamp, so probably the order of ids corresponds to the order of insertion (if we don't consider deviations in time between different machines).
If you need to sort by order of insertion then you need to add your own field for timestamp or incremental counter. In a sharded set-up sorting by _id might not work.