MongoDB return True if document exists
Asked Answered
W

6

40

I want to return true if a userID already exists and false otherwise from my collection.I have this function but it always returns True.

def alreadyExists(newID):
    if db.mycollection.find({'UserIDS': { "$in": newID}}):
        return True
    else:
        return False

How could I get this function to only return true if a user id already exists?

Wommera answered 6/8, 2014 at 14:55 Comment(0)
I
48

Note: This answer is outdated. More recent versions of MongoDB can use the far more efficient method db.collection.countDocuments. See the answer by Xavier Guihot for a better solution.

find doesn't return a boolean value, it returns a cursor. To check if that cursor contains any documents, use the cursor's count method:

if db.mycollection.find({'UserIDS': { "$in": newID}}).count() > 0

If newID is not an array you should not use the $in operator. You can simply do find({'UserIDS': newID}).

Ingraham answered 6/8, 2014 at 15:18 Comment(5)
I would only add to this answer to include a projection with only the '_id':1 set so as the DB doesn't return an entire object, every ms and byte counts :)Opalopalesce
Limiting result set to 1 with .limit(1) might be another valuable hint to the databaseVenturesome
@Venturesome So use find_one() instead?Delisadelisle
Oh, find_one() doesn't take a projection. find() it is!Delisadelisle
This is inefficient. For performance I suggest using 'count_documents' as stated in Xavier's answer.Duffel
P
50

Starting Mongo 4.0.3/PyMongo 3.7.0, we can use count_documents:

if db.collection.count_documents({ 'UserIDS': newID }, limit = 1) != 0:
  # do something

Used with the optional parameter limit, this provides a way to find if there is at least one matching occurrence.

Limiting the number of matching occurrences makes the collection scan stop as soon as a match is found instead of going through the whole collection.


Note that this can also be written as follow since 1 is interpreted as True in a python condition:

if db.collection.count_documents({ 'UserIDS': newID }, limit = 1):
  # do something

In earlier versions of Mongo/Pymongo, count could be used (deprecated and replaced by count_documents in Mongo 4):

if db.collection.count({ 'UserIDS': newID }, limit = 1) != 0:
  # do something
Pansir answered 26/10, 2018 at 8:59 Comment(1)
Thanks a bunch. This reply should be the first one in the list!Astrograph
I
48

Note: This answer is outdated. More recent versions of MongoDB can use the far more efficient method db.collection.countDocuments. See the answer by Xavier Guihot for a better solution.

find doesn't return a boolean value, it returns a cursor. To check if that cursor contains any documents, use the cursor's count method:

if db.mycollection.find({'UserIDS': { "$in": newID}}).count() > 0

If newID is not an array you should not use the $in operator. You can simply do find({'UserIDS': newID}).

Ingraham answered 6/8, 2014 at 15:18 Comment(5)
I would only add to this answer to include a projection with only the '_id':1 set so as the DB doesn't return an entire object, every ms and byte counts :)Opalopalesce
Limiting result set to 1 with .limit(1) might be another valuable hint to the databaseVenturesome
@Venturesome So use find_one() instead?Delisadelisle
Oh, find_one() doesn't take a projection. find() it is!Delisadelisle
This is inefficient. For performance I suggest using 'count_documents' as stated in Xavier's answer.Duffel
H
3

If you're using Motor, find() doesn't do any communication with the database, it merely creates and returns a MotorCursor:

http://motor.readthedocs.org/en/stable/api/motor_collection.html#motor.MotorCollection.find

Since the MotorCursor is not None, Python considers it a "true" value so your function returns True. If you want to know if at least one document exists that matches your query, try find_one():

@gen.coroutine
def alreadyExists(newID):
    doc = yield db.mycollection.find_one({'UserIDS': { "$in": newID}})
    return bool(doc)

Notice you need a "coroutine" and "yield" to do I/O with Tornado. You could also use a callback:

def alreadyExists(newID, callback):
    db.mycollection.find_one({'UserIDS': { "$in": newID}}, callback=callback)

For more on callbacks and coroutines, see the Motor tutorial:

http://motor.readthedocs.org/en/stable/tutorial.html

If you're using PyMongo and not Motor, it's simpler:

def alreadyExists(newID):
    return bool(db.mycollection.find_one({'UserIDS': { "$in": newID}}))

Final note, MongoDB's $in operator takes a list of values. Is newID a list? Perhaps you just want:

find_one({'UserIDS': newID})
Heterochromatin answered 6/8, 2014 at 15:20 Comment(1)
How to write this in Mongo Shell? Make Mongo Shell return boolean.Configurationism
A
1
return db.mycollection.find({'UserIDS': newID}).count > 0
Arguseyed answered 13/5, 2017 at 14:47 Comment(0)
R
1

One liner solution in mongodb query

db.mycollection.find({'UserIDS': { "$in": newID}}).count() > 0 ? true : false
Radiative answered 16/12, 2017 at 5:17 Comment(0)
U
0

This worked for me

result = num.find({"num": num}, { "_id": 0 }) 
if result.count() > 0:  
   return
else:
   num.insert({"num": num, "DateTime": DateTime })
Unceremonious answered 16/2, 2018 at 13:5 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.