MongoDB: findOne with $or condition - mongodb

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()?

Related

MongoDB insertMany returned _id order

After using insertMany I need to get the returned _ids from the new documents in the same order as they were inserted.
As stated by the documentation if the ordered parameter is equal to true, mongoDB will perform an ordered insert, but that does not imply that the returned _ids are also ordered in the same way as the new inserted documents.
I did some quick tests to check this and it seems that the order is preserved, but I need to be 100% sure that this is always the behavior.

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

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.

Mongodb query forward from username X

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.

mongodb - exclude subdocument depending on $gte while still returning root document

I would like to only return a subdocument if its expire field is in the future. My problem is that I would like to get the root document anyway.
I am currently using:
sub.expire: {"$gte": now}
it only returns the root document if sub.expire is true.
how would I return the root document regardless if sub gets returned or not?
Thanks
This isn't quite how MongoDB is designed. You're phrasing it as, you're trying to query a bunch of subdocuments and return them conditionally while returning the parent documents unconditionally; but as far as MongoDB is concerned there isn't a collection of subdocuments, there's a collection of documents, which each have fields, some of which may be subdocuments. When you say you're "using" this condition on a subdocument -- presumably for find() -- what you're really asking the collection for is documents which satisfy this condition in a subdocument. So documents that don't satisfy that condition aren't returned.
From MongoDB's point of view, what you actually want is closer to, return every document in the collection, but with a certain field (a subdocument, as it happens) stripped out if it's expired, which falls under "projection". There are two ways projection happens in MongoDB, and I'm afraid neither is exactly what you want:
find() lets you project the fields to return, but that's limited to: 1 (do), 0 (don't), or a few special operators if the field is an array, which a subdocument is not.
Aggregation gives you a $project operator to transform the results, but doesn't let you disappear this field (subdocument) entirely: if it has an expiration date in the past, you can replace it with null or (probably better) an empty document, but that's as close as you can get.

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.