对结果进行排序
Overview
在本指南中,您可以了解如何使用排序操作对 MongoDB Java 驱动程序的读取操作结果进行排序。
排序操作按指定的排序条件对查询返回的文档进行排序。 排序条件是您传递给 MongoDB 的规则,描述您希望如何对数据进行排序。 排序条件的一些示例如下:
最小数字到最大数字
一天中的最早时间到一天中的最晚时间
按名字字母顺序排列
如果您想执行以下操作,请阅读本指南:
执行升序排序和降序排序。
组合排序条件。
本指南中的示例使用包含以下文档的样本集合:
{"_id": 1, "letter": "c", "food": "coffee with milk"} {"_id": 3, "letter": "a", "food": "maple syrup"} {"_id": 4, "letter": "b", "food": "coffee with sugar"} {"_id": 5, "letter": "a", "food": "milk and cookies"} {"_id": 2, "letter": "a", "food": "donuts and coffee"} {"_id": 6, "letter": "c", "food": "maple donut"}
排序方法
您可以对查询检索的结果进行排序,也可以在聚合管道内对结果进行排序。 要对查询结果进行排序,请使用FindIterable
实例的 sort()
方法。 要对聚合管道中的结果进行排序,请使用Aggregates.sort()
静态工厂方法。 这两个方法都接收实现Bson
接口的对象作为参数。 有关更多信息,请参阅 BSON 接口的 API 文档。
您可以使用FindIterable
实例的sort()
方法,如下所示:
import static com.mongodb.client.model.Sorts.ascending; // <MongoCollection setup code here> collection.find().sort(ascending("_id"));
您可以在聚合管道中使用Aggregates.sort()
方法,如下所示:
import com.mongodb.client.model.Aggregates; import static com.mongodb.client.model.Sorts.ascending; // <MongoCollection setup code here> collection.aggregate(Arrays.asList(Aggregates.sort(ascending("_id"))));
前面的代码片段按_id
字段的最小值到最大值对样本集合中的文档进行排序:
{"_id": 1, "letter": "c", "food": "coffee with milk"} {"_id": 2, "letter": "a", "food": "donuts and coffee"} {"_id": 3, "letter": "a", "food": "maple syrup"} ...
在前面的代码片段中,我们使用Sorts
构建器类指定排序条件。 虽然可以使用任何实现Bson
接口的类指定排序条件,但我们建议您通过Sorts
构建器指定排序条件。 有关Sorts
构建器类的更多信息,请参阅有关排序构建指南的指南。
有关此部分中的类和接口的更多信息,请参阅以下 API 文档:
排序方向
排序方向可以是升序,也可以是降序。 升序排序可将结果从小到大进行排序。 降序排序将结果按从大到小的顺序排列。
以下是按升序排序的数据的一些示例:
数字:1、2、3、43、43、55、120
日期:1990-03-10、1995-01-01、2005-10-30、2005-12-21
单词 (ASCII):Banana,Dill,carrot,cucumber,hummus
以下是按降序排序的数据的一些示例:
数字:100、30、12、12、9、3、1
日期:2020 年 1 月 1 日、1998 年 12 月 11 日、1998 年 12 月 10 日、1975 年 7 月 22 日
单词(反向 ASCII):pear、graves、apple、Cheese
以下各小节介绍如何指定这些排序条件。
升序
要指定升序排序,请使用Sorts.ascending()
静态工厂方法。 向Sorts.ascending()
方法传递需要按升序排序的字段的名称。
您可以将Sorts.ascending()
方法的输出传递给sort()
方法,以指定对字段进行升序排序,如下所示:
import static com.mongodb.client.model.Sorts.ascending; // <MongoCollection setup code here> collection.find().sort(ascending("<field name>"));
前面的sort()
方法返回一个FindIterable
对象,该对象可以迭代集合中的文档,并按指定字段名称从小到大排序。
在以下代码示例中,我们使用ascending()
方法按_id
字段对样本集合进行排序:
import static com.mongodb.client.model.Sorts.ascending; // <MongoCollection setup code here> List<Document> results = new ArrayList<>(); collection.find().sort(ascending("_id")).into(results); for (Document result : results) { System.out.println(result.toJson()); }
上述代码示例的输出应如下所示:
{"_id": 1, "letter": "c", "food": "coffee with milk"} {"_id": 2, "letter": "a", "food": "donuts and coffee"} {"_id": 3, "letter": "a", "food": "maple syrup"} ...
降序
要指定降序排序,请使用Sorts.descending()
静态工厂方法。 向Sorts.descending()
方法传递需要按降序排序的字段的名称。
以下代码片段展示了如何指定对_id
字段进行降序排序:
import static com.mongodb.client.model.Sorts.descending; // <MongoCollection setup code here> collection.find().sort(descending("_id"));
前面的代码片段按降序返回样本集合中的文档:
{"_id": 6, "letter": "c", "food": "maple donut"} {"_id": 5, "letter": "a", "food": "milk and cookies"} {"_id": 4, "letter": "b", "food": "coffee with sugar"} ...
处理秩
当两个或多个文档在用于对结果进行排序的字段中具有相同的值时,就会出现“并列”情况。 MongoDB 不保证出现并列时的排序顺序。 例如,假设我们使用以下代码对样本集合进行排序时遇到平局:
import static com.mongodb.client.model.Sorts.ascending; // <MongoCollection setup code here> collection.find().sort(ascending("letter"));
由于与查询匹配的多个文档都包含我们执行排序的字段值“a”,因此可以按任意顺序返回以下文档:
{"_id": 3, "letter": "a", "food": "maple syrup"} {"_id": 5, "letter": "a", "food": "milk and cookies"} {"_id": 2, "letter": "a", "food": "donuts and coffee"}
如果需要保证具有相同值字段的文档具有特定的排序顺序,则可以指定其他字段,以在出现并列时作为排序依据。
我们可以指定对 letter
字段和 _id
字段进行升序排序,如下所示:
import static com.mongodb.client.model.Sorts.ascending; // <MongoCollection setup code here> collection.find().sort(ascending("letter", "_id"));
前面的代码片段按以下顺序返回样本集合中的文档:
{"_id": 2, "letter": "a", "food": "donuts and coffee"} {"_id": 3, "letter": "a", "food": "maple syrup"} {"_id": 5, "letter": "a", "food": "milk and cookies"} {"_id": 4, "letter": "b", "food": "coffee with sugar"} {"_id": 1, "letter": "c", "food": "coffee with milk"} {"_id": 6, "letter": "c", "food": "maple donut"}
组合排序标准
要组合排序条件,请使用Sorts.orderBy()
静态工厂方法。 此方法可构造一个对象,其中包含排序条件的有序列表。 执行排序时,如果最左边的排序条件的结果为并列,则排序将使用列表中的下一个排序条件来确定顺序。
在以下代码片段中,我们使用orderBy()
方法对数据进行排序,具体方法是对letter
字段执行降序排序;如果出现平局,则对_id
字段执行升序排序。
import static com.mongodb.client.model.Sorts.orderBy; import static com.mongodb.client.model.Sorts.ascending; import static com.mongodb.client.model.Sorts.descending; // <MongoCollection setup code here> Bson orderBySort = orderBy(descending("letter"), ascending("_id")); collection.find().sort(orderBySort);
前面的代码片段按以下顺序返回样本集合中的文档:
{"_id": 1, "letter": "c", "food": "coffee with milk"} {"_id": 6, "letter": "c", "food": "maple donut"} {"_id": 4, "letter": "b", "food": "coffee with sugar"} {"_id": 2, "letter": "a", "food": "donuts and coffee"} {"_id": 3, "letter": "a", "food": "maple syrup"} {"_id": 5, "letter": "a", "food": "milk and cookies"}
文本搜索(Text Search)
Atlas Searchstring您可以通过集合的文本索引指定的每个结果字段的 值与 的匹配程度来指定 文本Atlas Searchstring 结果的顺序。文本Atlas Search会分配一个数字文本分数,以指示每个结果与Atlas Search string的匹配程度。 使用Sorts.metaTextScore()
静态工厂方法构建排序条件,按文本分数进行排序。
在以下代码示例中,我们将向您展示如何使用Sorts.metaTextScore()
方法对Atlas Search 样本集合 上的文本 的结果进行排序。该代码示例使用Filters 、 Indexes和Projections构建器。 该代码示例执行以下操作:
在
food
字段上为样本集合创建文本索引。 如果调用createIndex()
时指定集合中已存在的索引,则该操作不会创建新索引。在文本Atlas Search中运行短语“maple donut”。
将文本分数作为
score
字段投影到查询结果中。按文本得分对结果进行排序(最匹配的排在前面)。
import com.mongodb.client.model.Sorts; import com.mongodb.client.model.Projections; import com.mongodb.client.model.Filters; import com.mongodb.client.model.Indexes; // <MongoCollection setup code here> collection.createIndex(Indexes.text("food")); Bson metaTextScoreSort = Sorts.metaTextScore("score"); Bson metaTextScoreProj = Projections.metaTextScore("score"); String searchTerm = "maple donut"; Bson searchQuery = Filters.text(searchTerm); collection.find(searchQuery) .projection(metaTextScoreProj) .sort(metaTextScoreSort) .into(results); for (Document result : results) { System.out.println(result.toJson()); }
上述代码示例的输出应如下所示:
{"_id": 6, "letter": "c", "food": "maple donut", "score": 1.5} {"_id": 2, "letter": "a", "food": "donuts and coffee", "score": 0.75} {"_id": 3, "letter": "a", "food": "maple syrup", "score": 0.75}
注意
或更高版本中的文本Atlas Search 行为MongoDB4.4
MongoDB 4.4 或更高版本的文本搜索结构已更改。 您不再需要将Projections.metaTextScore()
投影到FindIterable
实例中以对文本分数进行排序。 此外,在排序中使用的$meta
文本分数聚合操作中指定的字段名称将被忽略。 这意味着您传递给Sorts.metaTextScore()
的字段名称参数将被忽略。
有关本节中类的更多信息,请参阅以下 API 文档:
有关详细信息,请参阅 Sorts 类 API 文档。有关$text查询操作符和$meta聚合管道操作符的更多信息,请参阅服务器手册文档。