说明
查找前几个阶段中某个字段或表达式的不同值。
语法
distinct 阶段的语法与 select 类似。它接受一个或多个可选择的表达式,用于选择和查找不同的值。当表达式只是一个字段引用时,可以使用字符串:
Node.js
const cities = await db.pipeline()
.collection('/cities')
.distinct("country")
.execute();
const cities = await db.pipeline()
.collection('/cities')
.distinct(
field("state").toLower().as("normalized_state"),
field("country"))
.execute();
行为
在投影行为方面,distinct 类似于具有去重的 select,因此 select 可用的任何可选择的表达式也可用于 distinct。
distinct 阶段的工作方式与没有分组的聚合阶段类似。
查找不同的字段值
例如,如需获取以下 cities 集合中每个国家/地区的列表,请执行以下操作:
Node.js
await db.collection('cities').doc('SF').set({name: 'San Francisco', state: 'CA', country: 'USA'});
await db.collection('cities').doc('LA').set({name: 'Los Angeles', state: 'CA', country: 'USA'});
await db.collection('cities').doc('NY').set({name: 'New York', state: 'NY', country: 'USA'});
await db.collection('cities').doc('TOR').set({name: 'Toronto', state: null, country: 'Canada'});
await db.collection('cities').doc('MEX').set({name: 'Mexico City', state: null, country: 'Mexico'});
您可以使用以下方法查找不同的国家/地区:
Node.js
const cities = await db.pipeline()
.collection('/cities')
.distinct("country")
.execute();
这会生成以下结果:
{country: "USA"}
{country: "Canada"}
{country: "Mexico"}
表达式的去重输出
您还可以查找多个字段或更复杂表达式的不同组合。例如:
Node.js
const cities = await db.pipeline()
.collection('/cities')
.distinct(
field("state").toLower().as("normalized_state"),
field("country"))
.execute();
用于获取:
{country: "USA", normalized_state: "ca"}
{country: "USA", normalized_state: "ny"}
{country: "Canada", normalized_state: null}
{country: "Mexico", normalized_state: null}
等效行为
对去重值的等效性判断遵循与等式相同的语义。
这意味着,等效值(例如数学上等效的数值)无论其原始类型(32 位整数、64 位整数、浮点数、十进制数等)如何,都会被视为同一个去重值。
举例来说,在集合 numerics 中,不同的文档分别包含 32 位整数 1、64 位整数 1L 和浮点数 1.0 的 foo 值,distinct 将仅返回 1 个结果。
如果数据集中存在不同的等效值,则相应组的输出值可以是这些等效值中的任意一个。在此示例中,foo 的此值可以作为 1、1L 或 1.0 返回。
即使它看起来是确定性的,您也不应尝试依赖于选择特定值的行为。
内存使用量
distinct 阶段的执行方式取决于可用的索引。如果查询优化器未选择合适的索引,distinct 需要将所有不同的值缓冲到内存中。
如果存在大量不同的值,或者值本身非常大(例如,对巨大的值进行去重),此阶段可能会耗尽内存。
在这种情况下,您应应用过滤条件来限制要执行 distinct 的数据集,或按照建议创建索引,以避免大量使用内存。
查询解释将提供有关实际查询执行计划和分析数据的信息,以帮助进行调试。