distinct
定义
distinct
Finds the distinct values for a specified field across a single collection.
distinct
returns a document that contains an array of the distinct values. The return document also contains an embedded document with query statistics and the query plan.提示
在
mongosh
中,该命令也可通过db.collection.distinct()
辅助方法运行。辅助方法对
mongosh
用户来说很方便,但它们返回的信息级别可能与数据库命令不同。如果不追求方便或需要额外的返回字段,请使用数据库命令。
兼容性
此命令可用于以下环境中托管的部署:
MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务
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> } )
命令字段
该命令接受以下字段:
字段 | 类型 | 说明 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
| 字符串 | The name of the collection to query for distinct values. | ||||||||||
| 字符串 | 要针对该字段返回非重复值。 | ||||||||||
| 文档 | Optional. A query that specifies the documents from which to retrieve the distinct values. | ||||||||||
| 文档 | 可选。指定读关注。
可能的读关注级别是:
有关读关注级别的更多信息,请参阅读关注级别。 | ||||||||||
| 文档 | 可选。 指定用于操作的排序规则。 排序规则允许用户为字符串比较指定特定于语言的规则,例如字母大小写和重音符号规则。 排序规则选项的语法如下:
指定排序规则时, 如果未指定排序规则,但集合具有默认排序规则(请参阅 如果没有为收集或操作指定排序规则,MongoDB 将使用先前版本中使用的简单二进制比较来进行字符串比较。 您不能为一个操作指定多个排序规则。例如,您不能为每个字段指定不同的排序规则,或者如果执行带排序的查找,则不能使用一种排序规则进行查找而另一种排序规则进行排序。 | ||||||||||
| any | 可选。用户提供的待附加到该命令的注释。设置后,该注释将与该命令的记录一起出现在以下位置:
注释可以是任何有效的 BSON 类型(字符串、整型、对象、数组等)。 | ||||||||||
| 字符串或文档 | Optional. Specify the index name, either as a string or a document. If specified, the query planner only considers plans using the hinted index. For more details, see 指定索引. 版本 7.1 中的新增内容。 |
注意
结果不得大于最大 BSON 大小。如果您的结果超出最大 BSON 大小,请使用聚合管道通过 $group
操作符检索非重复值,如使用聚合管道检索非重复值中所述。
MongoDB also provides the shell wrapper method
db.collection.distinct()
for the distinct
command. Additionally, many MongoDB drivers
provide a wrapper method. Refer to the specific driver documentation.
行为
In a 分片集群, the distinct
command may return
orphaned documents.
对于时间序列集合, distinct
命令无法有效利用索引。相反,使用 $group
聚合按不同的值对文档进行分组。有关详细信息,请参阅时间序列限制。
数组字段
如果指定的 field
值是数组,则 distinct
将数组的每个元素视为一个单独的值。
例如,如果某一字段的值为 [ 1, [1], 1 ]
,则 distinct
会将 1
、[1]
和 1
视为不同的值。
Starting in MongoDB 6.0, the distinct
command returns the
same results for collections and views when
using arrays.
示例请参见:
索引使用
在可能的情况下,distinct
操作可以使用索引。
事务
如要在事务中执行不同的操作:
For unsharded collections, you can use the
db.collection.distinct()
method/thedistinct
command as well as the aggregation pipeline with the$group
stage.For sharded collections, you cannot use the
db.collection.distinct()
method or thedistinct
command.
重要
在大多数情况下,与单文档写入操作相比,分布式事务会产生更高的性能成本,并且分布式事务的可用性不应取代有效的模式设计。在许多情况下,非规范化数据模型(嵌入式文档和数组)仍然是数据和使用案例的最佳选择。换言之,对于许多场景,适当的数据建模将最大限度地减少对分布式事务的需求。
有关其他事务使用注意事项(如运行时间限制和 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
。
You can add query settings for find
, distinct
,
and aggregate
commands.
查询设置具有更多功能,相比已弃用的索引过滤器而言是您的首选。
要删除查询设置,请使用 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" } )
The command returns a document with a field named values
that
contains the distinct dept
values:
{ "values" : [ "A", "B" ], "ok" : 1 }
返回嵌入式字段的非重复值
以下示例针对 inventory
集合的所有文档,从中返回嵌入 item
字段中的字段 sku
的非重复值:
db.runCommand ( { distinct: "inventory", key: "item.sku" } )
The command returns a document with a field named values
that
contains the distinct sku
values:
{ "values" : [ "111", "222", "333" ], "ok" : 1 }
另请参阅:
用于获取有关访问嵌入式文档内字段的信息的点符号
返回数组字段的非重复值
以下示例将返回 inventory
集合的所有文档中字段 sizes
的不同值:
db.runCommand ( { distinct: "inventory", key: "sizes" } )
The command returns a document with a field named values
that
contains the distinct sizes
values:
{ "values" : [ "M", "S", "L" ], "ok" : 1 }
For information on distinct
and array fields, see the
行为 section.
Arrays in Collections and Views
Starting in MongoDB 6.0, the distinct
command returns the
same results for collections and views when
using arrays.
The following example creates a collection named sensor
with
an array of temperature values for each document:
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 } ] } ] )
The following example creates a view named sensorView
from the
sensor
collection:
db.createView( "sensorView", "sensor", [] )
The following example uses distinct
to return the unique
values from the temperatures
array in the sensor
collection:
db.sensor.distinct( "temperatures.1.value" )
The 1
in temperatures.1.value
specifies the temperatures
array index.
示例输出:
[ 4, 8, 12 ]
Example for sensorView
:
db.sensorView.distinct( "temperatures.1.value" )
示例输出:
[ 4, 8, 12 ]
starting in MongoDB 6.0 (identical to result returned from thesensor
collection).[]
in MongoDB versions earlier than 6.0.
使用 distinct
指定查询
对于 dept
等于 "A"
的文档,以下示例从中返回嵌入 item
字段中的字段 sku
的非重复值:
db.runCommand ( { distinct: "inventory", key: "item.sku", query: { dept: "A"} } )
The command returns a document with a field named values
that
contains the distinct 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"
写关注。
指定索引
You can specify an index name or pattern using the hint option.
To specify a hint based on an index name:
db.runCommand ( { distinct: "inventory", key: "dept", hint: "sizes" } )
To specify a hint based on an index pattern:
db.runCommand ( { distinct: "inventory", key: "dept", hint: { sizes: 1 } } )