distinct
定义
distinct
查找单个集合中指定字段的不同值。
distinct
将返回一份文档,其中包含一个由不同值组成的数组。该返回文档还包含一份嵌入式文档,其中列出了查询统计数据和查询计划。提示
在
mongosh
中,该命令也运行通过db.collection.distinct()
辅助方法运行。辅助方法对
mongosh
用户来说很方便,但它们返回的信息级别可能与数据库命令不同。如果不追求方便或需要额外的返回字段,请使用数据库命令。
兼容性
此命令可用于以下环境中托管的部署:
MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务
重要
此命令在 M 0 、 M 2和 M 5集群中提供有限支持。 有关更多信息,请参阅不支持的命令。
MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本
MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本
语法
该命令具有以下语法:
db.runCommand( { distinct: "<collection>", key: "<field>", query: <query>, readConcern: <read concern document>, collation: <collation document>, comment: <any>, hint: <string or document> } )
命令字段
该命令接受以下字段:
字段 | 类型 | 说明 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
distinct | 字符串 | 要查询不同值的集合名称。 | ||||||||||
key | 字符串 | 要针对该字段返回非重复值。 | ||||||||||
query | 文档 | 可选。指定要从中检索非重复值的文档的查询。 | ||||||||||
readConcern | 文档 | 可选。指定读关注。
可能的读关注级别是:
有关读关注级别的更多信息,请参阅读关注级别。 | ||||||||||
collation | 文档 | 可选。 指定用于操作的排序规则。 排序规则允许用户为字符串比较指定特定于语言的规则,例如字母大小写和重音符号规则。 排序规则选项的语法如下:
指定排序规则时, 如果未指定排序规则,但集合具有默认排序规则(请参阅 如果没有为收集或操作指定排序规则,MongoDB 将使用先前版本中使用的简单二进制比较来进行字符串比较。 您不能为一个操作指定多个排序规则。例如,您不能为每个字段指定不同的排序规则,或者如果执行带排序的查找,则不能使用一种排序规则进行查找而另一种排序规则进行排序。 | ||||||||||
comment | any | 可选。用户提供的待附加到该命令的注释。设置后,该注释将与该命令的记录一起出现在以下位置:
注释可以是任何有效的 BSON 类型(字符串、整型、对象、数组等)。 | ||||||||||
hint | 字符串或文档 | 可选。 以string或文档形式指定索引名称。 如果指定,则查询规划器仅考虑使用提示索引的计划。 有关更多详细信息,请参阅指定索引。 版本 7.1 中的新增内容。 |
注意
结果不得大于最大 BSON 大小。如果您的结果超出最大 BSON 大小,请使用聚合管道通过 $group
操作符检索非重复值,如使用聚合管道检索非重复值中所述。
MongoDB 还为 distinct
命令提供 shell 包装器方法 db.collection.distinct()
。此外,许多 MongoDB 驱动程序都提供包装器方法。请参阅具体的驱动程序文档。
行为
对于时间序列集合, distinct
命令无法有效利用索引。相反,使用 $group
聚合按不同的值对文档进行分组。有关详细信息,请参阅时间序列限制。
数组字段
如果指定的 field
值是数组,则 distinct
将数组的每个元素视为一个单独的值。
例如,如果某一字段的值为 [ 1, [1], 1 ]
,则 distinct
会将 1
、[1]
和 1
视为不同的值。
从 MongoDB 6.0 开始,当使用数组时,distinct
命令会为集合和视图返回相同的结果。
示例请参见:
索引使用
在可能的情况下,distinct
操作可以使用索引。
事务
如要在事务中执行不同的操作:
对于未分片的集合,可以使用
db.collection.distinct()
方法 /distinct
命令以及具有$group
阶段的聚合管道。对于分片集合,不能使用
db.collection.distinct()
方法或distinct
命令。
重要
在大多数情况下,与单文档写入操作相比,分布式事务会产生更高的性能成本,并且分布式事务的可用性不应取代有效的模式设计。在许多情况下,非规范化数据模型(嵌入式文档和数组)仍然是数据和使用案例的最佳选择。换言之,对于许多场景,适当的数据建模将最大限度地减少对分布式事务的需求。
有关其他事务使用注意事项(如运行时间限制和 oplog 大小限制),另请参阅生产注意事项。
客户端断开连接
从 MongoDB 4.2 开始,如果在操作完成之前,发出 distinct
的客户端断开连接,MongoDB 将使用killOp
将 distinct
标记为终止。
副本集节点状态限制
若要在副本集节点上运行,distinct
操作要求该节点处于 PRIMARY
或 SECONDARY
状态。如果该节点处于其他状态,如 STARTUP2
,则操作错误。
索引筛选器和排序规则
从 MongoDB 6.0 开始,索引筛选器会使用之前使用 planCacheSetFilter
命令设置的排序规则。
从 MongoDB 8.0开始,使用查询设置而不是添加索引筛选器。 从 MongoDB 8.0开始,索引筛选器已弃用。
查询设置的功能比索引筛选器更多。 此外,索引筛选器不是持久性的,您无法轻松地为所有集群节点创建索引筛选器。 要添加查询设置并探索示例,请参阅setQuerySettings
。
查询设置
8.0版本新增。
您可以使用查询设置来设置索引提示、设置操作拒绝过滤器以及其他字段。这些设置将应用于整个集群上的查询结构。在关闭之后,集群将保留这些设置。
在查询规划期间,查询优化器将使用查询设置作为附加输入,这样会影响为运行查询而选择的计划。您还可以使用查询设置来阻塞查询结构。
要添加查询设置并探索示例,请参阅 setQuerySettings
。
您可以为 find
、distinct
和 aggregate
命令添加查询设置。
查询设置具有更多功能,相比已弃用的索引过滤器而言是您的首选。
要删除查询设置,请使用 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" } )
该命令返回一个文档,其中包含名为values
的字段,其中包含不同的 dept
值:
{ "values" : [ "A", "B" ], "ok" : 1 }
返回嵌入式字段的非重复值
以下示例针对 inventory
集合的所有文档,从中返回嵌入 item
字段中的字段 sku
的非重复值:
db.runCommand ( { distinct: "inventory", key: "item.sku" } )
该命令返回一个文档,其中包含名为values
的字段,其中包含不同的 sku
值:
{ "values" : [ "111", "222", "333" ], "ok" : 1 }
返回数组字段的非重复值
以下示例将返回 inventory
集合的所有文档中字段 sizes
的不同值:
db.runCommand ( { distinct: "inventory", key: "sizes" } )
该命令返回一个文档,其中包含名为values
的字段,其中包含不同的 sizes
值:
{ "values" : [ "M", "S", "L" ], "ok" : 1 }
集合和视图中的数组
从 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" )
示例输出:
[ 4, 8, 12 ]
从 MongoDB 6.0 开始(与从sensor
集合返回的结果相同)。[]
在 MongoDB 6.0 以前的版本中。
使用以下项指定查询: distinct
对于 dept
等于 "A"
的文档,以下示例从中返回嵌入 item
字段中的字段 sku
的非重复值:
db.runCommand ( { distinct: "inventory", key: "item.sku", query: { dept: "A"} } )
该命令返回一个文档,其中包含名为values
的字段,其中包含不同的 sku
值:
{ "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 } } )