“文档” 菜单
文档首页
/
MongoDB Manual
/

排序规则

在此页面上

  • 排序规则文档
  • 支持排序规则的操作
  • 行为
  • 限制

排序规则允许用户为字符串比较指定特定于语言的规则,例如字母大小写和重音符号规则。

您可以为集合、视图、索引或支持排序规则的特定操作指定排序规则。

要在 MongoDB Atlas 用户界面中查询文档时指定排序规则,请参阅 指定排序规则

排序规则文档包含以下字段:

{
locale: <string>,
caseLevel: <boolean>,
caseFirst: <string>,
strength: <int>,
numericOrdering: <boolean>,
alternate: <string>,
maxVariable: <string>,
backwards: <boolean>
}

指定排序规则时,locale 字段为必填字段;所有其他排序规则字段均为可选字段。有关字段说明,请参阅排序规则文档

默认排序规则参数值因指定的区域设置而异。有关默认排序规则参数及其关联区域设置的完整列表,请参阅排序规则默认参数。

字段
类型
说明
locale
字符串

ICU 语言环境。有关支持的语言环境列表,请参阅支持的语言和语言环境

要指定简单的二进制比较,请指定 "simple"locale 值。

strength
整型

可选。要执行的比较级别。对应于 ICU 比较级别。可能的值为:

说明
1
主要比较级别。排序规则仅对基本字符进行比较,忽略其他差异,例如变音符号和大小写。
2
次要比较级别。排序规则会比较次要差异,例如变音符号。也就是说,排序规则会执行基本字符(主要差异)和变音符号(次要差异)的比较。基本字符之间的差异优先于次要差异。
3

第三级比较。排序规则会比较第三级差异,例如大小写和字母变体。也就是说,排序规则执行基本字符(主要差异)比较、变音符号(次要差异)比较以及大小写和字母变体(第三级差异)比较。基本字符之间的差异优先于次要差异,而次要差异又优先于第三级差异。

这是默认级别。

4
第四级。仅限于特定使用场景,可考虑前三个级别忽略的标点符号,或者用于处理日语文本。
5
等同级别。仅限于无法比较出差异的特定用例。

请参阅 ICU 排序规则:比较级别 了解详细信息。

caseLevel
布尔

可选。此标志用于确定是否在 strength 级别为 12 时进行大小写比较。

如果其值为 true,则包括大小写比较:

  • 当与 strength:1 一起使用时,排序规则会比较基本字符和大小写。

  • 当与 strength:2 一起使用时,排序规则会比较基本字符、变音符号(以及可能的其他次要差异)和大小写。

如果其值为 false,则在 1 级别或 2 级别不不包括大小写比较。默认值为 false

有关详细信息,请参阅 ICU 排序规则:大小写级别

caseFirst
字符串

可选。此字段用于确定第三级比较期间大小写差异的排序顺序。

可能的值为:

说明
"upper"
大写字母排序在小写字母之前。
"lower"
小写字母排序在大写字母之前。
"off"
默认值。与 "lower" 类似,但略有不同。请参阅 https://unicode-org.github.io/icu/userguide/strings/properties.html#customization 了解差异的详细信息。
numericOrdering
布尔

可选。此标志用于确定是将数字字符串作为数字还是字符串来比较。

如果其值为 true,则作为数字进行比较。例如,"10" 大于 "2"

如果其值为 false,则作为字符串进行比较。例如,"10" 小于 "2"

默认值为 false

参见 numericOrdering 限制

alternate
字符串

可选。此字段用于确定排序规则是否应将空格和标点符号视为基本字符来比较。

可能的值为:

说明
"non-ignorable"
空格和标点符号均被视为基本字符。
"shifted"
空格和标点符号不被视为基本字符,并且仅在强度级别大于 3 时才能区分。

请参阅 ICU 排序规则:比较级别 以了解更多信息。

默认值为 "non-ignorable"

maxVariable
字符串

可选。此字段用于确定在 alternate: "shifted" 时哪些字符会被视为可忽略的字段。如果 alternate: "non-ignorable",则无效

可能的值为:

说明
"punct"
空格和标点符号均可忽略,并且不被视为基本字符。
"space"
空格可以忽略,并且不被视为基本字符。
backwards
布尔

可选。此标志用于确定带有变音符号的字符串是否从字符串后面进行排序,例如某些法语词典排序。

如果 true,则从后往前进行比较。

如果 false,则从前往后进行比较。

默认值为 false

normalization
布尔

可选。此标志用于确定是否检查文本是否需要规范化并执行规范化。通常,大多数文本都不需要这种规范化处理。

如果 true,则检查是否需要完全规范化并执行规范化以比较文本。

如果 false,则不进行检查。

默认值为 false

有关详细信息,请参阅 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 在数值字段 scoreprice 以及字符串字段 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 参数设置了什么值。

以下索引只支持简单的二进制比较,不支持排序规则:

提示

要在具有非简单排序规则的集合上创建text2dgeoHaystack索引,您必须在创建索引时显式指定{collation: {locale: "simple"} }

当将 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.22.10 按字典顺序进行排序。

← 参考