排序规则
概述
在本指南中,您可以学习如何使用 排序规则 来根据字符串值对您的查找或聚合操作结果进行排序。排序规则是一组与特定语言和区域设置相对应的字符排序约定。
本指南包括以下部分
MongoDB 排序规则 描述了 MongoDB 如何根据默认排序规则和自定义排序规则对字符串值进行排序
指定排序规则 描述了如何创建一个
排序规则
结构实例在集合上设置排序规则 描述了如何为新集合设置排序规则
在索引上设置排序规则 描述了如何设置索引的排序规则
在操作上设置排序规则 描述了如何将排序规则应用于特定的 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驱动程序实现了Builder设计模式以创建某些结构体类型,包括Collation
。您可以使用builder()
方法通过链式选项构建器方法构建每种类型的实例。
以下表格描述了您可以用来设置Collation
实例字段的构建器方法。您必须使用locale()
方法来构建一个有效的Collation
结构体,但所有其他构建器方法是可选的
方法 | 可能值 | 描述 |
---|---|---|
locale() (必需) | 指定 ICU 区域 | |
strength() | CollationStrength::Primary ,CollationStrength::Secondary ,CollationStrength::Tertiary ,CollationStrength::Quaternary ,CollationStrength::Identical | 指定要执行的比较级别 |
case_level() | true ,false | 指定驱动器是否执行大小写比较 |
case_first() | CollationCaseFirst::Upper ,CollationCaseFirst::Lower ,CollationCaseFirst::Off | 指定在三级比较中比较大小差异的排序顺序 |
numeric_ordering() | true ,false | 指定驱动器是否将数字字符串作为数字进行比较 |
alternate() | CollationAlternate::NonIgnorable ,CollationAlternate::Shifted | 指定驱动器在字符串比较中是否将空白和标点符号视为基字符 |
max_variable() | CollationMaxVariable::Punct ,CollationMaxVariable::Space | 指定当 alternate 设置为时,驱动器忽略的字符CollationAlternate::Shifted |
normalization() | true ,false | 指定驱动器是否对字符串值执行文本规范化 |
backwards() | true ,false | 指定驱动器是否按逆字符顺序对包含重音符号的字符串进行排序 |
示例
以下示例指定了一个 Collation
实例并将排序区域设置为 "en_US"
let collation = Collation::builder() .locale("en_US") .build();
在集合上设置排序
当您创建一个新的集合时,您可以定义用于该集合后续操作的比较规则。通过将collation()
函数链接到create_collection()
方法,并将您的Collation
实例作为参数传递给collation()
来设置比较规则。
带有比较规则的创建集合示例
此示例根据“fr”(法语)区域约定指定比较规则,并将比较规则应用于名为“books”的新集合。将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
集合指定排序规则,则 find()
方法将遵循默认的二进制排序规则来确定在 "Infinite Jest"
之前出现的 name
值。这些规则将单词以 "Ç" 开头的情况排在以 "I" 开头的情况之后。因此,当先前的查找操作遵循二进制排序规则时,其中 name
值为 "Ça"
的文档不匹配过滤条件。
在索引上设置排序规则
当您在集合上创建新索引时,您可以定义由索引覆盖的操作的排序规则。要运行使用索引及其排序规则的操作,您的操作和索引必须指定相同的排序规则。
提示
有关索引和覆盖查询的更多信息,请参阅 索引 指南。
使用 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
在操作上设置排序规则
可以从集合中读取、更新和删除文档的操作可以使用排序规则。将排序规则应用于操作将覆盖集合或索引之前定义的任何排序规则。
如果您将排序规则应用于与索引排序规则不同的操作,则无法使用该索引。因此,该操作可能不如索引覆盖的操作高效。有关未由索引覆盖的排序操作的不利因素的信息,请参阅服务器手册中的使用索引对查询结果进行排序。
示例
此示例执行以下操作
将
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
的情况下运行前面的 find 操作,驱动程序会将 length
值作为字符串进行比较,并将字符串值 "1000"
排在值 "474"
和 "918"
之前。在这种情况下,前面的 find 操作将返回 books
集合中的所有文档。
附加信息
要了解更多关于 find()
方法的知识,请参阅检索数据指南。
要了解更多关于排序的信息,请参阅以下服务器手册页面
API 文档
要了解更多关于本指南中提到的任何方法或类型,请参阅以下API文档