collection traversal order with mongoose methods like findOne() or findOneAndRemove() - mongodb

How do mongoose methods like findOne() or findOneAndRemove() traverse a collection ? which object will this kind of methods return ? the oldest entry ? the first object from left to right in the collection ? do these methods sort collections by object id in ascending order during their execution ? or will it return a random object falling under the specified condition ? the Mongoose API Documentation just says "finds one document", it's probably obvious but it is not to me, hence this question ;)
[EDIT]
findOneAndRemove() documentation >>>
https://mongoosejs.com/docs/api.html#model_Model.findOneAndRemove
simply states ("Finds a matching document")
findOne() documentation >>>
https://mongoosejs.com/docs/api.html#model_Model.findOne
(simply states "Finds one document")
How can I be sure which document will be found by these methods if I have, lets say, two books in a books collection that have the same value under a "name" property ?
This question occured to me while running tests using mocha during my learning of MongoDB >>>
https://github.com/yactouat/JSNotions/blob/master/learningMongoDBMongoose/test/delete_test.js

Most driver functions correspond to Mongo DB's methods.
If you Google it a bit, you can find all Mongo shell's functions and their documentation.
For example, according to: findOne documentation on Mongo DB's site:
Returns one document that satisfies the specified query criteria on
the collection or view. 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. If no document satisfies
the query, the method returns null.

Related

Mongo: is it the same to use .find({_id: id}) vs .findOne({_id: id})?

I'm asking this question performance wise - knowing that there is a unique document with id.
MyCollection.find({_id: id}) //this should return only one document - id is unique
vs
MyCollection.findOne({_id: id}) //this is equivalent to .find({_id: id}).limit(1) from what I've read
My first thought is that no matter the filter, the .find has to go through the collection thus the .findOne is faster in the case I just want to retrieve one doc, am I correct? Or maybe since _id is always indexed, maybe there is no difference?
I'm not asking about the output of the functions, this is an optimization/perf question.
In this particular case, there's no performance difference (because of the unique index, yes).
There may be response shape differences. I'm not familiar with mongoose, but in mongodb shell, find() returns a cursor (which is enumerated right away) and findOne() returns the document directly.

How to order the fields of the documents returned by the find query in MongoDB? [duplicate]

I am using PyMongo to insert data (title, description, phone_number ...) into MongoDB. However, when I use mongo client to view the data, it displays the properties in a strange order. Specifically, phone_number property is displayed first, followed by title and then comes description. Is there some way I can force a particular order?
The above question and answer are quite old. Anyhow, if somebody visits this I feel like I should add:
This answer is completely wrong. Actually in Mongo Documents ARE ordered key-value pairs. However when using pymongo it will use python dicts for documents which indeed are not ordered (as of cpython 3.6 python dicts retain order, however this is considered an implementation detail). But this is a limitation of the pymongo driver.
Be aware, that this limitation actually impacts the usability. If you query the db for a subdocument it will only match if the order of the key-values pairs is correct.
Just try the following code yourself:
from pymongo import MongoClient
db = MongoClient().testdb
col = db.testcol
subdoc = {
'field1': 1,
'field2': 2,
'filed3': 3
}
document = {
'subdoc': subdoc
}
col.insert_one(document)
print(col.find({'subdoc': subdoc}).count())
Each time this code gets executed the 'same' document is added to the collection. Thus, each time we run this code snippet the printed value 'should' increase by one. It does not because find only maches subdocuemnts with the correct ordering but python dicts just insert the subdoc in arbitrary order.
see the following answer how to use ordered dict to overcome this: https://stackoverflow.com/a/30787769/4273834
Original answer (2013):
MongoDB documents are BSON objects, unordered dictionaries of key-value pairs. So, you can't rely on or set a specific fields order. The only thing you can operate is which fields to display and which not to, see docs on find's projection argument.
Also see related questions on SO:
MongoDB field order and document position change after update
Can MongoDB and its drivers preserve the ordering of document elements
Ordering fields from find query with projection
Hope that helps.

MongoDB: findOne with $or condition

Such request as db.collection.findOne({$or: [{email: 'email#example.com'},{'linkedIn.id': 'profile.id'}]}); may return an array with two records.
Is it possible to specify to return only the first occurrence so that I always have a model as a response, not an array?
E.g. if there is a record with a specified email, return it and do not return another record, if any, matching profile.id?
Another question is if the order of the params 'email' and 'linkedIn.id' matters.
All this hazel is about LinkedIn strategy, which never returns an email (at least for me) but I have to cater for case when it may return an email. So I construct my query depending on email presence and if it is present, the query is with $or operator. But I would like to avoid checking for whether the response is an object or an array and then perform additional operation on array values to figure out which of the values to use.
According to documentation of mongo DB
findOne()
always returns a single document irrespective of matches it found.
And regarding order of retrieval it will always return the first match except capped collection which maintains order of insertion of documents into collection.
For more detailed description about findOne please refer the documentation as mentioned in following URL
https://docs.mongodb.org/manual/reference/method/db.collection.findOne/
According to the MongoDB docs for db.collection.findOne():
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. If no document satisfies the query, the method returns null.
You can't recieve multiple records from db.collection.findOne(). Are you sure you're not using db.collection.find()?

meteor, find whether user exists in mongodb document array or not?

This is my meteor code to search whether user exist in the array or not
var u_exist=Polls_Coll.findOne( {option1:{$elemMatch:{ids:"xxx"}}} );
My question is, How to know whether the statement returning something or not(user exist or not)
$elemMatch will return only where one of the conditions supplied actually finds a match in the array. So if you don't get a document back then there was no match.
Also findOne is a single document. Modifiers such as .count() will not work on that. If you have more documents to be expected use find intstead. Also findOne not not make much sense without applying a unique identifier such as _id in the query. Without that you are almost certainly not getting what you want.
While useful for your purpose, findOne is not a good match with the $elemMatch operator. The reasoning is you can possibly get multiple results of the same document having the same set of array elements that matched the condition that you gave.
Buyer beware.

Sort by reference document in Doctrine MongoDB ODM

I'm using DoctrineMongoDBOBundle with Symfony2.
I've a Document Product which has an annotation referenceOne to other Document Price.
I want to sort by price when I fetch with queryBuilder.
$qb = $dm->createQueryBuilder('MyBundle:Product')
->field('geocoordinates')
->near('lat','lon')
->sort('hasPrice','desc')
But this doesn't works. Perhaps for the use of near?
It depends of toString() method of Document Price?
Regards.
I've a Document Product which has an annotation referenceOne to other Document Price.
There are no joins in MongoDB and I do not believe Doctrine does client side aggregation and sorting here. As such this wouldn't work anyway.
However sorting will work on a $near command ( http://docs.mongodb.org/manual/reference/operator/near/ ) which is what Doctrine should be using in this case, here you can see explicit support for $near being identified through the command you are using: https://github.com/doctrine/mongodb/commit/59f73cde2c15d171ff39afbf46c1a1339a51048c so your problem is the linked document, MongoDB has no JOINs.
In this case, hasPrice looks like it corresponds to a method, that perhaps checks whether the price reference is null or not. When referring to fields in ODM queries, names of class properties may be translated to the MongoDB field names (if they differ), but there is no support for method evaluation. Sammaye was correct that Doctrine does no client-side aggregation or sorting.
As an alternative, you may be able to sort on the price.$id field, which should group nonexistent values together in the results. Similarly, you could use the $exists operator to match/exclude based on whether a document was actual referenced. References in ODM (excluding the "Simple" type) are stored as MongoDBRef instances, which translate to objects with $id, $ref, and $db fields. As a result, you can query on those values just like any other field in your document.