文档菜单
文档首页
/
MongoDB 手册
/ / /

distinct

本页内容

  • 定义
  • 兼容性
  • 语法
  • 命令字段
  • 行为
  • 示例
distinct

在单个集合中查找指定字段的唯一值。distinct 返回一个包含唯一值数组的文档。返回文档还包含包含查询统计信息和查询计划的嵌入式文档。

提示

mongosh 中,此命令也可以通过db.collection.distinct() 辅助方法.

辅助方法对 mongosh 用户来说很方便,但它们可能不会返回与数据库命令相同级别的信息。在不需要便利性或需要额外的返回字段的情况下,请使用数据库命令。

此命令在以下环境中提供的部署中可用

  • MongoDB Atlas:云中MongoDB部署的全托管服务

重要

此命令在M0、M2和M5集群中支持有限。更多信息,请参阅不受支持的命令。

该命令具有以下语法

db.runCommand(
{
distinct: "<collection>",
key: "<field>",
query: <query>,
readConcern: <read concern document>,
collation: <collation document>,
comment: <any>,
hint: <string or document>
}
)

该命令包含以下字段

字段
类型
描述
distinct
string
要查询不同值的集合的名称。
key
string
返回不同值的字段。
query
document
可选。指定从其中检索不同值的文档的查询。
readConcern
document

可选。指定读取关注点。

readConcern 选项的语法如下:readConcern: { level: <value> }

可能的读取关注点级别包括

有关读关注级别的更多信息,请参阅 读关注级别。

排序规则
document

可选。

指定操作使用的 排序规则

排序规则 允许用户指定字符串比较的语言特定规则,例如字母大小写和重音符号的规则。

排序规则选项的语法

collation: {
locale: <string>,
caseLevel: <boolean>,
caseFirst: <string>,
strength: <int>,
numericOrdering: <boolean>,
alternate: <string>,
maxVariable: <string>,
backwards: <boolean>
}

在指定排序规则时,locale 字段是必需的;所有其他排序规则字段都是可选的。有关字段的说明,请参阅 排序规则文档。

如果未指定排序规则,但集合有默认排序规则(请参阅 db.createCollection()),则操作使用集合指定的排序规则。

如果未为集合或操作指定排序规则,MongoDB 使用先前版本中用于字符串比较的简单二进制比较。

您不能为操作指定多个排序规则。例如,您不能为每个字段指定不同的排序规则,或者在执行带有排序的查找时,您不能为查找和排序使用不同的排序规则。

注释
任何

可选。用户提供的附加到此命令的注释。一旦设置,此注释将出现在以下位置的此命令记录旁边

注释可以是任何有效的 BSON 类型(字符串、整数、对象、数组等)。

提示
字符串或文档

可选。指定索引名称,可以是字符串或文档。如果指定,查询规划器仅考虑使用提示索引的计划。有关更多详细信息,请参阅 指定索引。

在版本7.1.

注意

结果不得大于最大 BSON 大小。如果您的结果超出最大 BSON 大小,请使用聚合管道使用 $group 操作符检索不同的值,如使用聚合管道检索不同的值 中所述。

MongoDB 还提供了用于 distinct 命令的 shell 包装方法 db.collection.distinct()。此外,许多 MongoDB 驱动程序 提供了包装方法。请参阅特定驱动程序的文档。

分片集群中,distinct 命令可能会返回孤立文档

对于时间序列集合distinct 命令不能有效利用索引。相反,使用 $group 聚合来根据不同的值对文档进行分组。有关详细信息,请参阅时间序列限制

如果指定 字段 的值是数组,distinct 将数组中的每个元素视为一个单独的值。

例如,如果一个字段的值是 [ 1, [1], 1 ],那么 distinct1[1]1 视为不同的值。

从 MongoDB 6.0 开始,使用数组时,distinct 命令对集合和 视图 返回相同的结果。

有关示例,请参阅

在可能的情况下,可以使用索引执行distinct操作。

索引还可以覆盖 distinct操作。有关索引覆盖的查询的更多信息,请参阅覆盖查询

在事务中执行distinct操作

重要

在大多数情况下,分布式事务相对于单文档写入会产生更高的性能成本,分布式事务的可用性不应替代有效的模式设计。对于许多场景,非规范化数据模型(嵌入文档和数组)将继续是您数据和用例的最佳选择。也就是说,对于许多场景,适当地建模数据将最大限度地减少分布式事务的需求。

有关额外的交易使用考虑因素(如运行时限制和oplog大小限制),请参阅生产注意事项。

从MongoDB 4.2版本开始,如果发起distinct命令的客户端在操作完成前断开连接,MongoDB将使用killOp命令将distinct标记为终止。

要在副本集成员上运行,distinct操作需要成员处于PRIMARYSECONDARY状态。如果成员处于其他状态,例如STARTUP2,则操作将出错。

从MongoDB 6.0开始,索引过滤器使用之前通过planCacheSetFilter命令设置的校对规则

从MongoDB 8.0开始,使用查询设置而不是添加索引过滤器。从MongoDB 8.0开始,索引过滤器已被弃用。

查询设置比索引过滤器功能更强大。此外,索引过滤器不持久,并且您无法轻松为所有集群节点创建索引过滤器。要添加查询设置并查看示例,请参阅setQuerySettings

在版本8.0.

您可以使用查询设置来设置索引提示、设置操作拒绝过滤器以及其他字段。这些设置应用于整个集群上的查询形状。集群在关闭后仍保留这些设置。

查询优化器在查询规划期间将查询设置作为额外输入使用,这会影响选择的查询计划。您还可以使用查询设置来阻止查询形状。

要添加查询设置并查看示例,请参阅setQuerySettings

您可以为finddistinctaggregate命令添加查询设置。

查询设置比已弃用的索引过滤器功能更强大,更受青睐。

要删除查询设置,请使用removeQuerySettings。要获取查询设置,请使用聚合管道中的$querySettings阶段。

以下示例使用包含以下文档的 inventory 集合

{ "_id": 1, "dept": "A", "item": { "sku": "111", "color": "red" }, "sizes": [ "S", "M" ] }
{ "_id": 2, "dept": "A", "item": { "sku": "111", "color": "blue" }, "sizes": [ "M", "L" ] }
{ "_id": 3, "dept": "B", "item": { "sku": "222", "color": "blue" }, "sizes": "S" }
{ "_id": 4, "dept": "A", "item": { "sku": "333", "color": "black" }, "sizes": [ "S" ] }

以下示例返回 inventory 集合中所有文档的字段 dept 的唯一值

db.runCommand ( { distinct: "inventory", key: "dept" } )

该命令返回一个包含唯一 dept 值的名为 values 的字段文档

{
"values" : [ "A", "B" ],
"ok" : 1
}

以下示例返回 inventory 集合中所有文档内嵌在 item 字段中的字段 sku 的唯一值

db.runCommand ( { distinct: "inventory", key: "item.sku" } )

该命令返回一个包含唯一 sku 值的名为 values 的字段文档

{
"values" : [ "111", "222", "333" ],
"ok" : 1
}

提示

另请参阅

点符号 以获取有关访问内嵌文档中字段的详细信息

以下示例返回了从 inventory 集合中所有文档的 sizes 字段的唯一值。

db.runCommand ( { distinct: "inventory", key: "sizes" } )

此命令返回一个包含唯一 sizes 值的名为 values 的字段文档。

{
"values" : [ "M", "S", "L" ],
"ok" : 1
}

有关 distinct 和数组字段的更多信息,请参阅 行为 部分。

从 MongoDB 6.0 开始,使用数组时,distinct 命令对集合和 视图 返回相同的结果。

以下示例创建了一个名为 sensor 的集合,其中包含每个文档的温度值数组。

db.sensor.insertMany( [
{ _id: 0, temperatures: [ { value: 1 }, { value: 4 } ] },
{ _id: 1, temperatures: [ { value: 2 }, { value: 8 } ] },
{ _id: 2, temperatures: [ { value: 3 }, { value: 12 } ] },
{ _id: 3, temperatures: [ { value: 1 }, { value: 4 } ] }
] )

以下示例从 sensor 集合创建了一个名为 sensorView 的视图。

db.createView( "sensorView", "sensor", [] )

以下示例使用 distinct 返回 sensor 集合中 temperatures 数组的唯一值。

db.sensor.distinct( "temperatures.1.value" )

temperatures.1.value 中的 1 指定了 temperatures 数组的索引。

示例输出

[ 4, 8, 12 ]

sensorView 的示例

db.sensorView.distinct( "temperatures.1.value" )

示例输出

  • 从 MongoDB 6.0 开始,[ 4, 8, 12 ](与从 sensor 集合返回的结果相同)。

  • 在 MongoDB 6.0 之前的版本中为 []。

以下示例返回文档中 dept 等于 "A" 的字段 sku(嵌入在 item 字段中)的唯一值。

db.runCommand ( { distinct: "inventory", key: "item.sku", query: { dept: "A"} } )

该命令返回一个包含唯一 sku 值的名为 values 的字段文档

{
"values" : [ "111", "333" ],
"ok" : 1
}

排序规则 允许用户指定字符串比较的语言特定规则,例如字母大小写和重音符号的规则。

集合 myColl 包含以下文档

{ _id: 1, category: "café", status: "A" }
{ _id: 2, category: "cafe", status: "a" }
{ _id: 3, category: "cafE", status: "a" }

以下聚合操作包含排序规则选项

db.runCommand(
{
distinct: "myColl",
key: "category",
collation: { locale: "fr", strength: 1 }
}
)

有关排序字段描述,请参阅排序规则文档

要覆盖默认的读取关注级别 "local",请使用 readConcern 选项。

以下对副本集的操作指定了一个读取关注点"majority",以读取数据最新副本,该副本已被确认已写入多数节点。

注意

无论读取关注点的级别如何,节点上的最新数据可能不会反映系统中的最新数据版本。

db.runCommand(
{
distinct: "restaurants",
key: "rating",
query: { cuisine: "italian" },
readConcern: { level: "majority" }
}
)

为了确保单个线程可以读取其自身的写入,请对副本集的主节点使用"majority"读取关注点和"majority"写入关注点。

您可以使用提示选项指定索引名称或模式。

根据索引名称指定提示

db.runCommand ( { distinct: "inventory", key: "dept", hint: "sizes" } )

根据索引模式指定提示

db.runCommand ( { distinct: "inventory", key: "dept", hint: { sizes: 1 } } )

返回

count