distinct
定义
distinct
在单个集合中查找指定字段的唯一值。
distinct
返回一个包含唯一值数组的文档。返回文档还包含包含查询统计信息和查询计划的嵌入式文档。提示
在
mongosh
中,此命令也可以通过db.collection.distinct()
辅助方法.辅助方法对
mongosh
用户来说很方便,但它们可能不会返回与数据库命令相同级别的信息。在不需要便利性或需要额外的返回字段的情况下,请使用数据库命令。
兼容性
此命令在以下环境中提供的部署中可用
MongoDB Atlas:云中MongoDB部署的全托管服务
重要
此命令在M0、M2和M5集群中支持有限。更多信息,请参阅不受支持的命令。
MongoDB企业版:MongoDB基于订阅的自托管版本
MongoDB社区版:MongoDB源代码可用、免费使用和自托管版本
语法
该命令具有以下语法
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 选项的语法如下: 可能的读取关注点级别包括
有关读关注级别的更多信息,请参阅 读关注级别。 | ||||||||||
排序规则 | document | 可选。 指定操作使用的 排序规则。 排序规则 允许用户指定字符串比较的语言特定规则,例如字母大小写和重音符号的规则。 排序规则选项的语法
在指定排序规则时, 如果未指定排序规则,但集合有默认排序规则(请参阅 如果未为集合或操作指定排序规则,MongoDB 使用先前版本中用于字符串比较的简单二进制比较。 您不能为操作指定多个排序规则。例如,您不能为每个字段指定不同的排序规则,或者在执行带有排序的查找时,您不能为查找和排序使用不同的排序规则。 | ||||||||||
注释 | 任何 | 可选。用户提供的附加到此命令的注释。一旦设置,此注释将出现在以下位置的此命令记录旁边
注释可以是任何有效的 BSON 类型(字符串、整数、对象、数组等)。 | ||||||||||
提示 | 字符串或文档 | 可选。指定索引名称,可以是字符串或文档。如果指定,查询规划器仅考虑使用提示索引的计划。有关更多详细信息,请参阅 指定索引。 新在版本7.1. |
注意
结果不得大于最大 BSON 大小。如果您的结果超出最大 BSON 大小,请使用聚合管道使用 $group
操作符检索不同的值,如使用聚合管道检索不同的值 中所述。
MongoDB 还提供了用于 distinct
命令的 shell 包装方法 db.collection.distinct()
。此外,许多 MongoDB 驱动程序 提供了包装方法。请参阅特定驱动程序的文档。
行为
对于时间序列集合,distinct
命令不能有效利用索引。相反,使用 $group
聚合来根据不同的值对文档进行分组。有关详细信息,请参阅时间序列限制。
数组字段
如果指定 字段
的值是数组,distinct
将数组中的每个元素视为一个单独的值。
例如,如果一个字段的值是 [ 1, [1], 1 ]
,那么 distinct
将 1
、[1]
和 1
视为不同的值。
从 MongoDB 6.0 开始,使用数组时,distinct
命令对集合和 视图 返回相同的结果。
有关示例,请参阅
索引使用
在可能的情况下,可以使用索引执行distinct
操作。
事务
在事务中执行distinct操作
对于非分片集合,可以使用
db.collection.distinct()
方法/distinct
命令以及带有$group
阶段的聚合管道。对于分片集合,不能使用
db.collection.distinct()
方法或distinct
命令。要查找分片集合的不同值,请使用带有
$group
阶段的聚合管道。有关详细信息,请参阅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" } )
该命令返回一个包含唯一 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 }
集合和视图中的数组
从 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 之前的版本中为 []。
使用 distinct
指定查询
以下示例返回文档中 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 } } )