Matthew Casey
Matthew Casey

Reputation: 175

MongoDB find_one on array field returning document every-time even without a match

Trying so that I can check if a user has previously liked a recipe so they can't like it twice. I have users in my DB that look like:

username:"username"
password:"password"
likes:Array
0:"recipe_id"

Im trying to use the query:

 if mongo.db.users.find_one({'username': session.get('USERNAME')}, {'likes': [recipe_id]}) == None:
            mongo.db.recipe.update_one({'_id': ObjectId(recipe_id)}, {
                '$inc': {'likes': 1}})
            mongo.db.users.update_one({'username': session['USERNAME']}, {
                '$push': {'likes': recipe_id}})

but its just returning regardless of the recipeId being in the array or not. I think this is because its doing two queries. Is there a way to specify the second query to only look at that specific user ?

Upvotes: 1

Views: 290

Answers (1)

whoami - fakeFaceTrueSoul
whoami - fakeFaceTrueSoul

Reputation: 17935

Issue with your query is you're having likes : [recipe_id] in projection part of .find_one. So it has to be in filter part, Basically second argument to .find() or .find_one() is projection which helps to project certain fields in the document.

Try this query :

/** So all you need is to check if `recipe_id` exists in `likes` array or not,
 * then if it exists instead of returning entire doc, 
 * using projection just return `_id` of doc which is quiet enough for your need,
 * in other case query will return none if no matching doc exists */

if mongo.db.users.find_one({'username': session.get('USERNAME'), 'likes': recipe_id}, {_id :1}) == None:
            mongo.db.recipe.update_one({'_id': ObjectId(recipe_id)}, {
                '$inc': {'likes': 1}})
            mongo.db.users.update_one({'username': session['USERNAME']}, {
                '$push': {'likes': recipe_id}})

In .find_one() you don't need to wrap recipe_id in array like what you're doing : likes : [recipe_id] is not needed, If you wanted to do it you need to use $in operator like this { likes : {$in : [recipe_id] } } in filter part of query.

Ref : .findOne() & .find_one()

Upvotes: 2

Related Questions