Mongoid查询buffer_time整数字段+ Time的和.现在哪个比schedule_at字段大



我有一个mongo模型与buffer_time(Integer)和scheduled_at(DateTime)字段。我想要一个优化的查询来获取

(Time.now + buffer_time.minutes) > scheduled_at

这是模型adminationtask

{
                        :_id => BSON::ObjectId('53d5091870637330e84e0000'),
                :buffer_time => 60,
              :resident_name => "jegi",
               :scheduled_at => 2014-08-26 14:00:00 UTC,
                     :status => "open",
                 :updated_at => 2014-07-27 14:13:44 UTC
}
我可以用map来写这个,但是它会消耗很多时间。

CRUD操作只支持简单的比较和操作。如果需要进行计算,建议使用聚合框架。您仍然应该考虑简化您的模式,例如,通过将buffer_time字段的值合并到scheduled_at的值中来消除buffer_time字段。

下面是一个答案,展示了如何使用聚合框架来做你想做的事情。希望您喜欢它,并且它可以帮助您理解聚合框架如何计算匹配结果。

测试/单位/administration_task_test.rb

require 'test_helper'
require 'pp'
class AdministrationTaskTest < ActiveSupport::TestCase
  def setup
    Mongoid.default_session.drop
  end
  test 'multiple tag references' do
    admin_task_data = {
        :buffer_time => 60,
        :resident_name => "jegi",
        :scheduled_at => Time.parse("2014-08-26 14:00:00 UTC"),
        :status => "open",
        :updated_at => Time.parse("2014-07-27 14:13:44 UTC")
    }
    AdministrationTask.create(admin_task_data)
    AdministrationTask.create(admin_task_data.merge(resident_name: 'xyzzy', scheduled_at: Time.now))
    puts "nall administration tasks:"
    pp AdministrationTask.all.to_a
    run_now_tasks = AdministrationTask.collection.aggregate(
          {
              '$project' => {
                  '_id' => '$_id', 'buffer_time' => '$buffer_time', 'resident_name' => '$resident_name',
                    'scheduled_at' => '$scheduled_at', 'status' => '$status', 'updated_at' => '$updated_at',
                  'match' => {
                      '$gt' => [
                          {'$add' => [Time.now, {'$multiply' => ['$buffer_time', 1000]}]},
                          '$scheduled_at'
                      ]
                  }
              }
          },
          {
              '$match' => {'match' => true}
          }
      ).to_a
    puts "administration tasks to run now:"
    pp run_now_tasks
    assert_equal(1, run_now_tasks.size)
    assert_equal('xyzzy', run_now_tasks.first['resident_name'])
  end
  test '0. mongoid version' do
    puts "nMongoid::VERSION:#{Mongoid::VERSION}nMoped::VERSION:#{Moped::VERSION}"
  end
end

耙测试

Run options:
# Running tests:
[1/2] AdministrationTaskTest#test_0._mongoid_version
Mongoid::VERSION:3.1.6
Moped::VERSION:1.5.2
[2/2] AdministrationTaskTest#test_multiple_tag_references
all administration tasks:
[#<AdministrationTask _id: 53f266bd7f11ba0f51000001, buffer_time: 60, resident_name: "jegi", scheduled_at: 2014-08-26 14:00:00 UTC, status: "open", updated_at: 2014-07-27 14:13:44 UTC>,
 #<AdministrationTask _id: 53f266bd7f11ba0f51000002, buffer_time: 60, resident_name: "xyzzy", scheduled_at: 2014-08-18 20:49:01 UTC, status: "open", updated_at: 2014-07-27 14:13:44 UTC>]
administration tasks to run now:
[{"_id"=>"53f266bd7f11ba0f51000002",
  "buffer_time"=>60,
  "resident_name"=>"xyzzy",
  "scheduled_at"=>2014-08-18 20:49:01 UTC,
  "status"=>"open",
  "updated_at"=>2014-07-27 14:13:44 UTC,
  "match"=>true}]
Finished tests in 0.524457s, 3.8135 tests/s, 3.8135 assertions/s.
2 tests, 2 assertions, 0 failures, 0 errors, 0 skips

最新更新