ksol
ksol

Reputation: 12235

Mongoid or/any_of unexpected behaviour

I'm having an issue with mongoid any_of. I'm trying to find objects that have either one field > 0, or another one > 0. My query is :

Model.any_of(best_friend_method.gt => 0, method.gt => 0).desc(best_friend_method, method)

It is "translated" in :

#<Mongoid::Criteria
  selector: {"$or"=>[{:best_friends_lc_sum=>{"$gt"=>0}, :lc_sum=>{"$gt"=>0}}]},
  options:  {:sort=>[[:best_friends_lc_sum, :desc], [:lc_sum, :desc]]},
  class:    FbAlbum,
  embedded: false>

As I understand it, this is what I want. But it only returns me 6 results. Model.where(:best_friends_lc_sum.gt => 0).count returns me 6 results too, but Model.where(:lc_sum.gt => 0).count returns me ~850 objects.

I expect my query to return the union of those two : is a mongoid/mongodb error, or am I doing something wrong ?

FYI : mongoid 2.4.5, mongodb 2.0.2, rails 3.1.3

Thanks for your time!

Upvotes: 3

Views: 5399

Answers (2)

Andrew
Andrew

Reputation: 238717

In case this helps someone...In Mongoid 3, the Origin gem provides the syntax for querying. Here is the list of methods that you can use to write your Mongoid 3 queries. Among those methods is the or method which allows you to perform an $or query:

# Mongoid query:
Model.or(
  { name: "Martin" }, { name: "Dave" }
)

# resulting MongoDB query:
{
  "$or" => [
    { "name" => "Martin" }, { "name" => "Dave" }
  ]
}

Using the OP's original example, it can be rewritten as:

Model.or(
  { best_friend_method.gt => 0 },
  { method.gt => 0 }
).order_by(
  best_friend_method,
  method
)

At least one of the hashes passed to the or method must match in order for a record to be returned.

Upvotes: 0

shingara
shingara

Reputation: 46914

It's because you pass only one args and not 2 args. So it's like you have no $or usage.

Try :

Model.any_of({best_friend_method.gt => 0}, {method.gt => 0}).desc(best_friend_method, method)

In this case the Criteria become :

#<Mongoid::Criteria
  selector: {"$or"=>[{:best_friends_lc_sum=>{"$gt"=>0}}, {:lc_sum=>{"$gt"=>0}}]},
  options:  {:sort=>[[:best_friends_lc_sum, :desc], [:lc_sum, :desc]]},
  class:    FbAlbum,
  embedded: false>

Sometime the usage of {} is mandatory to separate different hash.

Upvotes: 10

Related Questions