排序

说明

根据一个或多个指定的排序规则对输入文档进行排序。

语法

以下示例按 population 升序对 cities 集合进行排序:

Node.js

const results = await db.pipeline()
  .collection("/cities")
  .sort(Field.of("population").ascending())
  .execute();

以下示例按城市名称的 lengthcities 集合进行升序排序。

Node.js

const results = await db.pipeline()
  .collection("/cities")
  .sort(Field.of("name").charLength().ascending())
  .execute();

客户端示例

Web

const results = await execute(db.pipeline()
  .collection("books")
  .sort(
    field("release_date").descending(), field("author").ascending()
  )
);
Swift
let results = try await db.pipeline()
  .collection("books")
  .sort([
    Field("release_date").descending(), Field("author").ascending()
  ])
  .execute()

Kotlin

val results = db.pipeline()
    .collection("books")
    .sort(
        field("release_date").descending(),
        field("author").ascending()
    )
    .execute()

Java

Task<Pipeline.Snapshot> results = db.pipeline()
    .collection("books")
    .sort(
        field("release_date").descending(),
        field("author").ascending()
    )
    .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import Field

results = (
    client.pipeline()
    .collection("books")
    .sort(Field.of("release_date").descending(), Field.of("author").ascending())
    .execute()
)
Java
Pipeline.Snapshot results =
    firestore
        .pipeline()
        .collection("books")
        .sort(descending(field("release_date")), ascending(field("author")))
        .execute()
        .get();

行为

排列顺序

排序规则遵循 Cloud Firestore 的值类型排序规则

结果的确定性顺序

如果查询中没有 sort 阶段,则返回结果的顺序是不确定的,并且可能会因执行而异。如果存在 sort 阶段,但排序表达式无法在返回的结果中生成唯一排序,则返回结果的排序仍可能因执行而异。

例如,针对以下数据集,根据城市的country对城市进行升序排序

{name: 'Los Angeles', state: 'CA', country: 'USA', population: 3970000},
{name: 'New York', state: 'NY', country: 'USA', population: 8530000}
{name: 'San Francisco', state: 'CA', country: 'USA', population: 870000},

可能生成数据集中 3 个文档的任意排列,因为它们都具有相同的 country 属性。如需生成确定性的结果排序,您可以向顺序附加 name 的排序顺序:

Node.js

const results = await db.pipeline()
  .collection("/cities")
  .sort(Field.of("country").ascending(), Field.of("__name__").ascending())
  .execute();

如果多个文档具有相同的 country 值,系统将使用唯一的文档名称作为决胜因素。请注意,任何与 country 字段共同构成集合中文档唯一键的其他字段,也可用于生成确定性的结果排序。

等效值排序

等效值会被归为一组排序,但等效类内部的结果顺序具有非确定性,如结果的确定性排序部分所述。例如,针对以下数据集,根据size对城市进行升序排序

{name: 'Los Angeles', state: 'CA', country: 'USA', size: 3970000},
{name: 'Mexico City', state: null, country: 'Mexico', size: 3970000.0},

可能生成数据集中这 2 个文档的任意排列,因为它们都具有等效的 size3970000

多个排序阶段

如果查询包含多个连续的排序阶段,则只有最后一个排序阶段会对查询结果产生影响。请注意,这与 Core API 中 orderBy 子句的行为不同。

Top-N 排序优化

limitsort 之后使用时,系统可能会采用 Top-N 排序优化。此优化通过使排序阶段一次仅需存储 N 个文档(由 limit 定义),从而限制排序阶段的内存占用,使排序过程更具内存效率。

Null 值和 Absent 值

如果排序指定的字段在文档中不存在,则在排序时将其视为 null 处理。例如,针对以下数据集,根据城市的state对城市进行升序排序

{name: 'Los Angeles', state: 'CA', country: 'USA', population: 3970000},
{name: 'Mexico City', state: null, country: 'Mexico', population: 9200000},
{name: 'New York', state: 'NY', country: 'USA', population: 8530000}
{name: 'San Francisco', state: 'CA', country: 'USA', population: 870000},
{name: 'Toronto', country: 'Canada', population: 2930000},

生成以下结果,其中“Toronto”文档和“Mexico City”文档按 null 排序,排在其他文档之前。

{name: 'Toronto', country: 'Canada', population: 2930000},
{name: 'Mexico City', state: null, country: 'Mexico', population: 9200000},
{name: 'Los Angeles', state: 'CA', country: 'USA', population: 3970000},
{name: 'San Francisco', state: 'CA', country: 'USA', population: 870000},
{name: 'New York', state: 'NY', country: 'USA', population: 8530000}