Tarang
Tarang

Reputation: 75975

Mongoid OR query syntax

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?

Upvotes: 47

Views: 25097

Answers (5)

miguel savignano
miguel savignano

Reputation: 1159

In Mongoid 5.0, this works for me

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

Upvotes: 7

James Lim
James Lim

Reputation: 13062

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.

Upvotes: 125

Johan Tique
Johan Tique

Reputation: 141

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

Upvotes: 9

Laura
Laura

Reputation: 148

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.

Upvotes: 9

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230531

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

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

Upvotes: 55

Related Questions