排序规则(Collations)
在此页面上
Overview
在本指南中,您可以了解如何使用排序规则按字符串值对查找或聚合操作结果进行排序。 排序规则是与特定语言和区域设置相对应的一组字符排序约定。
本指南包括以下部分:
MongoDB排序规则描述MongoDB如何根据默认排序规则和自定义排序规则对string值进行排序
指定排序规则描述了如何创建
Collation
结构体实例在集合上设置排序规则描述了如何为新集合设置排序规则
在索引上设置排序规则描述了如何为索引设立排序规则
对操作设置排序规则描述了如何将排序规则应用于某些 CRUD 操作
附加信息提供了本指南中提到的类型和方法的资源和 API 文档链接
MongoDB 排序规则
MongoDB 默认使用二进制排序规则对字符串进行排序。 此排序规则方法使用 ASCII 标准字符值对字符串进行比较和排序。 某些语言和区域设置具有与 ASCII 标准不同的特定字符排序约定。
提示
要学习;了解有关 ASCII 标准的更多信息,请参阅 ASCII 维基百科页面。
例如,在加拿大法语中,当其他字符相同时,最右边的重音字符决定字符串的顺序。 考虑以下加拿大法语单词:
cote
coté
côte
côté
使用默认的二进制排序规则时,MongoDB 按以下顺序对单词进行排序:
cote coté côte côté
在此排序顺序中,“coté”位于“côte”之前,因为 ASCII 标准将字符“o”置于字符“ô”之前。
使用加拿大法语排序规则时,MongoDB 按以下顺序对单词进行排序:
cote côte coté côté
在此排序顺序中,“coté”位于“côte”之后,因为加拿大法语排序规则将字符“e”置于字符“é”之前。
指定排序规则
您可以通过在Collation
结构实例中指定排序规则区域设置和其他选项来定义排序规则。 要开始构建Collation
实例,请调用Collation::builder()
方法。
注意
实例化结构
Rust驾驶员实现了用于创建某些结构体类型(包括Collation
的 Builder 设计模式。 您可以使用builder()
方法通过链接选项构建器方法来构造每种类型的实例。
下表描述了可用于设置Collation
实例字段的构建器方法。 您必须使用locale()
方法构建有效的Collation
结构体,但所有其他构建器方法都是可选的:
方法 | Possible Values | 说明 |
---|---|---|
locale() (Required) | Specifies the ICU locale | |
strength() | CollationStrength::Primary , CollationStrength::Secondary , CollationStrength::Tertiary , CollationStrength::Quaternary , CollationStrength::Identical | 指定要执行的比较级别 |
case_level() | true , false | Specifies whether the driver performs case comparison |
case_first() | CollationCaseFirst::Upper , CollationCaseFirst::Lower , CollationCaseFirst::Off | 指定三级比较期间大小写差异的排序顺序 |
numeric_ordering() | true , false | Specifies whether the driver compares numeric strings as numbers |
alternate() | CollationAlternate::NonIgnorable ,
CollationAlternate::Shifted | 指定驱动程序在字符串比较期间是否将空格和标点符号视为基本字符 |
max_variable() | CollationMaxVariable::Punct ,CollationMaxVariable::Space | Specifies which characters the driver ignores when alternate is set toCollationAlternate::Shifted |
normalization() | true , false | 指定驱动程序是否对字符串值执行文本规范化 |
backwards() | true , false | Specifies whether the driver sorts strings containing diacritics in reverse character order |
例子
以下示例指定一个Collation
实例并将排序规则区域设置设置为"en_US"
:
let collation = Collation::builder() .locale("en_US") .build();
对collection设置排序规则
创建新集合时,可以为将来对该集合调用的操作定义排序规则。 通过将collation()
函数链接到create_collection()
方法,将Collation
实例作为参数传递给collation()
来设置排序规则。
使用排序规则创建collection示例
此示例根据"fr"
(即法语)区域设置约定指定排序规则,并将该排序规则应用于名为books
的新collection。strength
字段设置为CollationStrength::Primary
以忽略变音符号的差异。
let collation = Collation::builder() .locale("fr") .strength(CollationStrength::Primary) .build(); let result = my_db.create_collection("books") .collation(collation) .await?;
排序规则排序演示
如果在books
集合上运行支持排序规则的操作,则该操作将使用前面使用排序规则创建集合示例中指定的排序规则。
假设books
集合包含以下文档:
{ "name" : "Emma", "length" : "474" } { "name" : "Les Misérables", "length": "1462" } { "name" : "Infinite Jest", "length" : "1104" } { "name" : "Cryptonomicon", "length" : "918" } { "name" : "Ça", "length" : "1138" }
提示
要学习;了解如何将文档插入集合,请参阅插入文档指南。
以下示例使用find()
方法返回name
字段的值按字母顺序位于"Infinite Jest"
之前的所有文档:
let query = doc! { "name": doc! { "$lt": "Infinite Jest" } }; let mut cursor = my_coll.find(query).await?; while let Some(doc) = cursor.try_next().await? { println!("{}", doc); }
{ "name": "Emma", "length": 474 } { "name": "Cryptonomicon", "length": 918 } { "name" : "Ça", "length" : "1138" }
如果没有为books
collection指定排序规则, find()
方法将遵循默认的二进制排序规则规则来确定"Infinite Jest"
之前的name
值。 这些规则将以“Ç”开头的单词放在以“I”开头的单词之后。 因此,当前面的查找操作遵循二进制排序规则规则时, name
值为"Ça"
的文档与筛选条件不匹配。
对索引设置排序规则
在collection上创建新索引时,可以为索引涵盖的操作定义排序规则。要运行使用索引及其排序规则的操作,操作和索引必须指定相同的排序规则。
提示
要了解有关索引和涵盖的查询的更多信息,请参阅索引指南。
使用collation()
函数构建IndexOptions
实例来设置索引排序规则。 然后,将IndexOptions
作为参数传递给IndexModel
构建器函数,并将IndexModel
作为参数传递给create_index()
方法。
例子
以下示例使用create_index()
方法在name
字段上创建升序索引,并指定与"en_US"
区域设置相对应的新排序规则:
let collation = Collation::builder() .locale("en_US") .build(); let index_opts = IndexOptions::builder() .collation(collation) .build(); let index = IndexModel::builder() .keys(doc! { "name": 1 }) .options(index_opts) .build(); let result = my_coll.create_index(index).await?; println!("Created index: {}", result.index_name);
Created index: name_1
为操作设置排序规则
从collection中读取、更新和删除文档的操作可以使用排序规则。 将排序规则应用于操作会覆盖之前为collection或索引定义的任何排序规则。
如果对操作应用的排序规则与索引的排序规则不同,则无法使用该索引。 因此,该操作的执行效率可能不如索引所涵盖的操作。 有关索引未涵盖的排序操作缺点的更多信息,请参阅服务器手册中的使用索引对查询结果进行排序。
例子
此示例将执行以下动作:
将
numeric_ordering
排序规则选项设置为true
,以确保值按数字顺序而不是字母顺序排序使用
find()
方法返回length
字段的值大于"1000"
的文档通过将
collation()
方法链接到find()
方法来指定排序规则,该方法会覆盖集合的排序规则
let collation = Collation::builder() .locale("en_US") .numeric_ordering(true) .build(); let filter = doc! { "length": doc! { "$gt": "1000" } }; let mut cursor = my_coll.find(filter) .collation(collation) .await?; while let Some(result) = cursor.try_next().await? { println!("{}", result); };
{ "name" : "Les Misérables", "length": "1462" } { "name" : "Infinite Jest", "length" : "1104" } { "name" : "Ça", "length" : "1138" }
如果您运行前面的查找操作而未将 numeric_ordering
选项设置为 true
,则驱动程序会将 length
值作为字符串进行比较,并将字符串值 "1000"
排序在值 "474"
和 "918"
之前。在这种情况下,上述查找操作返回 books
集合中的所有文档。
更多信息
要了解有关find()
方法的更多信息,请参阅检索数据指南。
要了解有关排序规则的更多信息,请参阅以下服务器手册页:
API 文档
要进一步了解本指南所提及的任何方法或类型,请参阅以下 API 文档: