Mongodb query forward from username X - mongodb

I have problem whit long Mongo find results. Example how can i start query starting from _id X
to forward Example I know I have document where is 1000 users details I know there is user called Peter in list I can make query Users.find({userName: "Peter"}) and get this on user _id but how I can get all users also after this with out I need return JSON from above "Peter"

With the little amount of information you have given, You need to do this in two steps:
Get the id of the first record that matches the name "peter".
db.test.findOne({"userName":"Peter"},{"_id":1});
Returns one document that satisfies the specified query criteria. If
multiple documents satisfy the query, this method returns the first
document according to the natural order which reflects the order of
documents on the disk. In capped collections, natural order is the
same as insertion order.
Once you have the id of the record with peter, you can retrieve the records with their id > the id of this record.
db.test.find({"_id":{$gte:x}});
Where, x is the id of the first record returned by the first query.

Related

Find documents with a certain field value only when another field value is a given string

I'm using this php package to make queries - https://github.com/jenssegers/laravel-mongodb
The situation is, there are two fields, user_id and post_status among others. I want to retrieve all the documents in that collection, but when post_status field value is draft, that should be retrieved only when user_id is a given string. The idea is, only logged in user finds their drafted posts among other posts.
I'm having hard time finding any solution for this problem. The app is still not in production. If I should store data is some different manner, that is an option as well.
Find documents with a certain field value only when another field value is a given string
The question your are framing is simply convert into a and query, how let's see it
when another field value is a given string
This means that you have some result sets and you need to filter out when user_id match with some string. i.e some result sets and user_id = <id>
Now consider the first part of the sentence Find documents with a certain field value
This means you are filtering the records with some values i.e "status" = "draft" and whatever result will come and want again to filter on the basis of user_id = <id>
So finally you will end-up with below query:
db.collectionName.find({"status":"draft", "user_id": "5c618615903aaa496d129d90"})
Hope this explanation will help you out or you can rephrase your question I will try to modify by ans.

Best way to get the first inserted record in a collection of MongoDB

I need to fetch the first inserted record in a collection in MongoDB for which I am currently using the below query:
db.users.find({}).sort({"created_at":1}).limit(1);
But, this takes up a lot of memory. The collection has about 100K records.
What is the efficient way to do this?
MongoDB _id is unique identifier which is automatically generated upon insertion of document into MongoDB collection
_id field stores ObjectId value and is automatically indexed.
According to MongoDB documentation,
The 12-byte ObjectId value consists of:
4-byte value representing the seconds since the Unix epoch,
3-byte machine identifier,
2-byte process id, and
3-byte counter, starting with a random value.
According to description as mentioned into above question to fetch first inserted record please try executing following mongodb find operation into MongoDB shell.
db.users.find({}).sort({"_id":1}).limit(1);
In above query we have sorted result according to _id field since _id Object ID value consists of unix epoch timestamp
further to this you can add specific filters in query to get first record inserted for that criteria:
like suppose you collection contains data for storing employees from IT, ADMIN, FINANCE department and you want to look for the first document inserted for IT (i.e. first IT employee) then you can execute:
db.users.find({"Dept" : "IT"}).sort({"_id":1}).limit(1);
and similarly to find last employee:
db.users.find({"Dept" : "IT"}).sort({"_id":-1}).limit(1);
Note: for bigger collections/sharded collection it will take considerable time to get the result as it iterates entire _id field for ascending and descending criteria.

Query by position in mongodb collection

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.

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 $in not only one result in case of repeated elements

I need to get the users whose ids are contained in an array. For this i'm using the $in operator, however being this inside an aggregate operation, i'd like to get back a specific user all the time it's id is present in the array, not just one. For example:
The ids array is A=[a,b,c,b] and U(x) is user with id x
with users.find({_id:{$in:A}}) i get these users as result: U(a),U(b),U(c)
instead i'd like to get back the result: U(a),U(b),U(c),U(b)
so get the user back every time it's id appears.
I understand that $in is working as expected but does anyone have an idea on how can i achieve this?
Thanks
This isn't possible using a MongoDB query.
MongoDB's query engine iterates over the documents in a collection (or over an index if there's a useful one) and returns to you any documents that match your query, in the order it finds them. Whether b appears once, twice, or a hundred times in your query makes no difference: the document with _id of b matches the query and is returned once, when MongoDB finds it.
You can do a post-processing step in your programming language to repeat documents as many times as you want.