2

So this question is two years old:

Querying embedded objects in Mongoid/rails 3 ("Lower than", Min operators and sorting)

and the way it recommends to query nested objects with less than or greater than:

current_user.trips.where('start.time' => {'$gte' => Time.now}).count

simply doesn't work, it returns 0 for the numerous queries I have like this which is wrong. I've also tried

current_user.trips.where(:'start.time'.gte => Time.now}).count

which is also 0. None of these actually throw an error.

What is the correct syntax for querying nested elements nowadays? Seems to be a fair bit of confusion over this.

Community
  • 1
  • 1
Niall Paterson
  • 3,580
  • 3
  • 29
  • 37

1 Answers1

2

It works as you expect in my environment. (mongoid 3.1.3)

class User
  include Mongoid::Document
  embeds_many :trips
end

class Trip
  include Mongoid::Document
  embeds_one :start
  embedded_in :user
end

class Start
  include Mongoid::Document
  field :time, type: DateTime
  embedded_in :trip
end

User.create({ trips: [
  Trip.new({ start: Start.new({ time: 5.days.ago }) }),
  Trip.new({ start: Start.new({ time: 2.days.from_now }) })
] })

current_user = User.where({}).first

p current_user.trips.where('start.time' => {'$gte' => Time.now}).count
p current_user.trips.where(:'start.time'.gte => Time.now).count

The above code outputs the following:

1
1

Is $gte really correct? It is a common mistake to use the opposite sign when comparing dates.

Or it might be because you are using older version of Mongoid.

Update:

You can check queries Mongoid generates with the following code:

Mongoid.logger.level = Logger::DEBUG
Moped.logger.level = Logger::DEBUG
Mongoid.logger = Logger.new($stdout)
Moped.logger = Logger.new($stdout)

This is useful for debugging.

Akihiro HARAI
  • 574
  • 1
  • 8
  • 17
  • Thanks for answering :) I don't want to use embeds_one/embedded_in, rather I'm using has_one/belongs_to, don't think thats causing the problem. Version is the same, still giving me back zero, even when `current_user.trips.first.start.time` is fine... – Niall Paterson May 13 '13 at 08:12
  • `has_one` is different from `embeds_one`. MongoDB doesn't support Join operation. Outputting logs of Mongoid will help you understand the difference. – Akihiro HARAI May 13 '13 at 14:07
  • Oh I know that, thats why I pointed it out! That could be it. – Niall Paterson May 13 '13 at 14:10
  • 1
    Nested querying which uses `has_one`/`has_many` relation is impossible in MongoDB. This is a limitation of MongoDB and even Object Document Mapper cannot solve it. – Akihiro HARAI May 13 '13 at 22:20