对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

排序规则(Collations)

在本指南中,您可以了解如何使用排序规则按string值对查询或聚合操作结果进行排序。 排序规则是一组适用于特定语言和区域设置的字符排序约定。

MongoDB默认使用二进制排序规则对字符串进行默认。此排序规则方法使用ASCII 标准字符值对字符串进行比较和排序。某些语言和区域设置具有与 ASCII 标准不同的特定字符排序约定。

例如,在加拿大法语中,当其他字符相同时,最右边的重音字符决定字符串的顺序。 考虑以下加拿大法语单词:

  • cote

  • coté

  • côte

  • côté

使用默认的二进制排序规则时,MongoDB 按以下顺序对它们进行排序:

cote
coté
côte
côté

使用加拿大法语排序规则时,MongoDB 按以下顺序对它们进行排序:

cote
côte
coté
côté

要指定排序规则,请创建一个Collation对象。 您必须定义Collation对象的Locale字段;所有其他字段均为可选字段。 例如,以下代码示例指定具有"en_US"区域设置排序规则的Collation对象:

myCollation := &options.Collation{Locale: "en_US"}

For a complete list of Collation object fields, visit the Collation API documentation. To see all the supported locales and the default values for the Locale fields, visit Supported Languages and Locales.

创建新的集合或视图时,可以应用排序规则。 这定义了对该集合或视图调用的任何操作的默认排序规则。 通过CreateCollectionOptionsCreateViewOptions对象设置排序规则。 然后,将选项对象作为参数调用CreateCollection()CreateView()方法。

以下示例创建了一个名为books的新集合,并指定了具有"fr"区域设置的默认排序规则。 Strength排序规则字段的值为1 ,用于忽略字母重音的差异。

myCollation := &options.Collation{Locale: "fr", Strength: 1}
opts := options.CreateCollection().SetCollation(myCollation)
err := db.CreateCollection(context.TODO(), "books", opts)
if err != nil {
panic(err)
}

如果您在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"之前的所有文档:

filter := bson.D{{"name", bson.D{{"$lt", "Infinite Jest"}}}}
cursor, err := coll.Find(context.TODO(), filter)
if err != nil {
panic(err)
}
var results []bson.D
if err = cursor.All(context.TODO(), &results); err != nil {
panic(err)
}
for _, result := range results {
res, _ := bson.MarshalExtJSON(result, false, false)
fmt.Println(string(res))
}

如果不指定默认的books排序规则, Find()方法将遵循默认的二进制排序规则规则来确定"Infinite Jest"之前的name值。 这些规则将以“Ç”开头的单词放在以“I”开头的单词之后。 输出将类似于以下内容:

{"name":"Emma","length":"474"}
{"name":"Cryptonomicon","length":"918"}

要了解有关Find()方法的更多信息,请参阅检索数据。

在集合上创建新索引时,可以应用排序规则。 该索引会将文档的有序表示形式存储在集合中,因此 MongoDB 实例不会在内存中执行排序操作。

要在操作中使用索引,操作必须使用与索引中指定的排序规则相同的排序规则。 此外,请确保包含排序规则的索引涵盖该操作。 通过IndexOptions对象设置排序规则,并将该对象作为参数传递给CreateOne()方法。

创建books集合并应用默认排序规则后(如创建集合示例部分所示),您无法更改集合的默认排序规则。 但是,您可以使用不同的排序规则为集合创建索引。

以下示例使用CreateOne()方法在name字段上创建升序索引,并指定具有"en_US"区域设置的新排序规则:

myCollation := &options.Collation{Locale: "en_US"}
opts := options.Index().SetCollation(myCollation)
indexModel := mongo.IndexModel{
Keys: bson.D{{"name", 1}},
Options: opts,
}
name, err := coll.Indexes().CreateOne(context.TODO(), indexModel)
if err != nil {
panic(err)
}
fmt.Println("Name of Index Created: " + name)

从集合中读取、更新和删除文档的操作可以使用排序规则。 将排序规则应用于操作会覆盖之前为集合定义的任何默认排序规则。

如果对操作应用的新排序规则不同于索引的排序规则,则无法使用该索引。 因此,该操作的性能可能不如索引所涵盖的操作。 有关索引未涵盖的排序操作缺点的更多信息,请参阅使用索引对查询结果进行排序。 有关支持排序规则的操作列表,请参阅MongoDB 手册

您可以使用支持排序规则的操作来更新和查询books集合中的文档。

以下示例使用Find()方法返回length值大于"1000"的文档。 NumericOrdering排序规则字段的值为true ,以确保值按数字顺序而不是字母顺序排序:

filter := bson.D{{"length", bson.D{{"$gt", "1000"}}}}
myCollation := &options.Collation{Locale: "en_US", NumericOrdering: true}
opts := options.Find().SetCollation(myCollation)
cursor, err := coll.Find(context.TODO(), filter, opts)
if err != nil {
panic(err)
}
var results []bson.D
if err = cursor.All(context.TODO(), &results); err != nil {
panic(err)
}
for _, result := range results {
res, _ := bson.MarshalExtJSON(result, false, false)
fmt.Println(string(res))
}

在不指定排序规则且将NumericOrdering字段设置为true的情况下,相同的Find()操作会将length值作为字符串进行比较。 在这种情况下,输出如下所示:

{"name":"Emma","length":"474"}
{"name":"Les Misérables","length":"1462"}
{""name":"Infinite Jest","length":"1104"}
{"name":"Cryptonomicon","length":"918"}
{"name":"Ça","length":"1138"}

要了解有关Find()方法的更多信息,请参阅检索数据指南。

要了解有关排序规则的更多信息,请访问以下手册页:

要进一步了解本指南中讨论的方法,请参阅以下 API 文档: