简介
在显示或检索数据时进行排序是大多数数据库系统的关键操作,这有助于将它们与其他数据存储机制区分开来。能够独立于其存储的顺序来操作各种字段的排序、优先级和解释是数据库本身及其相关查询系统最 H 有用的功能之一。
MongoDB 提供了多种控制查询返回数据排序方式的方法。在本指南中,我们将根据您的用例,介绍如何以多种方式对数据进行排序。我们将讲解简单排序和复合排序、如何更改排序顺序,以及排序如何与其他操作符结合使用。
当将 Prisma Client 与 MongoDB 连接器一起使用时,您可以使用 orderBy
API 对结果进行排序。
文档中包含了如何使用此功能以多种灵活方式对结果进行排序的概述。
设置示例数据
为了演示排序的工作原理,我们将查询 students
集合中包含的多个文档。您可以通过复制粘贴以下内容来创建 students
集合并插入我们将要查询的文档
db.students.insertMany([{first_name: 'Carol',last_name: 'Apple',dob: ISODate('2010-10-30'),address: {street: {name: 'Flint Rd.',number: '803',},city: 'Camden',zip: '10832',},},{first_name: 'Spencer',last_name: 'Burton',dob: ISODate('2008-12-04'),address: {street: {name: 'Edgecombe St.',number: '2083b',},city: 'Zoofreid',zip: '80828',},},{first_name: 'Nixie',last_name: 'Languin',dob: ISODate('2011-02-11'),address: {street: {name: 'Kensington Ln.',number: '33',},city: 'Zoofreid',zip: '80829',},},{first_name: 'Anthony',last_name: 'Apple',dob: ISODate('2009-08-16'),address: {street: {name: 'Flint Rd.',number: '803',},city: 'Camden',zip: '10832',},},{first_name: 'Rose',last_name: 'Southby',dob: ISODate('2011-03-03'),address: {street: {name: 'Plainfield Dr.',number: '4c',},city: 'Nambles',zip: '38008',},},{first_name: 'Lain',last_name: 'Singh',dob: ISODate('2013-06-22'),address: {street: {name: 'Plainfield Dr.',number: '308',},city: 'Brighton',zip: '18002',},},])
插入上述文档后,继续下一节了解简单排序。
如何对单个字段排序
在 MongoDB 中对结果进行排序的基本方法是将 .sort()
方法附加到查询上。.sort()
方法将一个文档作为参数,指定要排序的字段以及排序方向。
最基本的排序方法是提供一个文档,指定一个字段,该字段指示列名,其值为 1
表示升序排序
请注意,我们正在将一个 MongoDB 投影 作为
.find()
的第二个参数,以便只显示某些字段。我们还附加了.pretty()
方法,使输出更具可读性。
db.students.find({},{_id: 0,first_name: 1,last_name: 1,dob: 1,}).sort({dob: 1,}).pretty()
上述查询将按学生的出生日期以默认的升序返回结果
{"first_name" : "Spencer","last_name" : "Burton","dob" : ISODate("2008-12-04T00:00:00Z")}{"first_name" : "Anthony","last_name" : "Apple","dob" : ISODate("2009-08-16T00:00:00Z")}{"first_name" : "Carol","last_name" : "Apple","dob" : ISODate("2010-10-30T00:00:00Z")}{"first_name" : "Nixie","last_name" : "Languin","dob" : ISODate("2011-02-11T00:00:00Z")}{"first_name" : "Rose","last_name" : "Southby","dob" : ISODate("2011-03-03T00:00:00Z")}{"first_name" : "Lain","last_name" : "Singh","dob" : ISODate("2013-06-22T00:00:00Z")}
要反转排序,请将排序列设置为 -1
而不是 1
db.students.find({},{_id: 0,first_name: 1,last_name: 1,dob: 1,}).sort({dob: -1,}).pretty()
{"first_name" : "Lain","last_name" : "Singh","dob" : ISODate("2013-06-22T00:00:00Z")}{"first_name" : "Rose","last_name" : "Southby","dob" : ISODate("2011-03-03T00:00:00Z")}{"first_name" : "Nixie","last_name" : "Languin","dob" : ISODate("2011-02-11T00:00:00Z")}{"first_name" : "Carol","last_name" : "Apple","dob" : ISODate("2010-10-30T00:00:00Z")}{"first_name" : "Anthony","last_name" : "Apple","dob" : ISODate("2009-08-16T00:00:00Z")}{"first_name" : "Spencer","last_name" : "Burton","dob" : ISODate("2008-12-04T00:00:00Z")}
如何对附加字段排序
当主排序字段包含重复项时,MongoDB 可以使用附加字段来控制排序。为此,您可以在传递给 sort()
函数的文档中传递额外的字段及其排序顺序。
例如,如果按 last_name
对 student
文档进行排序,我们可以根据该字段获得按字母顺序排列的学生列表
db.students.find({},{_id: 0,first_name: 1,last_name: 1,}).sort({last_name: 1,}).pretty()
{ "first_name" : "Carol", "last_name" : "Apple" }{ "first_name" : "Anthony", "last_name" : "Apple" }{ "first_name" : "Spencer", "last_name" : "Burton" }{ "first_name" : "Nixie", "last_name" : "Languin" }{ "first_name" : "Lain", "last_name" : "Singh" }{ "first_name" : "Rose", "last_name" : "Southby" }
但是,有两个学生的姓氏都是“Apple”,并且在考虑他们的名字时,返回的顺序不是按字母顺序排列的。
为了解决这个问题,我们可以使用 first_name
作为次要排序字段
db.students.find({},{_id: 0,first_name: 1,last_name: 1,}).sort({last_name: 1,first_name: 1,}).pretty()
{ "first_name" : "Anthony", "last_name" : "Apple" }{ "first_name" : "Carol", "last_name" : "Apple" }{ "first_name" : "Spencer", "last_name" : "Burton" }{ "first_name" : "Nixie", "last_name" : "Languin" }{ "first_name" : "Lain", "last_name" : "Singh" }{ "first_name" : "Rose", "last_name" : "Southby" }
在进一步指定之后,结果符合我们对姓名所期望的常规字母顺序。
如何使用嵌入式文档字段排序
MongoDB 还可以根据嵌入式文档中包含的值对结果进行排序。为此,请使用点表示法深入到嵌入式文档中的相应字段。
例如,您可以根据学生所居住的 city
对 student
数据进行排序,city
是每个文档中 address
的一个组成部分。请记住,使用点表示法时,您需要引用字段名以确保它们被正确解释
db.students.find({},{_id: 0,first_name: 1,last_name: 1,'address.city': 1,}).sort({'address.city': 1,}).pretty()
{"first_name" : "Lain","last_name" : "Singh","address" : {"city" : "Brighton"}}{"first_name" : "Carol","last_name" : "Apple","address" : {"city" : "Camden"}}{"first_name" : "Anthony","last_name" : "Apple","address" : {"city" : "Camden"}}{"first_name" : "Rose","last_name" : "Southby","address" : {"city" : "Nambles"}}{"first_name" : "Spencer","last_name" : "Burton","address" : {"city" : "Zoofreid"}}{"first_name" : "Nixie","last_name" : "Languin","address" : {"city" : "Zoofreid"}}
您可以将其与附加排序字段结合使用,以确保结果完全按照您的预期排序
db.students.find({},{_id: 0,first_name: 1,last_name: 1,'address.city': 1,'address.street': 1,}).sort({'address.city': 1,'address.street.name': 1,'address.street.number': 1,last_name: 1,first_name: 1,}).pretty()
在此示例中,我们按以下字段的顺序排序
- 城市
- 街道名称
- 街道号码
- 姓氏
- 名字
查询结果如下所示
{"first_name" : "Lain","last_name" : "Singh","address" : {"street" : {"name" : "Plainfield Dr.","number" : "308"},"city" : "Brighton"}}{"first_name" : "Anthony","last_name" : "Apple","address" : {"street" : {"name" : "Flint Rd.","number" : "803"},"city" : "Camden"}}{"first_name" : "Carol","last_name" : "Apple","address" : {"street" : {"name" : "Flint Rd.","number" : "803"},"city" : "Camden"}}{"first_name" : "Rose","last_name" : "Southby","address" : {"street" : {"name" : "Plainfield Dr.","number" : "4c"},"city" : "Nambles"}}{"first_name" : "Spencer","last_name" : "Burton","address" : {"street" : {"name" : "Edgecombe St.","number" : "2083b"},"city" : "Zoofreid"}}{"first_name" : "Nixie","last_name" : "Languin","address" : {"street" : {"name" : "Kensington Ln.","number" : "33"},"city" : "Zoofreid"}}
现在也是提及您用于排序的字段*不必*是您为投影提供的字段的子集的好时机。
例如,我们可以实现完全相同的排序,但只通过输入返回学生姓名
db.students.find({},{_id: 0,first_name: 1,last_name: 1,}).sort({'address.city': 1,'address.street.name': 1,'address.street.number': 1,last_name: 1,first_name: 1,}).pretty()
查询返回以下数据
{ "first_name" : "Lain", "last_name" : "Singh" }{ "first_name" : "Anthony", "last_name" : "Apple" }{ "first_name" : "Carol", "last_name" : "Apple" }{ "first_name" : "Rose", "last_name" : "Southby" }{ "first_name" : "Spencer", "last_name" : "Burton" }{ "first_name" : "Nixie", "last_name" : "Languin" }
如果将结果与之前的查询进行比较,您可以验证文档已按相同的顺序返回。
结论
在本文中,我们探讨了如何使用 sort()
方法来控制 MongoDB 对其查询结果的排序方式。我们涵盖了单字段排序、按优先级对多个字段排序、更改排序顺序以及基于嵌入式文档字段进行排序。
结合文档排序规则和结果限制等功能,排序使您能够精确控制文档和字段如何相互比较以及如何返回。熟悉这些功能可以帮助您编写更好的查询,并以更接近您使用方式的状态返回数据。
当将 Prisma Client 与 MongoDB 连接器一起使用时,您可以使用 orderBy
API 对结果进行排序。
文档中包含了如何使用此功能以多种灵活方式对结果进行排序的概述。