排序规则
排序规则允许用户为字符串比较指定特定于语言的规则,例如字母大小写和重音符号规则。
您可以为集合、视图、索引或支持排序规则的特定操作指定排序规则。
要在 MongoDB Atlas 用户界面中查询文档时指定排序规则,请参阅 指定排序规则。
排序规则文档
排序规则文档包含以下字段:
{ locale: <string>, caseLevel: <boolean>, caseFirst: <string>, strength: <int>, numericOrdering: <boolean>, alternate: <string>, maxVariable: <string>, backwards: <boolean> }
指定排序规则时,locale
字段为必填字段;所有其他排序规则字段均为可选字段。有关字段说明,请参阅排序规则文档。
默认排序规则参数值根据您指定的区域设置而异。有关默认排序规则参数及其关联区域设置的完整列表,请参阅排序规则默认参数。
字段 | 类型 | 说明 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
locale | 字符串 | ICU 语言环境。有关支持的语言环境列表,请参阅支持的语言和语言环境。 要指定简单的二进制比较,请指定 | ||||||||||||
strength | 整型 | 可选。要执行的比较级别。对应于 ICU 比较级别。可能的值为:
有关详细信息,请参阅 ICU 排序规则:比较级别。 | ||||||||||||
caseLevel | 布尔 | 可选。此标志用于确定是否在 如果其值为
如果其值为 有关更多信息,请参阅 ICU 排序规则:大小写级别。 | ||||||||||||
caseFirst | 字符串 | 可选。此字段用于确定第三级比较期间大小写差异的排序顺序。 可能的值为:
| ||||||||||||
numericOrdering | 布尔 | 可选。此标志用于确定是将数字字符串作为数字还是字符串来比较。 如果其值为 如果其值为 默认值为 | ||||||||||||
alternate | 字符串 | 可选。此字段用于确定排序规则是否应将空格和标点符号视为基本字符来比较。 可能的值为:
有关更多信息,请参阅 ICU 排序规则:比较级别。 默认值为 | ||||||||||||
maxVariable | 字符串 | 可选。此字段用于确定在 可能的值为:
| ||||||||||||
backwards | 布尔 | 可选。此标志用于确定带有变音符号的字符串是否从字符串后面进行排序,例如某些法语词典排序。 如果 如果 默认值为 | ||||||||||||
normalization | 布尔 | 可选。此标志用于确定是否检查文本是否需要规范化并执行规范化。通常,大多数文本都不需要这种规范化处理。 如果 如果 默认值为 有关详细信息,请参阅 https://unicode-org.github.io/icu/userguide/collation/concepts.html#normalization。 |
支持排序规则的操作
您可以为以下操作指定排序规则:
注意
您不能为一个操作指定多个排序规则。例如,您不能为每个字段指定不同的排序规则,或者如果执行带排序的查找,则不能使用一种排序规则进行查找而另一种排序规则进行排序。
命令 | mongosh 方法 |
---|---|
db.collection.bulkWrite() 中的单独更新、替换和删除操作。 |
[1] | (1, 2) 某些索引类型不支持排序规则。有关详细信息,请参阅排序规则和不支持的索引类型。 |
行为
本地变体
某些排序规则语言环境会有一些变体,这些变体采用特定于语言的特殊规则。若要指定语言环境变体,请使用以下语法:
{ "locale" : "<locale code>@collation=<variant>" }
例如,若要使用中文排序规则的 unihan
变体:
{ "locale" : "zh@collation=unihan" }
有关所有排序规则语言环境及其变体的完整列表,请参阅排序规则语言环境。
排序规则和视图
您可以在创建视图时为其指定默认排序规则。如果未指定排序规则,视图的默认排序规则则为“简易”二进制比较排序规则。也就是说,视图不会继承集合的默认排序规则。
视图上的字符串比较使用的是视图的默认排序规则。尝试更改或覆盖视图默认排序规则的操作会失败并报错。
如果从另一个视图创建视图,则无法指定与源视图不同的排序规则。
如果执行的聚合涉及多个视图(如使用
$lookup
或$graphLookup
),则这些视图必须具有相同的排序规则。
排序规则和索引使用
要使用索引进行字符串比较,操作还必须指定相同的排序规则。换言之,如果一个操作对索引字段进行字符串比较,但又设定了与索引字段不同的排序规则,那么这个设有排序规则的索引将无法支持该操作。
警告
由于配置了排序规则的索引是通过 ICU 排序规则键来实现排序,因此,相比未配置排序规则的索引的索引键,有排序规则感知的索引键可能会更大。
例如,集合 myColl
在字符串字段 category
上具有一个索引,排序规则语言环境为 "fr"
。
db.myColl.createIndex( { category: 1 }, { collation: { locale: "fr" } } )
以下查询操作指定了与索引相同的排序规则,因此可以使用索引:
db.myColl.find( { category: "cafe" } ).collation( { locale: "fr" } )
而以下查询操作默认使用“简易的”二进制排序器,因此无法使用索引:
db.myColl.find( { category: "cafe" } )
如果一个复合索引的前缀键不是字符串、数组和嵌入式文档,在这种情况下,即使查询操作指定了一个与索引不同的排序规则,它仍然可以利用该复合索引来支持对其前缀健的比较。
例如,集合 myColl
在数值字段 score
和 price
以及字符串字段 category
上有一个复合索引;该索引使用排序规则语言环境 "fr"
创建,用于进行字符串比较:
db.myColl.createIndex( { score: 1, price: 1, category: 1 }, { collation: { locale: "fr" } } )
以下操作使用 "simple"
二进制排序规则进行字符串比较,它们可以使用索引:
db.myColl.find( { score: 5 } ).sort( { price: 1 } ) db.myColl.find( { score: 5, price: { $gt: NumberDecimal( "10" ) } } ).sort( { price: 1 } )
以下操作使用 "simple"
二进制排序规则对索引的 category
字段进行字符串比较,它们可以使用索引仅完成查询的 score: 5
部分:
db.myColl.find( { score: 5, category: "cafe" } )
重要
与文档键(包括嵌入式文档键)的匹配使用简单的二进制比较。这意味着类似“foo.bár”的键的查询不会匹配“foo.bar”键,无论您为 strength 参数设置了什么值。
排序规则和不支持的索引类型
以下索引只支持简单的二进制比较,不支持排序规则:
提示
要在具有非简单排序规则的集合上创建 text
或 2d
索引,您必须在创建索引时显式指定 {collation:
{locale: "simple"} }
。
限制
numericOrdering
当将 numericOrdering
指定为 true
时,适用以下限制:
在比较中,仅考虑数字的连续非负整数子字符串。
numericOrdering
不支持:+
-
小数分隔符,如小数点和小数点逗号
指数
只有数字或十进制数字 (Nd) 类别中的 Unicode 代码点才被视为数字。
如果数字长度超过 254 个字符,则超出的字符将被视为单独的数字。
请考虑一个具有以下字符串数字和十进制值的集合:
db.c.insertMany( [ { "n" : "1" }, { "n" : "2" }, { "n" : "2.1" }, { "n" : "-2.1" }, { "n" : "2.2" }, { "n" : "2.10" }, { "n" : "2.20" }, { "n" : "-10" }, { "n" : "10" }, { "n" : "20" }, { "n" : "20.1" } ] )
以下 find
查询使用包含 numericOrdering
参数的排序规则文档:
db.c.find( { }, { _id: 0 } ).sort( { n: 1 } ).collation( { locale: 'en_US', numericOrdering: true } )
操作返回以下结果:
[ { n: '-2.1' }, { n: '-10' }, { n: '1' }, { n: '2' }, { n: '2.1' }, { n: '2.2' }, { n: '2.10' }, { n: '2.20' }, { n: '10' }, { n: '20' }, { n: '20.1' } ]
numericOrdering: true
按升序对字符串值进行排序(类似于对数字值的排序)。两个负值
-2.1
和-10
没有按照预期的排序顺序进行排序,因为它们包含不支持的-
字符。由于
numericOrdering
参数不支持十进制值,因此值2.2
排序在值2.10
之前。因此,
2.2
和2.10
按字典顺序进行排序。