Docs 菜单
Docs 主页
/
MongoDB Manual
/ / /

$addToSet(聚合)

在此页面上

  • 定义
  • 语法
  • 行为
  • 示例

5.0 版本中的更改

$addToSet

$addToSet 返回所有唯一值的数组,其中包含将表达式应用到群组中每个文档后产生的结果。

返回的数组中元素的顺序未指定。

$addToSet 可在以下阶段使用:

$addToSet 事务语法:

{ $addToSet: <expression> }

有关表达式的更多信息,请参阅表达式运算符。

如果表达式的值是一个数组,$addToSet 会将整个数组作为一个元素附加。

如果该表达式的值为一个文档,则当数组中的另一文档与要添加的文档完全匹配时,MongoDB 便确定该文档为重复文档。具体而言,现有文档包含顺序完全相同的相同字段和值。

请考虑包含以下文档的 sales 集合:

{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-01-01T08:00:00Z") }
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-02-03T09:00:00Z") }
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-03T09:05:00Z") }
{ "_id" : 4, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-02-15T08:00:00Z") }
{ "_id" : 5, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T09:12:00Z") }

通过按照 date 字段的日期和年份对文档进行分组,以下操作使用 $addToSet 累加器计算每个群组销售的唯一物品清单:

db.sales.aggregate(
[
{
$group:
{
_id: { day: { $dayOfYear: "$date"}, year: { $year: "$date" } },
itemsSold: { $addToSet: "$item" }
}
}
]
)

操作返回以下结果:

{ "_id" : { "day" : 46, "year" : 2014 }, "itemsSold" : [ "xyz", "abc" ] }
{ "_id" : { "day" : 34, "year" : 2014 }, "itemsSold" : [ "xyz", "jkl" ] }
{ "_id" : { "day" : 1, "year" : 2014 }, "itemsSold" : [ "abc" ] }

版本 5.0 中的新增功能

创建cakeSales集合,其中包含加利福尼亚州 ( CA ) 和华盛顿州 ( WA ) 的蛋糕销售情况:

db.cakeSales.insertMany( [
{ _id: 0, type: "chocolate", orderDate: new Date("2020-05-18T14:10:30Z"),
state: "CA", price: 13, quantity: 120 },
{ _id: 1, type: "chocolate", orderDate: new Date("2021-03-20T11:30:05Z"),
state: "WA", price: 14, quantity: 140 },
{ _id: 2, type: "vanilla", orderDate: new Date("2021-01-11T06:31:15Z"),
state: "CA", price: 12, quantity: 145 },
{ _id: 3, type: "vanilla", orderDate: new Date("2020-02-08T13:13:23Z"),
state: "WA", price: 13, quantity: 104 },
{ _id: 4, type: "strawberry", orderDate: new Date("2019-05-18T16:09:01Z"),
state: "CA", price: 41, quantity: 162 },
{ _id: 5, type: "strawberry", orderDate: new Date("2019-01-08T06:12:03Z"),
state: "WA", price: 43, quantity: 134 }
] )

此示例在$addToSet $setWindowFields阶段使用type 输出每个 的唯一蛋糕state 销售额:

db.cakeSales.aggregate( [
{
$setWindowFields: {
partitionBy: "$state",
sortBy: { orderDate: 1 },
output: {
cakeTypesForState: {
$addToSet: "$type",
window: {
documents: [ "unbounded", "current" ]
}
}
}
}
}
] )

在示例中:

  • partitionBy: "$state"state 对集合中的文档分区CAWA 都有分区。

  • sortBy: { orderDate: 1 }orderDate 以升序 (1) 对每个分区中的文档进行排序,因此最早的 orderDate 位于最前面。

  • output 使用在 Documents(文档)窗口中运行的 $addToSet 将每个唯一的蛋糕 type 添加到 cakeTypesForState 数组字段。

    窗口包含介于 unbounded 下限和 current 文档之间的文档。这意味着 $addToSet 返回一个数组,其中包含分区开头和当前文档之间文档的非重复蛋糕 type 字段。

在此示例输出中,CAWA 的蛋糕 type 数组会显示在 cakeTypesForState 字段中:

{ "_id" : 4, "type" : "strawberry", "orderDate" : ISODate("2019-05-18T16:09:01Z"),
"state" : "CA", "price" : 41, "quantity" : 162,
"cakeTypesForState" : [ "strawberry" ] }
{ "_id" : 0, "type" : "chocolate", "orderDate" : ISODate("2020-05-18T14:10:30Z"),
"state" : "CA", "price" : 13, "quantity" : 120,
"cakeTypesForState" : [ "strawberry", "chocolate" ] }
{ "_id" : 2, "type" : "vanilla", "orderDate" : ISODate("2021-01-11T06:31:15Z"),
"state" : "CA", "price" : 12, "quantity" : 145,
"cakeTypesForState" : [ "strawberry", "vanilla", "chocolate" ] }
{ "_id" : 5, "type" : "strawberry", "orderDate" : ISODate("2019-01-08T06:12:03Z"),
"state" : "WA", "price" : 43, "quantity" : 134,
"cakeTypesForState" : [ "strawberry" ] }
{ "_id" : 3, "type" : "vanilla", "orderDate" : ISODate("2020-02-08T13:13:23Z"),
"state" : "WA", "price" : 13, "quantity" : 104,
"cakeTypesForState" : [ "vanilla", "strawberry" ] }
{ "_id" : 1, "type" : "chocolate", "orderDate" : ISODate("2021-03-20T11:30:05Z"),
"state" : "WA", "price" : 14, "quantity" : 140,
"cakeTypesForState" : [ "vanilla", "chocolate", "strawberry" ] }

后退

$add