Reputation: 115
I have a document in Mongo with two array fields:
field :app_usernames, type: Array
field :email_addresses, type: Array
I'd like to create a function which take an array of usernames and an array of email addresses to search collection. The kicker is that I want it to return documents which have any of the values passed in the arrays:
def find_people(usernames_to_search, emails_to_search)...
So given a document with field values:
app_usernames = ['test1','test2','test3']
email_addresses = ['[email protected]','[email protected]']
I want the function to find it when any of those values are searched, via the array parameters. It should return this document in the following cases:
find_people nil,['[email protected]']
find_people ['test3'],['[email protected]']
find_people ['oldusername'],['[email protected]']
The last one seems to be causing me trouble.
Thus far I've tried
.or(:app_usernames.in usernames_to_search, :email_addresses.in emails_to_search)
But to no avail.
Upvotes: 3
Views: 1730
Reputation: 434665
The or
method is meant to be called with a list of individual conditions so that it can turn this:
x.or(condition1, condition2)
into a MongoDB query like:
$or: [ condition1, condition2 ]
When you say:
.or(:app_usernames.in => usernames_to_search, :email_addresses.in => emails_to_search)
How many arguments are you passing to or
? The answer is one. You're actually saying this:
.or({ :app_usernames.in => usernames_to_search, :email_addresses.in => emails_to_search })
You need to add the braces yourself so Ruby doesn't collapse the arguments into one Hash:
.or(
{ :app_usernames.in => usernames_to_search },
{ :email_addresses.in => emails_to_search }
)
Or something like this:
args = [ ]
args.push(:app_usernames.in => usernames_to_search) if(usernames_to_search.present?)
args.push(:email_addresses.in => emails_to_search) if(emails_to_search.present?)
query = query.or(*args) if(args.present?)
Upvotes: 5