说明
过滤前一阶段的文档,仅返回条件计算结果为 true 的文档。
语法:
where(condition: Expr)
示例
创建一个包含以下文档的 cities 集合:
Node.js
await db.collection('cities').doc('SF').set({name: 'San Francisco', state: 'CA', country: 'USA', population: 870000});
await db.collection('cities').doc('LA').set({name: 'Los Angeles', state: 'CA', country: 'USA', population: 3970000});
await db.collection('cities').doc('NY').set({name: 'New York', state: 'NY', country: 'USA', population: 8530000});
await db.collection('cities').doc('TOR').set({name: 'Toronto', state: null, country: 'Canada', population: 2930000});
await db.collection('cities').doc('MEX').set({name: 'Mexico City', state: null, country: 'Mexico', population: 9200000});
执行等值搜索:
Node.js
const cities = await db.pipeline()
.collection("/cities")
.where(field("state").equals("CA"))
.execute();
生成以下结果:
{name: 'San Francisco', state: 'CA', country: 'USA', population: 870000},
{name: 'Los Angeles', state: 'CA', country: 'USA', population: 3970000}
行为
多个阶段
多个 where(...) 阶段可以链接在一起,充当每个条件中的 and(...) 表达式。
Node.js
const cities = await db.pipeline()
.collection("/cities")
.where(field("location.country").equals("USA"))
.where(field("population").greaterThan(500000))
.execute();
虽然需要根据两个条件的逻辑 or 进行过滤,但需要作为单个 where(...) 阶段来完成。
Node.js
const cities = await db.pipeline()
.collection("/cities")
.where(field("location.state").equals("NY").or(field("location.state").equals("CA")))
.execute();
复杂表达式
过滤条件可以包含深度嵌套的表达式和逻辑运算符,从而构成复杂的过滤逻辑。例如:
Node.js
const cities = await db.pipeline()
.collection("/cities")
.where(
field("name").like("San%")
.or(
field("location.state").charLength().greaterThan(7)
.and(field("location.country").equals("USA"))))
根据正则表达式过滤 /cities,或者在城市位于州名称足够长的 USA 中时进行过滤。您可以将任何表达式指定为条件,但只有计算结果为 true 的表达式才会匹配。
阶段顺序
阶段的顺序非常重要,因为它会改变查询评估顺序。例如,以下查询:
Node.js
const cities = await db.pipeline()
.collection("/cities")
.limit(10)
.where(field("location.country").equals("USA"))
.execute();
只会对一组(可能随机)10 个文档应用 location.country 过滤条件,因为前面的 limit(...) 阶段已经限制了后续 where(...) 阶段能够接收的文档数量。鉴于此,经验法则是尽可能早地在查询中放置 where(...) 阶段。
类似 HAVING 的功能:
where(...) 阶段可以位于任何更改文档架构的阶段(例如 select(...) 或 aggregate(...))之后,并将引用这些阶段生成的字段。重点在于,对于 aggregate(...) 阶段而言,其后跟随的、引用已聚合字段的 where(...) 子句,其作用类似于标准 SQL 中的 HAVING 子句。例如:
Node.js
const cities = await db.pipeline()
.collection("/cities")
.aggregate({
accumulators: [field("population").sum().as("total_population")],
groups: ['location.state']
})
.where(field("total_population").greaterThan(10000000))
可以返回那些城市总人口超过特定规模的州。
更多示例
Web
let results; results = await execute(db.pipeline().collection("books") .where(field("rating").equal(5)) .where(field("published").lessThan(1900)) ); results = await execute(db.pipeline().collection("books") .where(and(field("rating").equal(5), field("published").lessThan(1900))) );
Swift
var results: Pipeline.Snapshot results = try await db.pipeline().collection("books") .where(Field("rating").equal(5)) .where(Field("published").lessThan(1900)) .execute() results = try await db.pipeline().collection("books") .where(Field("rating").equal(5) && Field("published").lessThan(1900)) .execute()
Kotlin
var results: Task<Pipeline.Snapshot> results = db.pipeline().collection("books") .where(field("rating").equal(5)) .where(field("published").lessThan(1900)) .execute() results = db.pipeline().collection("books") .where(Expression.and(field("rating").equal(5), field("published").lessThan(1900))) .execute()
Java
Task<Pipeline.Snapshot> results; results = db.pipeline().collection("books") .where(field("rating").equal(5)) .where(field("published").lessThan(1900)) .execute(); results = db.pipeline().collection("books") .where(Expression.and( field("rating").equal(5), field("published").lessThan(1900) )) .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import And, Field results = ( client.pipeline() .collection("books") .where(Field.of("rating").equal(5)) .where(Field.of("published").less_than(1900)) .execute() ) results = ( client.pipeline() .collection("books") .where(And(Field.of("rating").equal(5), Field.of("published").less_than(1900))) .execute() )