Docs 菜单
Docs 主页
/ / /
Ruby MongoDB 驱动程序
/

排序规则(Collations)

在此页面上

  • Overview
  • 使用
  • 支持排序规则的操作

版本 3.4 中的新增功能

排序规则是指如何比较通常采用特定自然语言的字符串的规则集。

例如,在加拿大法语中,给定单词中的最后一个重音决定了排序顺序。

考虑以下法语单词:

cote < coté < côte < côté

使用加拿大法语排序规则的排序顺序将导致以下结果:

cote < côte < coté < côté

如果未指定排序规则,MongoDB 会对字符串使用简单的二进制比较。 因此,单词的排序顺序为:

cote < coté < côte < côté

您可以在创建collection和索引时为其指定默认排序规则,也可以为 CRUD 操作和聚合指定排序规则。 对于支持排序规则的操作,MongoDB 使用集合的默认排序规则,除非该操作指定了不同的排序规则。

'collation' => {
'locale' => <string>,
'caseLevel' => <bool>,
'caseFirst' => <string>,
'strength' => <int>,
'numericOrdering' => <bool>,
'alternate' => <string>,
'maxVariable' => <string>,
'normalization' => <bool>,
'backwards' => <bool>
}

唯一必需的参数是locale ,服务器会将其解析为 ICU 格式的区域设置 ID 。例如,将locale设置为en_US以代表美国英语,或将 fr_CA 设置为以代表加拿大法语。

有关可用参数的完整说明,请参阅MongoDB 手册条目。

以下示例在test数据库上创建了一个名为contacts的新集合,并指定了fr_CA区域设置的默认排序规则。 在创建集合时指定排序规则可确保针对contacts集合运行的所有涉及查询的操作都使用fr_CA排序规则,除非查询指定了其他排序规则。 除非创建命令指定了其他排序规则,否则新集合上的所有索引也会继承默认排序规则。

client = Mongo::Client.new([ "127.0.0.1:27017" ], :database => "test")
client[:contacts, { "collation" => { "locale" => "fr_CA" } } ].create

要为索引指定排序规则,请在创建索引时使用collation选项。

以下示例在启用unique参数并将默认排序规则将locale设置为en_US的情况下,在address_book集合的name字段上创建索引。

client = Mongo::Client.new([ "127.0.0.1:27017" ], :database => "test")
client[:address_book].indexes.create_one( { "first_name" => 1 },
"unique" => true,
"collation" => { "locale" => "en_US" }
)

要使用此索引,请确保您的查询也指定相同的排序规则。 以下查询使用上述索引:

client[:address_book].find({"first_name" : "Adam" },
"collation" => { "locale" => "en_US" })

以下查询使用索引。 第一个查询不使用排序规则,第二个查询使用的排序规则的strength值与索引排序规则不同。

client[:address_book].find({"first_name" : "Adam" })
client[:address_book].find({"first_name" : "Adam" },
"collation" => { "locale" => "en_US", "strength" => 2 })

所有读取、更新和删除方法都支持排序规则。 下面列出了一些示例。

单个查询可以指定对结果进行匹配和排序时使用的排序规则。 以下查询和排序操作使用德语排序规则,并将locale参数设置为de

client = Mongo::Client.new([ "127.0.0.1:27017" ], :database => "test")
docs = client[:contacts].find({ "city" => "New York" },
{ "collation" => { "locale" => "de" } }).sort( "name" => 1 )

名为 names 的集合包含以下文档:

{ "_id" : 1, "first_name" : "Hans" }
{ "_id" : 2, "first_name" : "Gunter" }
{ "_id" : 3, "first_name" : "Günter" }
{ "_id" : 4, "first_name" : "Jürgen" }

对collection执行的以下find_one_and_update操作未指定排序规则。

client = Mongo::Client.new([ "127.0.0.1:27017" ], :database => "test")
doc = client[:names].find_one_and_update( {"first_name" => { "$lt" => "Gunter" }},
{ "$set" => { "verified" => true } })

由于Gunter在collection中处于词法第一位,因此上述操作不会返回结果,也不会更新任何文档。

考虑相同的find_one_and_update操作,但指定了排序规则。 区域设置为de@collation=phonebook

注意

某些区域设置提供collation=phonebook选项,适用于以不同方式对专有名词和其他单词进行排序的语言。 根据de@collation=phonebook排序规则,带变音符号的字符位于不带变音符号的相同字符之前。

client = Mongo::Client.new([ "127.0.0.1:27017" ], :database => "test")
doc = client[:names].find_one_and_update( { "first_name" => { "$lt" => "Gunter" } },
{ "$set" => { "verified" => true } }, { "collation" => { "locale" => "de@collation=phonebook" },
:return_document => :after } )

该操作返回以下更新后的文档:

{ "_id" => 3, "first_name" => "Günter", "verified" => true }

numericOrdering排序规则参数设置为true ,以将数字字符串按其数值进行比较。

collection numbers 包含以下文档:

{ "_id" : 1, "a" : "16" }
{ "_id" : 2, "a" : "84" }
{ "_id" : 3, "a" : "179" }

以下示例匹配字段a的数值大于 100 的第一个文档并将其删除。

docs = numbers.find_one_and_delete({ "a" => { "$gt" => "100" } },
{ "collation" => { "locale" => "en", "numericOrdering" => true } })

完成上述操作后,集合中保留以下文档:

{ "_id" : 1, "a" : "16" }
{ "_id" : 2, "a" : "84" }

如果在没有排序规则的情况下执行相同的操作,服务器会删除它找到的第一个a词法值大于"100"的文档。

numbers = client[:numbers]
docs = numbers.find_one_and_delete({ "a" => { "$gt" => "100" } })

完成上述操作后, a等于"16"的文档已被删除,以下文档仍保留在collection中:

{ "_id" : 2, "a" : "84" }
{ "_id" : 3, "a" : "179" }

您可以将排序规则用于 Ruby 驱动程序中存在的所有各种批量操作。

collection recipes 包含以下文档:

{ "_id" : 1, "dish" : "veggie empanadas", "cuisine" : "Spanish" }
{ "_id" : 2, "dish" : "beef bourgignon", "cuisine" : "French" }
{ "_id" : 3, "dish" : "chicken molé", "cuisine" : "Mexican" }
{ "_id" : 4, "dish" : "chicken paillard", "cuisine" : "french" }
{ "_id" : 5, "dish" : "pozole verde", "cuisine" : "Mexican" }

将排序规则文档的strength参数设置为12会导致服务器在查询筛选器中忽略大小写。 以下示例使用不区分大小写的查询筛选器删除cuisine字段与French匹配的所有记录。

client = Mongo::Client.new([ "127.0.0.1:27017" ], :database => "test")
recipes = client[:recipes]
docs = recipes.delete_many({ "cuisine" => "French" },
"collation" => { "locale" => "en_US", "strength" => 1 })

运行上述操作后,将从collection中删除_id值为24的文档。

要将排序规则与聚合操作一起使用,请在聚合选项中指定排序规则。

以下聚合示例使用名为names的集合,并将first_name字段分组在一起,计算每组中的结果总数,并按德语电话簿顺序对结果进行排序。

aggregation = names.aggregate(
[
{
"$group" => { "_id" => "$first_name", "name_count" => { "$sum" => 1 } }
},
{
"$sort" => { "_id" => 1 }
},
], { "collation" => { "locale" => "de@collation=phonebook" } }
)
aggregation.each do |doc|
#=> Yields a BSON::Document.
end

后退

Atlas Search 索引