View a markdown version of this page

$添加 ToSet - Amazon DocumentDB

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

$添加 ToSet

$addToSet聚合运算符从每个组的指定表达式中返回一个由唯一值组成的数组。它在$group阶段内用于累积不同的值,自动消除重复值。

参数

  • expression:要为组中每个文档计算的表达式。

示例(MongoDB Shell)

以下示例演示如何使用$addToSet运营商收集为每位客户下单的独特城市。

创建示例文档

db.orders.insertMany([ { _id: 1, customer: "Alice", city: "Seattle", amount: 100 }, { _id: 2, customer: "Alice", city: "Portland", amount: 150 }, { _id: 3, customer: "Bob", city: "Seattle", amount: 200 }, { _id: 4, customer: "Alice", city: "Seattle", amount: 75 }, { _id: 5, customer: "Bob", city: "Boston", amount: 300 } ]);

查询示例

db.orders.aggregate([ { $group: { _id: "$customer", cities: { $addToSet: "$city" } } } ]);

输出

[ { _id: 'Bob', cities: [ 'Seattle', 'Boston' ] }, { _id: 'Alice', cities: [ 'Seattle', 'Portland' ] } ]

窗口运算符用法示例(MongoDB Shell)

8.0.2 版中的新内容。

该$addToSet操作员还可以在$setWindowFields舞台中用作窗口操作员。在此上下文中,它返回每个窗口中文档的指定表达式的唯一值的数组。您可以在output字段下指定运算符,也可以选择使用window文档定义窗口边界。

注意

在中用作窗口运算符时$setWindowFields,中间数据限制$addToSet为 100 MB。超过此限制的操作会返回错误。

创建示例文档

db.visits.insertMany([ { _id: 1, customer: "Alice", day: 1, city: "Seattle" }, { _id: 2, customer: "Alice", day: 2, city: "Portland" }, { _id: 3, customer: "Alice", day: 3, city: "Seattle" }, { _id: 4, customer: "Bob", day: 1, city: "Boston" }, { _id: 5, customer: "Bob", day: 2, city: "Boston" } ]);

查询示例

以下示例对文档进行分区customer,按分区排序day,并返回从分区开始到当前文档的一组唯一city值。

db.visits.aggregate([ { $setWindowFields: { partitionBy: "$customer", sortBy: { day: 1 }, output: { citiesSoFar: { $addToSet: "$city", window: { documents: ["unbounded", "current"] } } } } } ]);

输出

[ { "_id": 1, "customer": "Alice", "day": 1, "city": "Seattle", "citiesSoFar": [ "Seattle" ] }, { "_id": 2, "customer": "Alice", "day": 2, "city": "Portland", "citiesSoFar": [ "Portland", "Seattle" ] }, { "_id": 3, "customer": "Alice", "day": 3, "city": "Seattle", "citiesSoFar": [ "Portland", "Seattle" ] }, { "_id": 4, "customer": "Bob", "day": 1, "city": "Boston", "citiesSoFar": [ "Boston" ] }, { "_id": 5, "customer": "Bob", "day": 2, "city": "Boston", "citiesSoFar": [ "Boston" ] } ]

每个文档都添加citiesSoFar了从开始到当前文档的分区内的一组唯一city值。与累加器形式一样,不能保证返回数组中值的顺序。

代码示例

要查看使用$addToSet运算符的代码示例,请选择要使用的语言的选项卡。以下示例显示了累加器的用法(输入$group)和窗口运算符的用法(输入$setWindowFields):

Node.js
const { MongoClient } = require('mongodb'); async function example() { const client = await MongoClient.connect('mongodb://<username>:<password>@<cluster-endpoint>:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false'); const db = client.db('test'); // Accumulator usage: collect unique values per group const orders = db.collection('orders'); await orders.insertMany([ { _id: 1, customer: "Alice", city: "Seattle", amount: 100 }, { _id: 2, customer: "Alice", city: "Portland", amount: 150 }, { _id: 3, customer: "Bob", city: "Seattle", amount: 200 }, { _id: 4, customer: "Alice", city: "Seattle", amount: 75 }, { _id: 5, customer: "Bob", city: "Boston", amount: 300 } ]); const accumulatorResult = await orders.aggregate([ { $group: { _id: "$customer", cities: { $addToSet: "$city" } } } ]).toArray(); console.log('Accumulator result:', accumulatorResult); // Window operator usage: running set of unique values within each partition const visits = db.collection('visits'); await visits.insertMany([ { _id: 1, customer: "Alice", day: 1, city: "Seattle" }, { _id: 2, customer: "Alice", day: 2, city: "Portland" }, { _id: 3, customer: "Alice", day: 3, city: "Seattle" }, { _id: 4, customer: "Bob", day: 1, city: "Boston" }, { _id: 5, customer: "Bob", day: 2, city: "Boston" } ]); const windowResult = await visits.aggregate([ { $setWindowFields: { partitionBy: "$customer", sortBy: { day: 1 }, output: { citiesSoFar: { $addToSet: "$city", window: { documents: ["unbounded", "current"] } } } } } ]).toArray(); console.log('Window result:', windowResult); await client.close(); } example();
Python
from pymongo import MongoClient def example(): client = MongoClient('mongodb://<username>:<password>@<cluster-endpoint>:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false') db = client['test'] # Accumulator usage: collect unique values per group orders = db['orders'] orders.insert_many([ { '_id': 1, 'customer': 'Alice', 'city': 'Seattle', 'amount': 100 }, { '_id': 2, 'customer': 'Alice', 'city': 'Portland', 'amount': 150 }, { '_id': 3, 'customer': 'Bob', 'city': 'Seattle', 'amount': 200 }, { '_id': 4, 'customer': 'Alice', 'city': 'Seattle', 'amount': 75 }, { '_id': 5, 'customer': 'Bob', 'city': 'Boston', 'amount': 300 } ]) accumulator_result = list(orders.aggregate([ { '$group': { '_id': '$customer', 'cities': { '$addToSet': '$city' } } } ])) print('Accumulator result:', accumulator_result) # Window operator usage: running set of unique values within each partition visits = db['visits'] visits.insert_many([ { '_id': 1, 'customer': 'Alice', 'day': 1, 'city': 'Seattle' }, { '_id': 2, 'customer': 'Alice', 'day': 2, 'city': 'Portland' }, { '_id': 3, 'customer': 'Alice', 'day': 3, 'city': 'Seattle' }, { '_id': 4, 'customer': 'Bob', 'day': 1, 'city': 'Boston' }, { '_id': 5, 'customer': 'Bob', 'day': 2, 'city': 'Boston' } ]) window_result = list(visits.aggregate([ { '$setWindowFields': { 'partitionBy': '$customer', 'sortBy': { 'day': 1 }, 'output': { 'citiesSoFar': { '$addToSet': '$city', 'window': { 'documents': ['unbounded', 'current'] } } } } } ])) print('Window result:', window_result) client.close() example()