Docs 菜单

新增功能

在此页面上

了解以下版本中的新功能:

要查看版本列表和详细的发布说明,请参阅Github上的 Mongoid 版本。

9.0发布包括以下新增功能、改进和修复:

随着 Mongoid v9.0 的发布, railsmdb 是一个用于创建、更新、管理和维护 Rails 应用程序的命令行实用程序,现已正式发布。

railsmdb使通过Ruby on Rails 开发者已经熟悉的通用生成器可以更轻松地命令行使用MongoDB 。

示例,您可以使用railsmdb为新的 Mongoid 模型生成存根:

bin/railsmdb generate model person

这将在app/models/person.rb处创建一个新模型:

class Person
include Mongoid::Document
include Mongoid::Timestamp
end

您可以指定模型的字段:

bin/railsmdb generate model person name:string birth:date
class Person
include Mongoid::Document
include Mongoid::Timestamp
field :name, type: String
field :birth, type: Date
end

您可以通过传递--parent选项来指示生成器将新模型设为另一个模型的子类:

bin/railsmdb generate model student --parent=person
class Student < Person
include Mongoid::Timestamp
end

如果您需要将模型存储在不同于从模型名称推断的集合中,则可以指定 --collection

bin/railsmdb generate model course --collection=classes
class Course
include Mongoid::Document
include Mongoid::Timestamp
store_in collection: 'classes'
end

有关更多信息,请参阅Github上的 mongoid-railsmdb存储库。

Mongoid v9.0 需要Ruby 2.7 或更高版本或 JRuby 9.4。 不支持早期的Ruby和 JRuby 版本。

Mongoid v9.0 需要 Rails 6.0 或更高版本。 不支持早期的 Rails 版本。

已弃用的Mongoid::Errors::InvalidStorageParent类已被删除。

Mongoid v8.x 及更早版本允许用户为嵌入式文档定义 around_* 回调。 从 v9.0 开始, 这些回调将被忽略,不会被执行。 如果定义了此类回调,则控制台将打印警告。

如果要恢复旧行为,可以在应用程序中将Mongoid.around_embedded_document_callbacks设立为 true。

注意

不建议为嵌入式文档启用around_*回调,因为当文档具有许多嵌入式文档时,可能会导致SystemStackError异常。 请参阅 MONGOID-5658 了解更多详情。

for_js 方法已弃用,并将在 Mongoid v10.0 中删除。

重大更改:Mongoid v 中删除了以下配置选项。9.0请确保您已从应用应用中删除对这些内容的所有引用。 如果您在升级之前使用的是 config.load_defaults 8.1,则不会出现任何行为变化。 有关每个选项的含义,请参阅早期的发布说明。

  • :use_activesupport_time_zone

  • :broken_aggregables

  • :broken_alias_handling

  • :broken_and

  • :broken_scoping

  • :broken_updates

  • :compare_time_by_ms

  • :legacy_attributes

  • :legacy_pluck_distinct

  • :legacy_triple_equals

  • :object_id_as_json_oid

  • :overwrite_chained_operators

此外,已删除对 config.load_defaults 版本 v7.5 及更早版本的支持(您必须至少使用版本 v8.0。)

重大更改:以下已弃用的功能现已删除:

  • Mongoid::QueryCache 模块已被删除。 请将 1-for-1 的所有用法替换为 Mongo::QueryCache。 方法 Mongoid::QueryCache#clear_cache 应替换为 Mongo::QueryCache#clear。 所有其他方法和子模块的名称相同。

  • Object#blank_criteria? 方法已删除(之前已弃用)。

  • Document#as_json :compact选项已删除。 请改为对返回的Hash对象调用`#compact

  • 已弃用的Mongoid::Errors::InvalidStorageParent类已被删除。

在 Mongoid v8.x 及更早版本中,touch 方法使模型处于更改状态:

# v8.x behaviour
band = Band.create!
band.touch
band.changed? # => true
band.changes
# => {"updated_at"=>[2023-01-30 13:12:57.477191135 UTC, 2023-01-30 13:13:11.482975646 UTC]}

从 v9.0 开始, Mongoid 现在可以在使用 touch 方法后正确清除变更状态。

# v9.0 behavior
band = Band.create!
band.touch
band.changed? # => false
band.changes # => {}

Mongoid 现在支持 Rails 控制台沙盒模式。 如果 Rails 控制台使用 --sandbox 标志启动,则 Mongoid 会在打开控制台之前在 :default客户端上启动ACID 事务。 此ACID 事务不会提交。 因此,使用 :default客户端在控制台中执行的所有命令都不会保留在数据库中。

注意

如果使用 default 以外的任何其他客户端在沙盒模式下执行命令,这些更改将照常保留。

Mongoid 9.0 引入了受 Active Record 启发的新事务API :

Band.transaction do
Band.create(title: 'Led Zeppelin')
end
band = Band.create(title: 'Deep Purple')
band.transaction do
band.active = false
band.save!
end

要学习;了解更多信息,请参阅 事务和会话指南。

Mongoid v8.x 及更早版本允许用户为嵌入式文档指定持久性上下文(使用 store_in 宏)。 在 Mongoid v9.0 对于嵌入式文档,这些设置将被忽略。 嵌入式文档现在始终使用其父文档的持久性上下文。

在执行查询时,现在可以使用 Mongoid::RawValue 包装器类跳过 Mongoid 的类型强制逻辑。 当数据库中的传统数据的类型与字段定义不同时,这非常有用。

class Person
include Mongoid::Document
field :age, type: Integer
end
# Query for the string "42", not the integer 42
Person.where(age: Mongoid::RawValue("42"))

现在,当尝试访问模型实例上的字段时,如果在加载实例时使用onlywithout查询投影方法排除了该字段,Mongoid 现在会引发Mongoid::Errors::AttributeNotLoaded错误。

Band.only(:name).first.label
#=> raises Mongoid::Errors::AttributeNotLoaded
Band.without(:label).first.label = 'Sub Pop Records'
#=> raises Mongoid::Errors::AttributeNotLoaded

在早期的 Mongoid 版本中,相同的条件会引发ActiveModel::MissingAttributeError 。 请检查您的代码中是否有此类的任何特定于 Mongoid 的用法,并将其更改为Mongoid::Errors::AttributeNotLoaded 。 另外请注意, AttributeNotLoaded会继承自Mongoid::Errors::MongoidError ,而ActiveModel::MissingAttributeError不会。

当使用日期值查询时间字段时,Mongoid 现在可以正确地考虑Time.zone来执行类型转换。

class Magazine
include Mongoid::Document
field :published_at, type: Time
end
Time.zone = 'Asia/Tokyo'
Magazine.gte(published_at: Date.parse('2022-09-26'))
#=> will return all results on or after Sept 26th, 2022
# at 0:00 in Asia/Tokyo time zone.

在以前的 Mongoid 版本中,上述代码会忽略 Time.zone(无论现在已删除的 :use_activesupport_time_zone 设置如何),并始终使用系统时区域来执行类型转换。

请注意,在以前的 Mongoid 版本中,在持久性操作期间将 Date 类型转换为 Time 已经正确使用时区域。

当对embedded_in关系设立touch: false选项时,对嵌入式子文档调用touch方法将不会对其父文档调用touch

class Address
include Mongoid::Document
include Mongoid::Timestamps
embedded_in :mall, touch: false
end
class Mall
include Mongoid::Document
include Mongoid::Timestamps
embeds_many :addresses
end
mall = Mall.create!
address = mall.addresses.create!
address.touch
#=> updates address.updated_at but not mall.updated_at

此外, touch方法已经过优化,即使在使用多个级别的嵌套嵌入式文档时,也可对每个父文档执行一个持久性操作。

更新嵌入式子文档现在将自动触及父文档,除非您在该关系上显式设立touch: false

class Address
include Mongoid::Document
include Mongoid::Timestamps
embedded_in :mall, touch: false
end

对于所有其他关联,默认仍为touch: false

Mongoid v8.1 向 upsert 方法添加了 :replace 选项。 此选项用于指定是否应更新或替换现有文档。

Mongoid v9.0 将此标志的默认从 true 翻转为 false。 这意味着,默认,Mongoid v9.0 更新现有文档,而不是替换它。

在 Mongoid v9.0 之前, 修改 _id字段的行为会不一致,具体取决于文档是顶层文档还是嵌入式文档,以及更新的执行方式。 在 v9.0 中, 现在,如果文档之前已持久保存,则更改 _id字段现在会在保存文档时引发异常。

Mongoid 9.0还引入了一个新的功能标志immutable_ids ,默认为true

Mongoid::Config.immutable_ids = true

当设立为 false 时,将恢复较早的不一致行为。

已添加对在index宏的以下选项中使用别名字段名称的支持: partial_filter_expressionweightswildcard_projection

class Person
include Mongoid::Document
field :a, as: :age
index({ age: 1 }, { partial_filter_expression: { age: { '$gte' => 20 } })
end

注意

索引选项中字段名称别名的扩展(例如partial_filter_expression )是根据MongoDB 服务器 6.0的行为执行的。 未来的服务器版本可能会改变对这些选项的解释方式,Mongoid 的功能可能不支持此类更改。

当BSON 4 或更早版本存在时,声明为 BSON::Decimal128 的任何字段都将返回 BSON::Decimal128 值。 但是,当BSON 5 存在时,声明为 BSON::Decimal128 的任何字段都将默认返回 BigDecimal 值。

class Model
include Mongoid::Document
field :decimal_field, type: BSON::Decimal128
end
# under BSON <= 4
Model.first.decimal_field.class #=> BSON::Decimal128
# under BSON >= 5
Model.first.decimal_field.class #=> BigDecimal

如果您需要具有BSON 5 的字面 BSON::Decimal128 值,您可以指示 Mongoid 支持字面 BSON::Decimal128 字段:

Model.first.decimal_field.class #=> BigDecimal
Mongoid.allow_bson5_decimal128 = true
Model.first.decimal_field.class #=> BSON::Decimal128

注意

allow_bson5_decimal128选项仅在 BSON 5及更高版本下有效。 BSON 4及更早版本完全忽略该设置。

连接到MongoDB Atlas时,Mongoid 现在支持创建和删除搜索索引。 您可以通过 Mongoid::SearchIndexable API以编程方式执行此操作:

class SearchablePerson
include Mongoid::Document
search_index { ... } # define the search index here
end
# create the declared search indexes; this returns immediately, but the
# search indexes may take several minutes before they are available.
SearchablePerson.create_search_indexes
# query the available search indexes
SearchablePerson.search_indexes.each do |index|
# ...
end
# remove all search indexes from the model's collection
SearchablePerson.remove_search_indexes

如果未连接到MongoDB Atlas,则会忽略搜索索引定义。 尝试创建、枚举或删除搜索索引将导致错误。

为了方便起见,还提供了 rake 任务:

# create search indexes for all models; waits for indexes to be created
# and shows progress on the terminal.
$ rake mongoid:db:create_search_indexes
# as above, but returns immediately and lets the indexes be created in the
# background
$ rake WAIT_FOR_SEARCH_INDEXES=0 mongoid:db:create_search_indexes
# removes search indexes from all models
$ rake mongoid:db:remove_search_indexes

Time.configured返回包装已配置时区域的时间对象,或标准Ruby Time类。 这样,即使没有配置时区域,您也可以查询时间值。

现在,如果您打算对时间值执行任何操作(包括在文档中使用时间戳),Mongoid 都要求您设置时区。 对Time.configured的任何使用都必须替换为Time.zone

# before:
puts Time.configured.now
# after:
puts Time.zone.now
# or, better for finding the current Time specifically:
puts Time.current

如果不设立时区域,您将在代码中看到与nil值相关的错误。 如果您使用的是 Rails,则默认时区域已设立为 UTC。 如果您不使用 Rails,则可以在程序启动时设立时区域,如下所示:

Time.zone = 'UTC'

这会将时区域设立为 UTC。 您可以通过运行以下命令来查看所有可用的时区域名称:

$ ruby -ractive_support/values/time_zone \
-e 'puts ActiveSupport::TimeZone::MAPPING.keys'

考虑以下代码:

record = Model.with(collection: 'other_collection') { Model.first }
record.update(field: 'value')

在 Mongoid v9.0 之前,上述代码无法以静默方式执行更新,因为记录不会记住存储选项(此处为模型的备用集合规范)。 因此,该记录将从 other_collection 加载,但在更新时会尝试在模型的默认集合中查找并更新该文档。 为此,您必须为每次更新显式指定集合。

从 Mongoid v9.0 开始, 在显式存储选项下创建或加载的记录,将记住这些选项(包括命名客户端、不同数据库或不同集合)。

如果您需要旧版(v9.0 之前的版本) 行为,您可以使用以下标志启用它:

Mongoid.legacy_persistence_context_behavior = true

在 Mongoid v9.0 中,此标志默认为 false。

在此页面上