Docs 菜单

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 用户来说很方便,但它们返回的信息级别可能与数据库命令不同。如果不追求方便或需要额外的返回字段,请使用数据库命令。

此命令可用于以下环境中托管的部署:

重要

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

该命令具有以下语法:

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

该命令接受以下字段:

字段
类型
说明

distinct

字符串

The name of the collection to query for distinct values.

key

字符串

要针对该字段返回非重复值。

query

文档

Optional. A query that specifies the documents from which to retrieve the distinct values.

readConcern

文档

可选。指定读关注

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

可能的读关注级别是:

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

collation

文档

可选。

指定用于操作的排序规则

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

排序规则选项的语法如下:

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

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

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

如果没有为收集或操作指定排序规则,MongoDB 将使用先前版本中使用的简单二进制比较来进行字符串比较。

您不能为一个操作指定多个排序规则。例如,您不能为每个字段指定不同的排序规则,或者如果执行带排序的查找,则不能使用一种排序规则进行查找而另一种排序规则进行排序。

comment

any

可选。用户提供的待附加到该命令的注释。设置后,该注释将与该命令的记录一起出现在以下位置:

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

hint

字符串或文档

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 操作可以使用索引。

索引还可以涵盖 distinct 操作。有关索引涵盖的查询的详细信息,请参阅涵盖的查询

如要在事务中执行不同的操作:

重要

在大多数情况下,与单文档写入操作相比,分布式事务会产生更高的性能成本,并且分布式事务的可用性不应取代有效的模式设计。在许多情况下,非规范化数据模型(嵌入式文档和数组)仍然是数据和使用案例的最佳选择。换言之,对于许多场景,适当的数据建模将最大限度地减少对分布式事务的需求。

有关其他事务使用注意事项(如运行时间限制和 oplog 大小限制),另请参阅生产注意事项

从 MongoDB 4.2 开始,如果在操作完成之前,发出 distinct 的客户端断开连接,MongoDB 将使用killOpdistinct 标记为终止。

若要在副本集节点上运行,distinct 操作要求该节点处于 PRIMARYSECONDARY 状态。如果该节点处于其他状态,如 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.

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 the sensor collection).

  • [] in MongoDB versions earlier than 6.0.

对于 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 } } )