【问题标题】:How to replace a null date field using MongoDB's aggregation framework?如何使用 MongoDB 聚合框架替换空日期字段?
【发布时间】:2013-10-23 18:49:12
【问题描述】:

使用 Rails 3.2.14、Ruby 1.9.3、Mongoid 3.1.5

我正在查询看起来像这样的文档:

{
   paid_on: ISODate("2013-03-08T22:25:24.973Z"),
   paid_amt: 25.5
}

有时 paid_onnull,但我也需要捕获这些文档,所以我尝试使用 $ifNull 来替换默认日期:

Claim.collection.aggregate(
    {
        "$project" => {
            "paid_on"  => {"$ifNull" => ["$paid_on", Date.new(1980, 1, 1).mongoize]},
            "paid_amt" => 1,
        }
    }
)

发送到 Mongo 的查询如下所示(刚刚捕获了 $project 部分):

{
"$project"=>{
     "paid_on" => {"$ifNull"=>["$paid_on", 1980-01-01 00:00:00 UTC]},
     "paid_amt" => 1
 }

失败:

失败并出现错误 16006:“异常:无法从 BSON 类型字符串转换为日期”

我尝试了其他几种发送日期的方法,但都没有成功:

  • 'ISODate("1980-01-01")'
  • { "$date" => 315554400000 }

【问题讨论】:

    标签: ruby mongodb mongoid aggregation-framework mongoid3


    【解决方案1】:

    以下内容对我有用。我建议你重新创建它,看看它与你的代码有什么不同。

    model/app/claim.rb

    class Claim
      include Mongoid::Document
      field :paid_on, type: Time
      field :paid_amt, type: Float
    end
    

    test/unit/claim_test.rb

    require 'test_helper'
    require 'pp'
    
    class ClaimTest < ActiveSupport::TestCase
      def setup
        Claim.delete_all
      end
    
      test "replace null date field" do
        docs = [
            {
                :paid_on => DateTime.parse("2013-03-08T22:25:24.973Z"),
                :paid_amt => 25.5
            },
            {
                :paid_on => nil,
                :paid_amt => 12.25
            }
        ]
        Claim.create(docs)
        pipeline = [
            {
                "$project" => {
                    "paid_on" => {"$ifNull" => ["$paid_on", Date.new(1980, 1, 1).mongoize]},
                    "paid_amt" => 1
                }
            }
        ]
        puts "\nMongoid::VERSION:#{Mongoid::VERSION}\nMoped::VERSION:#{Moped::VERSION}"
        puts "pipeline:#{pipeline.inspect}"
        pp Claim.collection.aggregate(pipeline)
      end
    end
    

    $ rake 测试

    Run options: 
    
    # Running tests:
    
    [1/1] ClaimTest#test_replace_null_date_field
    Mongoid::VERSION:3.1.5
    Moped::VERSION:1.5.1
    pipeline:[{"$project"=>{"paid_on"=>{"$ifNull"=>["$paid_on", 1980-01-01 00:00:00 UTC]}, "paid_amt"=>1}}]
    [{"_id"=>"5272720a7f11ba4293000001",
      "paid_on"=>2013-03-08 22:25:24 UTC,
      "paid_amt"=>25.5},
     {"_id"=>"5272720a7f11ba4293000002",
      "paid_on"=>1980-01-01 00:00:00 UTC,
      "paid_amt"=>12.25}]
    Finished tests in 0.039125s, 25.5591 tests/s, 0.0000 assertions/s.
    1 tests, 0 assertions, 0 failures, 0 errors, 0 skips
    

    【讨论】:

    • 我试图简化发布此问题的问题,不幸的是我简化了太多。您的解决方案有效,我将发布另一个更能代表我的确切问题的问题。谢谢
    猜你喜欢
    • 2013-05-27
    • 2020-04-08
    • 2013-07-23
    • 1970-01-01
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    • 2013-03-19
    • 1970-01-01
    相关资源
    最近更新 更多