mongoid pluck - 不返回模型中默认值的正确值

mongoid pluck - not returning correct values with default values in model

我有一个用户模型,其中有一个默认值为 "Engineering" 的部门字段。

该字段是我们网站上线2个月后引入的,自mongo以来,一直没有迁移。

当我尝试使用 where 获取对象时,返回了正确的值

 User.find_by(:name => "John).department

但是,如果我尝试提取值,它 returns 为 nil 而不是默认值。

 User.limit(2).pluck(:department)

returns

[nil,"Finance"]

我做了一些研究,发现了这个博客 post http://ahmadsherif.com/blog/2013/01/29/mongoid-default-fields-can-give-you-hard-time/

我想我也遇到了同样的问题。有什么解决方法吗?我选择了 pluck 因为它不占用内存并且节省时间。

基本上,这里的行为可以用 MongoDB 处理默认值的方式与传统关系数据库(如 Postgres)的不同来解释。

在 SQL 世界中,您通过数据库架构设置默认值,并且每次您插入一行时,数据库都会填充一个 NULL 字段。

由于 MongoDB 是无模式文档字段,默认值为 nil,无法更改* 因为没有模式,我们可以在数据库级别定义默认值。相反,默认值是在应用程序级别实现的。对于 Mongoid,这意味着当您初始化一个新的模型实例时,如果它们为 nil,它将填充默认值。

在 ActiveRecord 术语中它看起来像这样:

class Thing < ActiveRecord::Base
  after_initialize :set_default_foo, if: -> { self.foo.nil? }

  private 
    def set_default_foo
      self.foo = "bar"
    end
end

但是,如果您有现有文档并向现有字段添加新字段或默认值,Mongoid 不会为您更新现有文档!

那么这两种情况如何解释呢?

User.find_by(:name => "John").department
User.limit(2).pluck(:department)

在第一种情况下,您从存储中提取文档并使用它来初始化模型实例。初始化模型实例时,回调是 运行,它设置默认值。

当在手上调用 .pluck 时,Mongoid 直接从存储中提取值,而不初始化任何模型实例。因此,对于任何 "legacy" 文档,它将 return 为零值。

要解决此问题,您需要为任何包含 nil 的文档设置默认值。

User.where(department: nil).update_all(department: 'engineering')