文档菜单
文档首页
/ / /
Node.js 驱动
/

排序规则

在本页

  • 概述
  • 用法
  • 排序参数
  • 排序示例
  • 在集合上设置默认排序
  • 将排序分配给索引
  • 排序查询示例

从MongoDB 3.4版开始支持排序。

本指南展示了如何使用 排序规则,一组排序规则,以特定语言和地区(一个共享共同语言习语的社区或地区)的字符串排序来运行操作。

默认情况下,MongoDB使用 二进制排序 对字符串进行排序。此排序方法使用ASCII标准 字符值来比较和排序字符串。语言和地区有特定的字符排序惯例,与ASCII标准不同。

例如,在加拿大法语中,最右侧的重音字符决定了当其他字符相同时字符串的排序。考虑以下法语单词: cotecotécôte,和 côté

MongoDB使用默认的二进制排序按以下顺序对它们进行排序

cote
coté
côte
côté

MongoDB使用加拿大法语排序按以下顺序对它们进行排序

cote
côte
coté
côté

在创建新的集合或索引时,您可以指定排序规则。您还可以为CRUD操作和聚合指定排序规则。

当您使用排序规则创建新集合时,您定义了在该集合上调用任何支持排序规则的操作的默认排序规则。您可以通过指定不同的排序规则来覆盖操作的排序规则。

注意

目前,您无法在现有集合上创建排序规则。要使用现有集合的排序规则,请创建具有排序规则的索引,并在该索引上的操作中指定相同的排序规则。

当您使用排序规则创建索引时,您指定了使用该索引的操作的排序顺序。为了在索引中使用排序规则,您必须在操作中提供匹配的排序规则,并且操作必须使用该索引。尽管大多数索引类型支持排序规则,但以下类型仅支持二进制比较

  • text

  • 2d

  • geoHaystack

排序规则对象包含以下参数

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

您必须指定locale字段在排序规则中;其他所有字段都是可选的。有关受支持的区域设置和locale字段的默认值的完整列表,请参阅受支持的语言和区域设置。有关每个字段的说明,请参阅MongoDB手册中的排序规则文档

以下示例中,我们创建了一个名为 souvenirs 的新集合,并使用 "fr_CA" 区域设置分配了默认比较规则。该比较规则应用于对该集合执行的所有支持比较的操作。

db.createCollection("souvenirs", {
collation: { locale: "fr_CA" },
});

支持比较规则的操作会自动应用集合上定义的比较规则。以下查询搜索 souvenirs 集合并应用 "fr_CA" 区域设置的比较规则

myColl.find({type: "photograph"});

您可以在支持比较规则的操作中指定不同的比较规则作为参数。以下查询指定了 "is" 冰岛区域设置以及带有值为 "upper"caseFirst 可选参数

myColl.find({type: "photograph"},
{ collation: { locale: "is", caseFirst: "upper" } }
);

以下示例中,我们在一个集合的 title 字段上创建了一个新的索引,并将排序规则设置为 "en_US"

myColl.createIndex(
{ 'title' : 1 },
{ 'collation' : { 'locale' : 'en_US' } });

以下查询使用了我们创建的索引

myColl.find({"year": 1980}, {"collation" : {"locale" : "en_US" }})
.sort({"title": -1});

以下查询 没有 使用我们创建的索引。第一个查询没有包含排序规则,第二个查询包含的强度值与索引上的排序规则不同。

myColl.find({"year": 1980}, {"collation" : {"locale" : "en_US", "strength": 2 }})
.sort({"title": -1});
myColl.find({"year": 1980})
.sort({"title": -1});

读取、更新和删除集合中文档的操作可以使用排序规则。本节包括这些操作的示例。有关支持排序规则的操作的完整列表,请参阅 MongoDB 手册:支持排序规则的操作。

以下示例在一个使用默认二进制排序的集合上调用find()sort()。我们通过将locale参数的值设置为"de"来使用德语排序。

myColl.find({ city: "New York" }, { collation: { locale: "de" } })
.sort({ name: 1 });

以下示例在一个使用默认二进制排序的集合上调用findOneAndUpdate()操作。该集合包含以下文档

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

考虑以下在集合上进行的findOneAndUpdate()操作,它没有指定排序

myColl.findOneAndUpdate(
{ first_name : { $lt: "Gunter" } },
{ $set: { verified: true } }
);

由于使用二进制排序时,“Gunter”是第一个排序结果,因此没有任何文档在字典上位于其之前并匹配查询文档中的$lt比较运算符。因此,该操作没有更新任何文档。

考虑使用指定为de@collation=phonebook的排序以及本地设置为de@collation=phonebook的相同操作。此区域指定了collation=phonebook选项,它包含优先排序专有名词的规则,这些专有名词通过首字母的大写来识别。在de@collation=phonebook区域和选项中,带重音符号的字符排序在相同不带重音符号的字符之前。

myColl.findOneAndUpdate(
{ first_name: { $lt: "Gunter" } },
{ $set: { verified: true } },
{ collation: { locale: "de@collation=phonebook" } },
);

由于使用在findOneAndUpdate()中指定的de@collation=phonebook排序,“Günter”在字典上位于“Gunter”之前,该操作返回以下更新后的文档

{ lastErrorObject: { updatedExisting: true, n: 1 },
value: { _id: 3, first_name: 'Günter' },
ok: 1 }

以下示例在一个使用默认二进制排序并包含以下文档的集合上调用findOneAndDelete()操作

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

在此示例中,我们将numericOrdering排序参数设置为true,以根据数字顺序而不是字典顺序对数字字符串进行排序。

myColl.findOneAndDelete(
{ a: { $gt: "100" } },
{ collation: { locale: "en", numericOrdering: true } },
);

运行上述操作后,集合包含以下文档

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

如果您在对三个文档原始集合进行相同操作而不进行排序时,它会根据字符串的词汇值("16""84""179")匹配文档,并删除第一个符合查询条件的文档。

await myColl.findOneAndDelete({ a: { $gt: "100" } });

由于所有文档在 a 字段中包含的词汇值都符合条件(大于 "100" 的词汇值),该操作删除了第一个结果。执行上述操作后,集合包含以下文档

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

要在 aggregate 操作中使用排序,请在管道阶段数组之后传递排序文档到选项字段。

以下示例显示了一个在默认二进制排序上运行的集合的聚合管道。该聚合按 first_name 字段分组,计算每个组的总结果数,并按德语电话簿("de@collation=phonebook" 区域)排序。

注意

在聚合中只能指定一个排序。

myColl.aggregate(
[
{ $group: { "_id": "$first_name", "nameCount": { "$sum": 1 } } },
{ $sort: { "_id": 1 } },
],
{ collation: { locale: "de@collation=phonebook" } },
);

返回

索引