指定文档查询
在此页面上
Overview
在本指南中,您可以学习;了解如何使用 Mongoid 指定查询。
您可以通过创建查询过滤来优化查询返回的文档设立。查询过滤是一个表达式,用于指定MongoDB在读取或写入操作中用于匹配文档的搜索条件。 创建查询过滤时,可以提示驾驶员搜索与查询完全匹配的文档,也可以组合查询筛选器以Express更复杂的匹配条件。
Mongoid 提供了一种查询特定领域语言(DSL),类似于 Active Record 中使用的语言。
样本数据
本指南中的示例使用 Band
模型,该模型表示乐队或音乐群组。 每个部分的 Band
模型的定义可能不同,以演示不同的查询功能。 某些部分可能会使用其他模型来演示查询功能。
Mongoid 中的查询
Mongoid查询方法返回 Mongoid::Criteria
对象,这些对象是MongoDB查询API的可链接且延迟评估的包装器。 当您遍历结果时,将执行查询。 以下示例演示了简单查询的返回类型:
# Creates a simple query Band.where(name: "Deftones") # Returns a Criteria object # => #<Mongoid::Criteria # selector: {"name"=>"Deftones"} # options: {} # class: Band # embedded: false> # Evaluate the query by converting to JSON Band.where(name: "Deftones").to_json # Returns matching documents # => [{"_id":"...","name":"Deftones"}]
您可以使用 first
和 last
等方法返回单个文档。 您还可以使用 each
或 map
等方法遍历 Criteria
对象,从服务器检索文档。 您可以使用 to_json
将 Criteria
对象转换为JSON。
提示
链接方法
如果您在现有 Criteria
对象上链接其他查询方法,Mongoid 会合并过滤条件。
创建查询筛选器
本节介绍可用于创建过滤条件的语法模式。 您可以使用以下任何语法模式在 Mongoid 中指定查询:
字段语法
查询API语法
符号操作符语法
本部分中的示例使用以下模型定义:
class Band include Mongoid::Document field :name, type: String field :founded, type: Integer field :m, as: :member_count, type: Integer embeds_one :manager end class Manager include Mongoid::Document embedded_in :band field :name, type: String end
字段语法
字段查询语法使用基本的Ruby哈希。 键可以是符号或字符串,与MongoDB文档中的字段名称相对应。
以下代码显示了两个等效查询,它们使用字段查询语法来检索name
字段值为 'Depeche Mode'
的文档:
Band.where(name: 'Depeche Mode') Band.where('name' => 'Depeche Mode')
查询API事务语法
您可以使用哈希语法在任何字段上指定 Query API操作符,如以下等效查询所示:
Band.where(founded: {'$gt' => 1980}) Band.where('founded' => {'$gt' => 1980})
符号操作符语法
您可以将 Query API操作符指定为相应字段名称的符号方法,如以下代码所示:
Band.where(:founded.gt => 1980)
对不同字段类型的查询
本节介绍如何对具有不同类型值的字段执行查询。
已定义字段
要查询字段,该字段不需要位于模型类定义中。 但是,如果在模型类中定义了字段,则 Mongoid 在构造查询时会强制查询值以匹配定义的字段类型。
以下代码在查询 founded
字段时指定一个字符串值。 由于 founded
字段在模型类中定义为具有 Integer
值,因此在执行查询时,Mongoid 会将字符串 '2020'
强制转换为 2020
:
Band.where(founded: '2020')
原始值
要绕过 Mongoid 的查询类型强制行为并直接查询数据库中的原始类型值,请将查询值包装在 Mongoid::RawValue
类中,如以下代码所示:
Band.where(founded: Mongoid::RawValue('2020'))
字段别名
id
和 _id
字段是别名,因此您可以在查询中使用任一字段名称:
Band.where(id: '5ebdeddfe1b83265a376a760') Band.where(_id: '5ebdeddfe1b83265a376a760')
嵌入式文档
要查询嵌入式文档的字段值,可以使用点表示法。 以下代码检索嵌入式 Manager
文档的 name
字段为 'Smith'
的文档:
Band.where('manager.name' => 'Smith')
以下代码演示了在查询嵌入式字段时如何使用符号操作符:
Band.where(:'manager.name'.ne => 'Smith')
注意
即使所有条件都引用嵌入式文档字段,查询也始终返回顶级模型实例。
逻辑操作
Mongoid 支持对 Criteria
对象执行以下逻辑操作:
and
or
nor
not
这些方法采用一个或多个条件哈希或另一个 Criteria
对象作为参数。 not
操作有一个无参数版本。
以下代码演示了如何在查询中使用逻辑运算:
# Uses "and" to combine criteria Band.where(label: 'Trust in Trance').and(name: 'Astral Projection') # Uses "or" to specify criteria Band.where(label: 'Trust in Trance').or(Band.where(name: 'Astral Projection')) # Uses "not" to specify criteria Band.not(label: 'Trust in Trance', name: 'Astral Projection') # Uses "not" without arguments Band.not.where(label: 'Trust in Trance', name: 'Astral Projection')
注意
数组参数
为了确保与早期 Mongoid 版本的向后兼容性,逻辑运算方法接受参数数组,这些参数数组将被展平以获得条件。
将数组传递给逻辑操作已弃用,并且可能会在未来版本中删除。
以下查询会产生相同的条件:
# Conditions passed to separate "and" calls Band.and(name: 'Sun Kil Moon').and(member_count: 2) # Multiple conditions in the same "and" call Band.and({name: 'Sun Kil Moon'}, {member_count: 2}) # Multiple conditions in an array - Deprecated Band.and([{name: 'Sun Kil Moon'}, {member_count: 2}]) # Condition in "where" and a scope Band.where(name: 'Sun Kil Moon').and(Band.where(member_count: 2)) # Condition in "and" and a scope Band.and({name: 'Sun Kil Moon'}, Band.where(member_count: 2)) # Scope as an array element, nested arrays - Deprecated Band.and([Band.where(name: 'Sun Kil Moon'), [{member_count: 2}]])
操作符组合
逻辑操作符具有与 Active Record 中的逻辑操作符相同的语义。
当对同一字段多次指定条件时,所有条件都将添加到条件中,如以下代码中的查询所示:
# Combines as "and" Band.where(name: 'Swans').where(name: 'Feist') # Combines as "or" Band.where(name: 'Swans').or(name: 'Feist')
any_of
、none_of
、nor
和 not
操作的行为类似。
当您使用 and
、or
和 nor
逻辑操作符时,它们会根据点建立的条件进行操作:
# "or" applies to the first condition, and the second is combined # as "and" Band.or(name: 'Sun').where(label: 'Trust') # Same as previous example - "where" and "and" are aliases Band.or(name: 'Sun').and(label: 'Trust') # Same operator can be stacked any number of times Band.or(name: 'Sun').or(label: 'Trust') # The last label condition is added to the top level as "and" Band.where(name: 'Sun').or(label: 'Trust').where(label: 'Feist') # Interpreted query: # {"$or"=>[{"name"=>"Sun"}, {"label"=>"Trust"}], "label"=>"Feist"}
not 行为
您可以使用不带参数的 not
方法,在这种情况下,它将否定指定的下一个条件。 可以使用一个或多个哈希条件或 Criteria
对象来调用 not
方法,这些对象都会取反并添加到条件中。
以下示例演示了 not
的行为:
# "not" negates "where" Band.not.where(name: 'Best') # The second "where" is added as "$and" Band.not.where(name: 'Best').where(label: /Records/) # "not" negates its argument Band.not(name: 'Best')
注意
不能在MongoDB中将 $not
操作符与字符串参数一起使用。 Mongoid 使用 $ne
操作符来实现求反:
# String negation - uses "$ne" Band.not.where(name: 'Best') # Regex negation - uses "$not" Band.not.where(name: /Best/)
与 and
类似,not
操作会否定简单字段条件的各个条件。 对于复杂条件以及当字段已经定义了条件时,Mongoid 会使用 {'$and' => [{'$nor' => ...}]}
构造来模拟 $not
,因为MongoDB仅在每个字段上而不是全局上支持 $not
操作符:
# Simple condition Band.not(name: /Best/) # Complex conditions Band.where(name: /Best/).not(name: 'Astral Projection') # Symbol operator syntax Band.not(:name.ne => 'Astral Projection')
如果将not
与数组或正则表达式一起使用,请在服务器手册中查看$not
的限制。
增量查询构建
默认下,当您向查询添加条件时,Mongoid 认为每个条件都是完整的,并且独立于查询中存在的任何其他条件。 示例,调用 in
两次会添加两个单独的 $in
条件:
Band.in(name: ['a']).in(name: ['b']) # Interpreted query: # {"name"=>{"$in"=>["a"]}, "$and"=>[{"name"=>{"$in"=>["b"]}}]}
某些操作符方法支持以增量方式构建条件。 当您添加使用支持的操作符之一的条件时,Mongoid 会查看同一字段上是否已经存在使用相同操作符的条件。 如果是,则根据指定的合并策略对操作符表达式进行组合。以下部分介绍了可用的合并策略。
合并策略
Mongoid 提供以下合并策略:
覆盖:新的操作符实例使用相同的操作符替换同一字段上的任何现有条件。
相交:如果已经有一个条件在同一字段上使用了相同的操作符,则现有条件的值将与新条件的值相交,并将结果作为操作符值存储。
Union:如果同一字段上已存在使用相同运算符的条件,则新条件的值将添加到现有条件的值中,并将结果存储为运算符值。
以下代码使用 in
作为示例操作符,演示了合并策略如何生成条件:
Band.in(name: ['a']).override.in(name: ['b']) # Interpreted query: # {"name"=>{"$in"=>["b"]}} Band.in(name: ['a', 'b']).intersect.in(name: ['b', 'c']) # Interpreted query: # {"name"=>{"$in"=>["b"]}} Band.in(name: ['a']).union.in(name: ['b']) # Interpreted query: # {"name"=>{"$in"=>["a", "b"]}}
通过在 Criteria
实例上调用 override
、intersect
或 union
可请求该策略。所请求的策略适用于在查询中调用的下一个条件方法。如果调用的下一个条件方法不支持合并策略,则该策略将被重置,如以下示例所示:
Band.in(name: ['a']).union.ne(name: 'c').in(name: ['b']) # Interpreted query: # {"name"=>{"$in"=>["a"], "$ne"=>"c"}, "$and"=>[{"name"=>{"$in"=>["b"]}}]}
由于 ne
不支持合并策略,因此 union
策略将被忽略并重置。 然后,当第二次调用 in
时,就没有活动策略了。
警告
合并策略假定先前的条件已添加到查询的顶层。 但情况并非总是如此,因为条件可能会嵌套在 $and
子句下。 使用具有复杂条件的合并策略可能会生成不正确的查询。
支持的操作符方法
以下操作符方法支持合并策略:
all
in
nin
设立方法可能会在 Mongoid 的未来版本中得到扩展。 为了确保未来的兼容性,仅当下一个方法调用是支持合并策略的操作符时,才调用策略方法。
仅当通过指定方法添加条件时,才会应用合并策略。 在以下示例中,未应用合并策略,因为第二个条件是作为 where
添加的,而不是使用 in
:
Band.in(name: ['a']).union.where(name: {'$in' => 'b'}) # Interpreted query: # {"foo"=>{"$in"=>["a"]}, "$and"=>[{"foo"=>{"$in"=>"b"}}]}
操作符值扩展
支持合并策略的操作符方法将 Array
作为其值类型。 当与这些操作符方法一起使用时,Mongoid 会扩展与 Array
兼容的类型,例如 Range
。
以下示例演示了在使用 in
方法时如何传递 Range
对象作为查询值:
Band.in(year: 1950..1960) # Interpreted query: # {"year"=>{"$in"=>[1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960]}}
Mongoid 将非 Array
值包装在数组中,如以下示例所示:
Band.in(year: 1950) # Interpreted query: {"year"=>{"$in"=>[1950]}}
元素匹配
您可以使用 elem_match
方法,将包含大量字段的文档与至少一个与所有指定查询条件匹配的元素进行匹配。
以下示例创建一个包含大量字段的示例文档。 然后,它使用 elem_match
方法来匹配 tour
大量字段包含 city
值为 'London'
的条目的文档:
aerosmith = Band.create!(name: 'Aerosmith', tours: [ {city: 'London', year: 1995}, {city: 'New York', year: 1999}, ]) swans = Band.create!(name: 'Swans', tours: [ {city: 'Milan', year: 2014}, {city: 'Montreal', year: 2015}, ]) # Returns only "Aerosmith" Band.elem_match(tours: {city: 'London'})
关联
您可以使用 elem_match
方法来匹配嵌入式关联。
此示例使用以下模型来定义 Band
和 Tour
之间的嵌入式关联:
class Band include Mongoid::Document field :name, type: String embeds_many :tours end class Tour include Mongoid::Document field :city, type: String field :year, type: Integer embedded_in :band end
以下代码创建一个 Band
对象和嵌入式 Tour
对象,然后使用 elem_match
方法对 city
字段进行查询:
aerosmith = Band.create!(name: 'Aerosmith') Tour.create!(band: aerosmith, city: 'London', year: 1995) Tour.create!(band: aerosmith, city: 'New York', year: 1999) # Returns the "Aerosmith" document Band.elem_match(tours: {city: 'London'})
注意
不能在非嵌入式关联上使用 elem_match
,因为MongoDB不会对集合执行连接操作。 如果执行此查询,条件将添加到作为非嵌入式关联源的集合,而不是关联的集合。
您可以使用 elem_match
来查询递归嵌入的关联,如以下示例所示:
class Tag include Mongoid::Document field name:, type: String recursively_embeds_many end # Creates the root Tag root = Tag.create!(name: 'root') # Adds embedded Tags sub1 = Tag.new(name: 'sub_tag_1', child_tags: [Tag.new(name: 'sub_sub_tag_1')]) root.child_tags << sub1 root.child_tags << Tag.new(name: 'sub_tag_2') root.save! # Searches for Tag in which one child Tag tame is "sub_tag_1" Tag.elem_match(child_tags: {name: 'sub_tag_1'}) # Searches for a child Tag in which one child Tag tame is "sub_sub_tag_1" root.child_tags.elem_match(child_tags: {name: 'sub_sub_tag_1'})
按_id值查询
Mongoid 提供了 find
方法,允许您按 _id
值查询文档。
以下示例使用 find
方法将文档与指定的 _id
字段值进行匹配:
Band.find('6725342d4cb3e161059f91d7')
注意
类型转换
当您将ID值传递给 find
方法时,该方法会将其转换为为模型中的 _id
字段声明的数据类型。 默认下,_id
字段定义为 BSON::ObjectId
类型。
前面的示例相当于以下代码,它将 BSON::ObjectId
实例作为参数传递给 find
:
Band.find(BSON::ObjectId.from_string('5f0e41d92c97a64a26aabd10'))
如果您使用Ruby驾驶员对 _id
字段进行查询,find
不会在内部执行类型转换。
find
方法接受多个参数或参数大量。 Mongoid 将每个参数或大量元素解释为 _id
值,并返回大量中包含所有指定 _id
值的文档,如以下示例所示:
# Equivalent ways to match multiple documents Band.find('5f0e41d92c97a64a26aabd10', '5f0e41b02c97a64a26aabd0e') Band.find(['5f0e41d92c97a64a26aabd10', '5f0e41b02c97a64a26aabd0e'])
find
方法表现出以下行为:
如果多次提供相同的
_id
值,Mongoid 将仅返回一个文档(如果存在)。Mongoid 不会以有序的方式返回文档。 返回文档的顺序可能与提供的
_id
值的顺序不同。如果在数据库中找不到任何
_id
值,则结果取决于raise_not_found_error
配置选项的值。如果将
raise_not_found_error
选项设立为true
,则在未找到任何_id
值时,find
会引发Mongoid::Errors::DocumentNotFound
错误。如果您将
raise_not_found_error
选项设立为false
并查询单个_id
值,则当 Mongoid 与文档不匹配时,find
将返回nil
。 如果传递多个_id
值,而其中一些或全部不匹配,则返回值为所有匹配文档的大量,如果没有文档匹配,则返回值为空大量。
find Variations
本部分介绍与上一节所述 find
方法类似的方法。
您可以使用 find_by
方法根据提供的条件检索文档。 如果未找到文档,则会引发错误或返回 nil
,具体取决于您设立raise_not_found_error
配置选项的方式。
以下代码演示了如何使用 find_by
方法:
# Simple equality query Band.find_by(name: "Photek") # Performs an action on each returned result Band.find_by(name: "Tool") do |band| band.fans += 1 end
您可以使用 find_or_create_by
方法根据提供的条件检索文档。 如果未找到文档,则会创建并返回一个保存到MongoDB 的实例。
以下代码演示了如何使用 find_or_create_by
方法:
# If no matches, creates a Band with just the "name" field Band.find_or_create_by(name: "Photek") # If no matches, creates a Band with just the "name" field because the # query condition is not a literal Band.where(:likes.gt => 10).find_or_create_by(name: "Photek") # Creates a Band in which the name is Aerosmith because there is no # document in which "name" is Photek and Aerosmith at the same time Band.where(name: "Photek").find_or_create_by(name: "Aerosmith")
您可以使用 find_or_initialize_by
方法根据提供的条件检索文档。 如果未找到文档,则会返回一个新文档,而不会将其持久保存到MongoDB中。 对 find_or_initialize_by
使用与 find_or_create_by
方法相同的语法。
正则表达式
Mongoid 允许您在过滤条件中使用正则表达式来查询文档。
以下代码创建示例Band
模型:
Band.create!(name: 'Tame Impala', description: "Tame\nImpala is an American band")
您可以使用Ruby正则表达式执行查询,如以下代码所示:
# Matches documents in which the "name" field includes the string "impala" Band.where(name: /impala/i) # => Returns sample document
您还可以使用Perl兼容正则表达式 (PCRE) 语法和 BSON::Regexp::Raw
对象执行查询:
# Matches "description" values that start exactly with "Impala" Band.where(description: /\AImpala/) # => nil # Matches "description" values that start exactly with "Impala" Band.where(description: BSON::Regexp::Raw.new('^Impala')) # => nil # Matches "description" values that start exactly with "Impala" with # the multiline option Band.where(description: BSON::Regexp::Raw.new('^Impala', 'm')) # => Returns sample document
字段类型查询转换
当您指定对模型中定义的字段进行查询时,如果该字段具有指定的数据类型,则 Mongoid 会根据该字段的定义方式转换查询值。
请考虑以下 Album
模型定义,其中包含一个值为 Date
的字段、一个值为 Time
的字段和一个隐式值为 Object
的字段。 该模型还故意不定义名为 last_reviewed
的字段:
class Album include Mongoid::Document field :release_date, type: Date field :last_commented, type: Time field :last_purchased end
您可以使用 Date
和 Time
值对 release_date
和 last_commented
字段查询,如以下代码所示:
Album.where(release_date: Date.today) # Interpreted query: # {"release_date"=>2024-11-05 00:00:00 UTC} Album.where(last_commented: Time.now) # Interpreted query: # {"last_commented"=>2024-11-04 17:20:47.329472 UTC}
但是,如果在定义为其他类型的字段上仅使用 Date
值查询,则生成的查询将显示默认转换行为,如以下示例所示:
Album.where(last_commented: Date.today) # Interpreted query: # {"last_commented"=>Mon, 04 Nov 2024 00:00:00.000000000 EST -05:00} Album.where(last_purchased: Date.today) # Interpreted query: # {"last_purchased"=>"2024-11-04"} Album.where(last_reviewed: Date.today) # Interpreted query: # {"last_reviewed"=>2024-11-04 00:00:00 UTC}
在前面的示例中,应用了以下转换:
当使用
Date
值查询值为Time
的last_commented
字段时,Mongoid 会将日期解释为当地时间并应用配置的时区域。对没有显式类型的
last_purchased
字段进行查询时,将在构建的查询中不加修改地使用日期。在查询未定义的
last_reviewed
字段时,Mongoid 会将 UTC 格式的Date
解释为时间并转换为时间,这与查询release_date
等具有Date
值的字段的行为相匹配。
其他查询方法
本节介绍了可以在 Mongoid 中使用的更多查询方法。
计算文档
您可以使用 count
和 estimated_count
方法来计算集合中的文档数量。
您可以使用 count
方法计算符合过滤条件的文档数量:
# Counts all documents in collection Band.count # Counts documents that match criteria Band.where(country: 'England').count
提示
length 和 size 方法
您还可以使用 length
或 size
方法对文档进行计数。 这些方法缓存对数据库的后续调用,这可能会提高性能。
您可以使用 estimated_count
方法从集合元数据中获取集合中文档的大致数量:
Band.estimated_count
estimated_count
方法不接受查询条件,包括模型上的作用域设立的条件。如果在具有默认作用域的模型上调用此方法,则必须首先调用 unscoped
方法以禁用该作用域。
顺序方法
以下列表中描述的方法允许您根据位置从返回文档列表中选择特定结果。
first
:返回第一个匹配的文档。 您可以通过传递整数值参数来获取前n
个文档。 此方法会自动对_id
字段进行排序。 有关示例,请参阅以下代码中的第 - 行。18last
:返回最后一个匹配的文档。 您可以通过传递整数值参数来获取最后n
个文档。 此方法会自动对_id
字段进行排序。 11有关示例,请参阅以下代码中的第 行。first_or_create
:返回第一个匹配的文档。 如果没有匹配的文档,则创建并返回新保存的文档。first_or_initialize
:返回第一个匹配的文档。 如果没有匹配的文档,则返回一个新文档。second
:返回第二个匹配的文档。 自动对_id
字段进行排序。third
:返回第三个匹配文档。 自动对_id
字段进行排序。fourth
:返回第四个匹配文档。 自动对_id
字段进行排序。fifth
:返回第五个匹配文档。 自动对_id
字段进行排序。second_to_last
:返回倒数第二个匹配文档。 自动对_id
字段进行排序。 14有关示例,请参阅以下代码中的第 行。third_to_last
:返回倒数第三个匹配文档。 自动对_id
字段进行排序。
以下代码演示了如何使用前面列表中描述的某些方法:
1 # Returns the first document in the collection 2 Band.first 3 4 # Returns the first matching document 5 Band.where(founded: {'$gt' => 1980}).first 6 7 # Returns the first two matching documents 8 Band.first(2) 9 10 # Returns the last matching document 11 Band.where(founded: {'$gt' => 1980}).last 12 13 # Returns the second to last document 14 Band.second_to_last
提示
错误生成
本节中描述的每种方法都有一个以 !
为后缀的变体,如果 Mongoid 与任何文档都不匹配,该变体将返回错误。 示例,要在查询未返回结果时在应用程序中实现错误处理,请使用 first!
方法而不是 first
。
调查字段值
要检查集合中文档的指定字段的值,可以使用以下方法:
distinct
:获取单个字段的非重复值列表。 有关示例,请参阅以下代码中的第 - 行。17pick
:从一个文档中获取所提供字段的值。 对于未设置的字段和不存在的字段,返回nil
。 10有关示例,请参阅以下代码中的第 行。pluck
:获取所提供字段的所有值。 对于未设置的字段和不存在的字段,返回nil
。 13有关示例,请参阅以下代码中的第 行。tally
:获取指定字段的值与计数的映射。 16有关示例,请参阅以下代码中的第 行。
前面的方法接受使用点表示法引用的字段名称,这允许您引用嵌入式关联中的字段。 它们还遵循字段别名,包括嵌入式文档中定义的字段别名。
以下代码演示了如何使用这些方法:
1 Band.distinct(:name) 2 # Example output: "Ghost Mountain" "Hello Goodbye" "She Said" 3 4 Band.where(:members.gt => 2).distinct(:name) 5 # Example output: "Arctic Monkeys" "The Smiths" 6 7 Band.distinct('tours.city') 8 # Example output: "London" "Sydney" "Amsterdam" 9 10 Band.all.pick(:name) 11 # Example output: "The Smiths" 12 13 Band.all.pluck(:country) 14 # Example output: "England" "Spain" "England" "Japan" 15 16 Band.all.tally(:country) 17 # Example output: ["England",2] ["Italy",3]
其他
以下列表描述了不属于其他类别的 Mongoid 方法:
each
:遍历所有匹配的文档。
# Print each matching document "name" to console Band.where(:members.gt => 1).each do |band| p band.name end
exists?
:确定是否存在匹配的文档,如果找到至少一个匹配的文档,则返回true
。
# Checks existence of any document Band.exists? # Checks existence based on query Band.where(name: "Le Tigre").exists? Band.exists?(name: "Le Tigre") # Checks existence based on "_id" value Band.exists?('6320d96a3282a48cfce9e72c') # Always returns false Band.exists?(false) Band.exists?(nil)
更多信息
要学习;了解如何修改 Mongoid 返回结果的方式,请参阅修改查询结果。
要学习;了解有关在模型上定义范围的更多信息,请参阅范围界定。