45
votes

This must be asked alot but it is very poorly documented. There is no mention at http://mongoid.org/en/mongoid/docs/querying.html

I'm trying to check whether a user exists (below is an AND query), how can I change it to an OR type query

Username.where(:username=>@username, :email=>@email)

(Either the email or the username must match).

I have found some pretty complicated ways online including sending a direct javascript (from): http://omarqureshi.net/articles/2010-6-17-using-or-in-mongoid

Surely there must be a simple clear syntax to do this correctly?

5

5 Answers

121
votes

For the sake of others who end up on this page, the updated syntax is now

Username.or({username: @username}, {email: @email})

Please refer to the updated docs or relevant impl.

51
votes

Yeah, this used to be documented better. Try this:

Username.any_of({:username => @username},
                {:email => @email})
9
votes

There is a typo in @miguel-savignano's response. According to Stackoverflow the "edit queue is full", which is why I didn't submit an edit.

Proper syntax:

Username.or({username: @username}).or({email: @email})

A more concise solution:

Username.or({username: @username}, {email: @email})

The Mongo selector will resolve to:

{"$or"=>[{"username"=>@username}, {"email"=>@email}]}

I found this question as I was trying to solve for creating "or" queries.

If you are looking to match a string or any one of an array of elements, then you will need to write a Mongoid query with the Mongo '$in' selector.

For example, you have a specific username and an array of emails. You would like to return all results where at least one of the fields matches either the username or one of the emails within the array.

@username = "jess"
@emails = ["[email protected]", "[email protected]", "[email protected]"]
User.or({username: ""}, {email: {'$in': @emails}})

The Mongo selector will resolve to:

{"$or"=>[{"first_name"=>""}, {"email"=>{:$in=>["[email protected]", "[email protected]", "[email protected]"]}}]}
  • If you have Users with 2 of the 3 emails in your database, then the selector will return a count of 2.
  • If you have a User with the username "jess" and 3 additional Users each with one of the given emails, then the selector will return a count of 4.
9
votes

Also, in Mongoid 5.0, if you still want to use the where method, use the following

Username.where('$or' => [ { username: @username }, { email: @email } ])

this is very useful when you are building a kind of query hash in a dynamic way and you need to keep the where method

4
votes

In Mongoid 5.0, this works for me

Username.or({username: @username}).or({email: @email})