Именованная область Mongoid, сравнивающая два поля времени в одном документе

Мне нужно создать именованную область в Mongoid, которая сравнивает два поля времени в одном документе. Такие как

scope :foo, :where => {:updated_at.gt => :checked_at}

Очевидно, что это не сработает, так как :checked_at рассматривается как символ, а не как фактическое поле. Любые предложения о том, как это можно сделать?

Обновление 1

Вот моя модель, в которой у меня объявлена ​​эта область действия, из которой удалено много лишнего кода.

class User
  include Mongoid::Document
  include Mongoid::Paranoia
  include Mongoid::Timestamps

  field :checked_at, :type => Time

  scope :unresolved, :where => { :updated_at.gt => self.checked_at }
end

Это дает мне следующую ошибку:

'<class:User>': undefined method 'checked_at' for User:Class (NoMethodError)


person Jey Balachandran    schedule 25.09.2010    source источник


Ответы (3)


Насколько я знаю, mongodb не поддерживает запросы к динамическим значениям. Но вы можете использовать функцию javascript:

scope :unresolved, :where => 'this.updated_at >= this.checked_at'

Чтобы ускорить это, вы можете добавить такой атрибут, как «is_unresolved», который будет установлен в значение true при обновлении, когда это условие будет соблюдено (и проиндексировать это).

person Baju    schedule 13.10.2010
comment
Круто, это отлично работает. Также спасибо за предложение по производительности. - person Jey Balachandran; 18.10.2010

scope :foo, :where => {:updated_at.gt => self.checked_at}

Например, это будет работать:

scope :foo, where(:start_date.lte=>Date.today.midnight)
person Jesse Wolgamott    schedule 25.09.2010
comment
Это не работает. undefined method checked_at' для пользователя: класс (NoMethodError)`. Второй оператор будет работать, так как вы передаете объект. Мне нужно сравнить два поля, которые являются частью одного и того же документа/модели. - person Jey Balachandran; 26.09.2010
comment
Вам нужно опубликовать свой пользовательский класс - просто включить mongoid и определение для checked_at и вашей области - person Jesse Wolgamott; 26.09.2010
comment
Я отредактировал исходный вопрос с помощью класса User. Спасибо за ваше время до сих пор Джесси. - person Jey Balachandran; 27.09.2010

Не уверен, что вам понравится этот метод, он не самый лучший, но он должен работать.

class User
  include Mongoid::Document
  include Mongoid::Paranoia
  include Mongoid::Timestamps

  field :checked_at, :type => Time

  scope :unresolved, lambda{ |user| where(:updated_at.gt => user.checked_at) }
end

Вы вызываете это с помощью User.unresolved(my_user_object). Теперь, после повторного прочтения вашего сообщения, кажется, что это, вероятно, не будет делать то, что вы хотите. Если это так, то вам, вероятно, потребуется использовать MapReduce или, возможно, метод Baju (не проверял его)

person Preston Marshall    schedule 14.10.2010