Database Manual / Aggregation Operations / Aggregation Pipeline / Complete Pipeline Examples

Perform One-to-One Joins执行一对一连接

This tutorial illustrates how to construct an aggregation pipeline, perform the aggregation on a collection, and display the results using the language of your choice.本教程说明了如何构建聚合管道,对集合执行聚合,并使用您选择的语言显示结果。

About This Task关于此任务

This tutorial demonstrates how to combine data from a collection that describes product information with another collection that describes customer orders. The results show a list of all orders placed in 2020 and includes the product details associated with each order.本教程演示了如何将描述产品信息的集合的数据与描述客户订单的另一个集合的数据组合在一起。结果显示了2020年所有订单的列表,并包括与每个订单相关的产品详细信息。

This aggregation performs a one-to-one join. A one-to-one join occurs when a document in one collection has a field value that matches a single document in another collection that has the same field value. The aggregation matches these documents on the field value and combines information from both sources into one result.此聚合执行一对一连接。当一个集合中的文档的字段值与另一个具有相同字段值的集合中的单个文档匹配时,就会发生一对一联接。聚合在字段值上匹配这些文档,并将来自两个来源的信息组合成一个结果。

Note

A one-to-one join does not require the documents to have a one-to-one relationship. To learn more about this data relationship, see the Wikipedia entry about One-to-one (data model).一对一联接不要求文档具有一对一关系。要了解有关此数据关系的更多信息,请参阅维基百科中关于一对一(数据模型)的条目。

Before You Begin开始之前


Use the Select your language drop-down menu in the upper-right to set the language of the following examples or select MongoDB Shell.使用右上角的“选择语言”下拉菜单设置以下示例的语言,或选择MongoDB Shell。


MongoDB Shell

This example uses two collections:此示例使用两个集合:

  • orders: documents that describe individual orders for products in a shop:描述商店中单个产品订单的文档
  • products: documents that describe the products that a shop sells:描述商店销售产品的文档

An order can only contain one product. The aggregation uses a one-to-one join to match an order document to the corresponding product document. The aggregation joins the collections by the product_id field that exists in documents in both collections.一个订单只能包含一个产品。聚合使用一对一连接将订单文档与相应的产品文档相匹配。聚合通过两个集合中文档中存在的product_id字段将集合连接起来。

To create the orders and products collections, use the insertMany() method:要创建ordersproducts集合,请使用insertMany()方法:

db.orders.insertMany( [
{
customer_id: "elise_smith@myemail.com",
orderdate: new Date("2020-05-30T08:35:52Z"),
product_id: "a1b2c3d4",
value: 431.43
},
{
customer_id: "tj@wheresmyemail.com",
orderdate: new Date("2019-05-28T19:13:32Z"),
product_id: "z9y8x7w6",
value: 5.01
},
{
customer_id: "oranieri@warmmail.com",
orderdate: new Date("2020-01-01T08:25:37Z"),
product_id: "ff11gg22hh33",
value: 63.13
},
{
customer_id: "jjones@tepidmail.com",
orderdate: new Date("2020-12-26T08:55:46Z"),
product_id: "a1b2c3d4",
value: 429.65
}
] )
db.products.insertMany( [
{
p_id: "a1b2c3d4",
name: "Asus Laptop",
category: "ELECTRONICS",
description: "Good value laptop for students"
},
{
p_id: "z9y8x7w6",
name: "The Day Of The Triffids",
category: "BOOKS",
description: "Classic post-apocalyptic novel"
},
{
p_id: "ff11gg22hh33",
name: "Morphy Richardds Food Mixer",
category: "KITCHENWARE",
description: "Luxury mixer turning good cakes into great"
},
{
p_id: "pqr678st",
name: "Karcher Hose Set",
category: "GARDEN",
description: "Hose + nozzles + winder for tidy storage"
}
] )
C

Create the Template App创建模板应用程序

Before you begin following this aggregation tutorial, you must set up a new C app. You can use this app to connect to a MongoDB deployment, insert sample data into MongoDB, and run the aggregation pipeline.在开始学习此聚合教程之前,您必须设置一个新的C应用程序。您可以使用此应用程序连接到MongoDB部署,将示例数据插入MongoDB,并运行聚合管道。

Tip

To learn how to install the driver and connect to MongoDB, see the Get Started with the C Driver guide.要了解如何安装驱动程序并连接到MongoDB,请参阅C驱动程序入门指南。

To learn more about performing aggregations in the C Driver, see the Aggregation guide.要了解有关在C驱动程序中执行聚合的更多信息,请参阅聚合指南

After you install the driver, create a file called agg-tutorial.c. Paste the following code in this file to create an app template for the aggregation tutorials.安装驱动程序后,创建一个名为agg-tutorialc的文件。将以下代码粘贴到此文件中,为聚合教程创建应用程序模板。

Important

In the following code, read the code comments to find the sections of the code that you must modify for the tutorial you are following.在下面的代码中,阅读代码注释,找到您必须为正在学习的教程修改的代码部分。

If you attempt to run the code without making any changes, you will encounter a connection error.如果您尝试在不进行任何更改的情况下运行代码,您将遇到连接错误。

#include <stdio.h>
#include <bson/bson.h>
#include <mongoc/mongoc.h>

int main(void)
{
mongoc_init();

// Replace the placeholder with your connection string.
char *uri = "<connection string>";
mongoc_client_t* client = mongoc_client_new(uri);

// Get a reference to relevant collections.
// ... mongoc_collection_t *some_coll = mongoc_client_get_collection(client, "agg_tutorials_db", "some_coll");
// ... mongoc_collection_t *another_coll = mongoc_client_get_collection(client, "agg_tutorials_db", "another_coll");

// Delete any existing documents in collections if needed.
// ... {
// ... bson_t *filter = bson_new();
// ... bson_error_t error;
// ... if (!mongoc_collection_delete_many(some_coll, filter, NULL, NULL, &error))
// ... {
// ... fprintf(stderr, "Delete error: %s\n", error.message);
// ... }
// ... bson_destroy(filter);
// ... }

// Insert sample data into the collection or collections.
// ... {
// ... size_t num_docs = ...;
// ... bson_t *docs[num_docs];
// ...
// ... docs[0] = ...;
// ...
// ... bson_error_t error;
// ... if (!mongoc_collection_insert_many(some_coll, (const bson_t **)docs, num_docs, NULL, NULL, &error))
// ... {
// ... fprintf(stderr, "Insert error: %s\n", error.message);
// ... }
// ...
// ... for (int i = 0; i < num_docs; i++)
// ... {
// ... bson_destroy(docs[i]);
// ... }
// ... }

{
const bson_t *doc;

// Add code to create pipeline stages.
bson_t *pipeline = BCON_NEW("pipeline", "[",
// ... Add pipeline stages here.
"]");

// Run the aggregation.
// ... mongoc_cursor_t *results = mongoc_collection_aggregate(some_coll, MONGOC_QUERY_NONE, pipeline, NULL, NULL);

bson_destroy(pipeline);

// Print the aggregation results.
while (mongoc_cursor_next(results, &doc))
{
char *str = bson_as_canonical_extended_json(doc, NULL);
printf("%s\n", str);
bson_free(str);
}
bson_error_t error;
if (mongoc_cursor_error(results, &error))
{
fprintf(stderr, "Aggregation error: %s\n", error.message);
}

mongoc_cursor_destroy(results);
}

// Clean up resources.
// ... mongoc_collection_destroy(some_coll);
mongoc_client_destroy(client);
mongoc_cleanup();

return EXIT_SUCCESS;
}

For every tutorial, you must replace the connection string placeholder with your deployment's connection string.对于每个教程,您必须将连接字符串占位符替换为部署的连接字符串。

Tip

To learn how to locate your deployment's connection string, see the Create a Connection String step of the C Get Started guide.要了解如何定位部署的连接字符串,请参阅《C入门》指南的创建连接字符串步骤。

For example, if your connection string is "mongodb+srv://mongodb-example:27017", your connection string assignment resembles the following:例如,如果连接字符串是"mongodb+srv://mongodb-example:27017",连接字符串分配类似于以下内容:

char *uri = "mongodb+srv://mongodb-example:27017";

Create the Collection创建集合

This example uses two collections:此示例使用两个集合:

  • orders: documents that describe individual orders for products in a shop:描述商店中单个产品订单的文档
  • products: documents that describe the products that a shop sells:描述商店销售产品的文档

An order can only contain one product. The aggregation uses a one-to-one join to match an order document to the corresponding product document. The aggregation joins the collections by the product_id field that exists in documents in both collections.一个订单只能包含一个产品。聚合使用一对一连接将订单文档与相应的产品文档相匹配。聚合通过两个集合中文档中存在的product_id字段将集合连接起来。

To create the orders and products collections and insert the sample data, add the following code to your application:要创建ordersproducts集合并插入示例数据,请将以下代码添加到应用程序中:

mongoc_collection_t *orders = mongoc_client_get_collection(client, "agg_tutorials_db", "orders");
mongoc_collection_t *products = mongoc_client_get_collection(client, "agg_tutorials_db", "products");

{
bson_t *filter = bson_new();
bson_error_t error;
if (!mongoc_collection_delete_many(orders, filter, NULL, NULL, &error))
{
fprintf(stderr, "Delete error: %s\n", error.message);
}
if (!mongoc_collection_delete_many(products, filter, NULL, NULL, &error))
{
fprintf(stderr, "Delete error: %s\n", error.message);
}
bson_destroy(filter);
}

{
size_t num_docs = 4;
bson_t *order_docs[num_docs];

order_docs[0] = BCON_NEW(
"customer_id", BCON_UTF8("elise_smith@myemail.com"),
"orderdate", BCON_DATE_TIME(1590822952000UL), // 2020-05-30T08:35:52Z
"product_id", BCON_UTF8("a1b2c3d4"),
"value", BCON_DOUBLE(431.43));

order_docs[1] = BCON_NEW(
"customer_id", BCON_UTF8("tj@wheresmyemail.com"),
"orderdate", BCON_DATE_TIME(1559063612000UL), // 2019-05-28T19:13:32Z
"product_id", BCON_UTF8("z9y8x7w6"),
"value", BCON_DOUBLE(5.01));

order_docs[2] = BCON_NEW(
"customer_id", BCON_UTF8("oranieri@warmmail.com"),
"orderdate", BCON_DATE_TIME(1577869537000UL), // 2020-01-01T08:25:37Z
"product_id", BCON_UTF8("ff11gg22hh33"),
"value", BCON_DOUBLE(63.13));

order_docs[3] = BCON_NEW(
"customer_id", BCON_UTF8("jjones@tepidmail.com"),
"orderdate", BCON_DATE_TIME(1608976546000UL), // 2020-12-26T08:55:46Z
"product_id", BCON_UTF8("a1b2c3d4"),
"value", BCON_DOUBLE(429.65));

bson_error_t error;
if (!mongoc_collection_insert_many(orders, (const bson_t **)order_docs, num_docs, NULL, NULL, &error))
{
fprintf(stderr, "Insert error: %s\n", error.message);
}

for (int i = 0; i < num_docs; i++)
{
bson_destroy(order_docs[i]);
}
}

{
size_t num_docs = 4;
bson_t *product_docs[num_docs];

product_docs[0] = BCON_NEW(
"id", BCON_UTF8("a1b2c3d4"),
"name", BCON_UTF8("Asus Laptop"),
"category", BCON_UTF8("ELECTRONICS"),
"description", BCON_UTF8("Good value laptop for students"));

product_docs[1] = BCON_NEW(
"id", BCON_UTF8("z9y8x7w6"),
"name", BCON_UTF8("The Day Of The Triffids"),
"category", BCON_UTF8("BOOKS"),
"description", BCON_UTF8("Classic post-apocalyptic novel"));

product_docs[2] = BCON_NEW(
"id", BCON_UTF8("ff11gg22hh33"),
"name", BCON_UTF8("Morphy Richardds Food Mixer"),
"category", BCON_UTF8("KITCHENWARE"),
"description", BCON_UTF8("Luxury mixer turning good cakes into great"));

product_docs[3] = BCON_NEW(
"id", BCON_UTF8("pqr678st"),
"name", BCON_UTF8("Karcher Hose Set"),
"category", BCON_UTF8("GARDEN"),
"description", BCON_UTF8("Hose + nozzles + winder for tidy storage"));

bson_error_t error;
if (!mongoc_collection_insert_many(products, (const bson_t **)product_docs, num_docs, NULL, NULL, &error))
{
fprintf(stderr, "Insert error: %s\n", error.message);
}

for (int i = 0; i < num_docs; i++)
{
bson_destroy(product_docs[i]);
}
}
C++11

Create the Template App创建模板应用程序

Before you begin following an aggregation tutorial, you must set up a new C++ app. You can use this app to connect to a MongoDB deployment, insert sample data into MongoDB, and run the aggregation pipeline.在开始学习聚合教程之前,您必须设置一个新的C++应用程序。您可以使用此应用程序连接到MongoDB部署,将示例数据插入MongoDB,并运行聚合管道。

Tip

To learn how to install the driver and connect to MongoDB, see the Get Started with C++ tutorial.要了解如何安装驱动程序并连接到MongoDB,请参阅C++入门教程

To learn more about using the C++ driver, see the API documentation.要了解有关使用C++驱动程序的更多信息,请参阅API文档

To learn more about performing aggregations in the C++ Driver, see the Aggregation guide.要了解有关在C++驱动程序中执行聚合的更多信息,请参阅聚合指南

After you install the driver, create a file called agg-tutorial.cpp. Paste the following code in this file to create an app template for the aggregation tutorials.安装驱动程序后,创建一个名为agg-tutorial.cpp的文件。将以下代码粘贴到此文件中,为聚合教程创建应用程序模板。

Important

In the following code, read the code comments to find the sections of the code that you must modify for the tutorial you are following.在下面的代码中,阅读代码注释,找到您必须为正在学习的教程修改的代码部分。

If you attempt to run the code without making any changes, you will encounter a connection error.如果您尝试在不进行任何更改的情况下运行代码,您将遇到连接错误。

#include <iostream>
#include <bsoncxx/builder/basic/document.hpp>
#include <bsoncxx/builder/basic/kvp.hpp>
#include <bsoncxx/json.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/instance.hpp>
#include <mongocxx/pipeline.hpp>
#include <mongocxx/uri.hpp>
#include <chrono>

using bsoncxx::builder::basic::kvp;
using bsoncxx::builder::basic::make_document;
using bsoncxx::builder::basic::make_array;

int main() {
mongocxx::instance instance;

// Replace the placeholder with your connection string.
mongocxx::uri uri("<connection string>");
mongocxx::client client(uri);

auto db = client["agg_tutorials_db"];
// Delete existing data in the database, if necessary.
db.drop();

// Get a reference to relevant collections.
// ... auto some_coll = db["..."];
// ... auto another_coll = db["..."];

// Insert sample data into the collection or collections.
// ... some_coll.insert_many(docs);

// Create an empty pipelne.
mongocxx::pipeline pipeline;

// Add code to create pipeline stages.
// pipeline.match(make_document(...));

// Run the aggregation and print the results.
auto cursor = orders.aggregate(pipeline);
for (auto&& doc : cursor) {
std::cout << bsoncxx::to_json(doc, bsoncxx::ExtendedJsonMode::k_relaxed) << std::endl;
}
}

For every tutorial, you must replace the connection string placeholder with your deployment's connection string.对于每个教程,您必须将连接字符串占位符替换为部署的连接字符串。

Tip

To learn how to locate your deployment's connection string, see the Create a Connection String step of the C++ Get Started tutorial.要了解如何定位部署的连接字符串,请参阅C++入门教程的创建连接字符串步骤。

For example, if your connection string is "mongodb+srv://mongodb-example:27017", your connection string assignment resembles the following:例如,如果连接字符串是"mongodb+srv://mongodb-example:27017",连接字符串分配类似于以下内容:

mongocxx::uri uri{"mongodb+srv://mongodb-example:27017"};

Create the Collection创建集合

This example uses two collections:此示例使用两个集合:

  • orders: documents that describe individual orders for products in a shop:描述商店中单个产品订单的文档
  • products: documents that describe the products that a shop sells:描述商店销售产品的文档

An order can only contain one product. The aggregation uses a one-to-one join to match an order document to the corresponding product document. The aggregation joins the collections by the product_id field that exists in documents in both collections.一个订单只能包含一个产品。聚合使用一对一连接将订单文档与相应的产品文档相匹配。聚合通过两个集合中文档中存在的product_id字段将集合连接起来。

To create the orders and products collections and insert the sample data, add the following code to your application:要创建ordersproducts集合并插入示例数据,请将以下代码添加到应用程序中:

auto orders = db["orders"];
auto products = db["products"];

std::vector<bsoncxx::document::value> order_docs = {bsoncxx::from_json(R"({
"customer_id": "elise_smith@myemail.com",
"orderdate": {"$date": 1590821752000},
"product_id": "a1b2c3d4",
"value": 431.43
})"),
bsoncxx::from_json(R"({
"customer_id": "tj@wheresmyemail.com",
"orderdate": {"$date": 1559062412},
"product_id": "z9y8x7w6",
"value": 5.01
})"),
bsoncxx::from_json(R"({
"customer_id": "oranieri@warmmail.com",
"orderdate": {"$date": 1577861137},
"product_id": "ff11gg22hh33",
"value": 63.13
})"),
bsoncxx::from_json(R"({
"customer_id": "jjones@tepidmail.com",
"orderdate": {"$date": 1608972946000},
"product_id": "a1b2c3d4",
"value": 429.65
})")};

orders.insert_many(order_docs); // Might throw an exception

std::vector<bsoncxx::document::value> product_docs = {bsoncxx::from_json(R"({
"id": "a1b2c3d4",
"name": "Asus Laptop",
"category": "ELECTRONICS",
"description": "Good value laptop for students"
})"),
bsoncxx::from_json(R"({
"id": "z9y8x7w6",
"name": "The Day Of The Triffids",
"category": "BOOKS",
"description": "Classic post-apocalyptic novel"
})"),
bsoncxx::from_json(R"({
"id": "ff11gg22hh33",
"name": "Morphy Richardds Food Mixer",
"category": "KITCHENWARE",
"description": "Luxury mixer turning good cakes into great"
})"),
bsoncxx::from_json(R"({
"id": "pqr678st",
"name": "Karcher Hose Set",
"category": "GARDEN",
"description": "Hose + nozzles + winder for tidy storage"
})")};

products.insert_many(product_docs); // Might throw an exception
C#

Create the Template App创建模板应用程序

Before you begin following this aggregation tutorial, you must set up a new C#/.NET app. You can use this app to connect to a MongoDB deployment, insert sample data into MongoDB, and run the aggregation pipeline.在开始学习此聚合教程之前,您必须设置一个新的C#/NET应用程序。您可以使用此应用程序连接到MongoDB部署,将示例数据插入MongoDB,并运行聚合管道。

Tip

To learn how to install the driver and connect to MongoDB, see the C#/.NET Driver Quick Start guide.要了解如何安装驱动程序并连接到MongoDB,请参阅C#/.NET驱动程序快速入门指南

To learn more about performing aggregations in the C#/.NET Driver, see the Aggregation guide.要了解有关在C#/NET驱动程序中执行聚合的更多信息,请参阅聚合指南

After you install the driver, paste the following code into your Program.cs file to create an app template for the aggregation tutorials.安装驱动程序后,将以下代码粘贴到Program.cs文件中,为聚合教程创建应用程序模板。

Important

In the following code, read the code comments to find the sections of the code that you must modify for the tutorial you are following.在下面的代码中,阅读代码注释,找到您必须为正在学习的教程修改的代码部分。

If you attempt to run the code without making any changes, you will encounter a connection error.如果您尝试在不进行任何更改的情况下运行代码,您将遇到连接错误。

using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;

// Define data model classes.
// ... public class MyClass { ... }

// Replace the placeholder with your connection string.
var uri = "<connection string>";
var client = new MongoClient(uri);
var aggDB = client.GetDatabase("agg_tutorials_db");

// Get a reference to relevant collections.
// ... var someColl = aggDB.GetCollection<MyClass>("someColl");
// ... var anotherColl = aggDB.GetCollection<MyClass>("anotherColl");

// Delete any existing documents in collections if needed.
// ... someColl.DeleteMany(Builders<MyClass>.Filter.Empty);

// Insert sample data into the collection or collections.
// ... someColl.InsertMany(new List<MyClass> { ... });

// Add code to chain pipeline stages to the Aggregate() method.
// ... var results = someColl.Aggregate().Match(...);

// Print the aggregation results.
foreach (var result in results.ToList())
{
Console.WriteLine(result);
}

For every tutorial, you must replace the connection string placeholder with your deployment's connection string.对于每个教程,您必须将连接字符串占位符替换为部署的连接字符串。

Tip

To learn how to locate your deployment's connection string, see the Set Up a Free Tier Cluster in Atlas step of the C# Quick Start guide.要了解如何定位部署的连接字符串,请参阅《C#快速入门》指南的在Atlas中设置免费层集群步骤。

For example, if your connection string is "mongodb+srv://mongodb-example:27017", your connection string assignment resembles the following:例如,如果连接字符串是"mongodb+srv://mongodb-example:27017",连接字符串分配类似于以下内容:

var uri = "mongodb+srv://mongodb-example:27017";

Create the Collection创建集合

This example uses two collections:此示例使用两个集合:

  • orders: documents that describe individual orders for products in a shop:描述商店中单个产品订单的文档
  • products: documents that describe the products that a shop sells:描述商店销售产品的文档

An order must contain one product. The aggregation uses a one-to-one join to match an order document to the corresponding product document. The aggregation joins the collections by the ProductId field that exists in documents in both collections.订单必须包含一个产品。聚合使用一对一连接将订单文档与相应的产品文档相匹配。聚合通过两个集合中文档中存在的ProductId字段将集合连接起来。

First, create C# classes to model the data in the orders and products collections:首先,创建C#类来对ordersproducts集合中的数据进行建模:

public class Order
{
[BsonId]
public ObjectId Id { get; set; }
public required string CustomerId { get; set; }
public DateTime OrderDate { get; set; }
public required string ProductId { get; set; }
public double Value { get; set; }
}

public class Product
{
[BsonId]
public required string Id { get; set; }

public string Name { get; set; } = "";
public string Category { get; set; } = "";
public string Description { get; set; } = "";
}

To create the orders and products collections and insert the sample data, add the following code to your application:要创建ordersproducts集合并插入示例数据,请将以下代码添加到应用程序中:

var orders = aggDB.GetCollection<Order>("orders");
var products = aggDB.GetCollection<Product>("products");

orders = aggDB.GetCollection<Order>("orders");
products = aggDB.GetCollection<Product>("products");

orders.InsertMany(new List<Order>
{
new Order
{
CustomerId = "elise_smith@myemail.com",
OrderDate = DateTime.Parse("2020-05-30T08:35:52Z"),
ProductId = "a1b2c3d4",
Value = 431.43
},
new Order
{
CustomerId = "tj@wheresmyemail.com",
OrderDate = DateTime.Parse("2019-05-28T19:13:32Z"),
ProductId = "z9y8x7w6",
Value = 5.01
},
new Order
{
CustomerId = "oranieri@warmmail.com",
OrderDate = DateTime.Parse("2020-01-01T08:25:37Z"),
ProductId = "ff11gg22hh33",
Value = 63.13
},
new Order
{
CustomerId = "jjones@tepidmail.com",
OrderDate = DateTime.Parse("2020-12-26T08:55:46Z"),
ProductId = "a1b2c3d4",
Value = 429.65
}
});

products.InsertMany(new List<Product>
{
new Product
{
Id = "a1b2c3d4",
Name = "Asus Laptop",
Category = "ELECTRONICS",
Description = "Good value laptop for students"
},
new Product
{
Id = "z9y8x7w6",
Name = "The Day Of The Triffids",
Category = "BOOKS",
Description = "Classic post-apocalyptic novel"
},
new Product
{
Id = "ff11gg22hh33",
Name = "Morphy Richardds Food Mixer",
Category = "KITCHENWARE",
Description = "Luxury mixer turning good cakes into great"
},
new Product
{
Id = "pqr678st",
Name = "Karcher Hose Set",
Category = "GARDEN",
Description = "Hose + nozzles + winder for tidy storage"
}
});
Go

Create the Template App创建模板应用程序

Before you begin following this aggregation tutorial, you must set up a new Go app. You can use this app to connect to a MongoDB deployment, insert sample data into MongoDB, and run the aggregation pipeline.在开始学习此聚合教程之前,您必须设置一个新的Go应用程序。您可以使用此应用程序连接到MongoDB部署,将示例数据插入MongoDB,并运行聚合管道。

Tip

To learn how to install the driver and connect to MongoDB, see the Go Driver Quick Start guide.要了解如何安装驱动程序并连接到MongoDB,请参阅Go驱动程序快速入门指南

To learn more about performing aggregations in the Go Driver, see the Aggregation guide.要了解有关在Go驱动程序中执行聚合的更多信息,请参阅聚合指南

After you install the driver, create a file called agg_tutorial.go. Paste the following code in this file to create an app template for the aggregation tutorials.安装驱动程序后,创建一个名为agg_tutorial.go的文件。将以下代码粘贴到此文件中,为聚合教程创建应用程序模板。

Important

In the following code, read the code comments to find the sections of the code that you must modify for the tutorial you are following.在下面的代码中,阅读代码注释,找到您必须为正在学习的教程修改的代码部分。

If you attempt to run the code without making any changes, you will encounter a connection error.如果您尝试在不进行任何更改的情况下运行代码,您将遇到连接错误。

package main

import (
"context"
"fmt"
"log"

"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/v2/mongo/options"
)

// Define structs.
// type MyStruct struct { ... }

func main() {
ctx := context.Background()
// Replace the placeholder with your connection string.
const uri = "<connection string>"

client, err := mongo.Connect(options.Client().ApplyURI(uri))
if err != nil {
log.Fatal(err)
}

defer func() {
if err = client.Disconnect(ctx); err != nil {
log.Fatal(err)
}
}()

aggDB := client.Database("agg_tutorials_db")

// Get a reference to relevant collections.
// ... someColl := aggDB.Collection("...")
// ... anotherColl := aggDB.Collection("...")

// Delete any existing documents in collections if needed.
// ... someColl.DeleteMany(cxt, bson.D{})

// Insert sample data into the collection or collections.
// ... _, err = someColl.InsertMany(...)

// Add code to create pipeline stages.
// ... myStage := bson.D{{...}}

// Create a pipeline that includes the stages.
// ... pipeline := mongo.Pipeline{...}

// Run the aggregation.
// ... cursor, err := someColl.Aggregate(ctx, pipeline)

if err != nil {
log.Fatal(err)
}

defer func() {
if err := cursor.Close(ctx); err != nil {
log.Fatalf("failed to close cursor: %v", err)
}
}()

// Decode the aggregation results.
var results []bson.D
if err = cursor.All(ctx, &results); err != nil {
log.Fatalf("failed to decode results: %v", err)
}

// Print the aggregation results.
for _, result := range results {
res, _ := bson.MarshalExtJSON(result, false, false)
fmt.Println(string(res))
}
}

For every tutorial, you must replace the connection string placeholder with your deployment's connection string.对于每个教程,您必须将连接字符串占位符替换为部署的连接字符串。

Tip

To learn how to locate your deployment's connection string, see the Create a MongoDB Cluster step of the Go Quick Start guide.要了解如何定位部署的连接字符串,请参阅Go快速入门指南的创建MongoDB集群步骤。

For example, if your connection string is "mongodb+srv://mongodb-example:27017", your connection string assignment resembles the following:例如,如果连接字符串是"mongodb+srv://mongodb-example:27017",连接字符串分配类似于以下内容:

const uri = "mongodb+srv://mongodb-example:27017";

Create the Collection创建集合

This example uses two collections:此示例使用两个集合:

  • orders: documents that describe individual orders for products in a shop:描述商店中单个产品订单的文档
  • products: documents that describe the products that a shop sells:描述商店销售产品的文档

An order can only contain one product. The aggregation uses a one-to-one join to match an order document to the corresponding product document. The aggregation joins the collections by the product_id field that exists in documents in both collections.一个订单只能包含一个产品。聚合使用一对一连接将订单文档与相应的产品文档相匹配。聚合通过两个集合中文档中存在的product_id字段将集合连接起来。

First, create Go structs to model the data in the orders and products collections:首先,创建Go结构体来对ordersproducts集合中的数据进行建模:

type Order struct {
CustomerID string `bson:"customer_id"`
OrderDate bson.DateTime `bson:"orderdate"`
ProductID string `bson:"product_id"`
Value float32 `bson:"value"`
}

type Product struct {
ID string `bson:"id"`
Name string `bson:"name"`
Category string `bson:"category"`
Description string `bson:"description"`
}

To create the orders and products collections and insert the sample data, add the following code to your application:要创建ordersproducts集合并插入示例数据,请将以下代码添加到应用程序中:

orders := aggDB.Collection("orders")
products := aggDB.Collection("products")

_, err = orders.InsertMany(ctx, []interface{}{
Order{
CustomerID: "elise_smith@myemail.com",
OrderDate: bson.NewDateTimeFromTime(time.Date(2020, 5, 30, 8, 35, 52, 0, time.UTC)),
ProductID: "a1b2c3d4",
Value: 431.43,
},
Order{
CustomerID: "tj@wheresmyemail.com",
OrderDate: bson.NewDateTimeFromTime(time.Date(2019, 5, 28, 19, 13, 32, 0, time.UTC)),
ProductID: "z9y8x7w6",
Value: 5.01,
},
Order{
CustomerID: "oranieri@warmmail.com",
OrderDate: bson.NewDateTimeFromTime(time.Date(2020, 01, 01, 8, 25, 37, 0, time.UTC)),
ProductID: "ff11gg22hh33",
Value: 63.13,
},
Order{
CustomerID: "jjones@tepidmail.com",
OrderDate: bson.NewDateTimeFromTime(time.Date(2020, 12, 26, 8, 55, 46, 0, time.UTC)),
ProductID: "a1b2c3d4",
Value: 429.65,
},
})
if err != nil {

log.Fatal(err)
}

_, err = products.InsertMany(ctx, []interface{}{
Product{
ID: "a1b2c3d4",
Name: "Asus Laptop",
Category: "ELECTRONICS",
Description: "Good value laptop for students",
},
Product{
ID: "z9y8x7w6",
Name: "The Day Of The Triffids",
Category: "BOOKS",
Description: "Classic post-apocalyptic novel",
},
Product{
ID: "ff11gg22hh33",
Name: "Morphy Richardds Food Mixer",
Category: "KITCHENWARE",
Description: "Luxury mixer turning good cakes into great",
},
Product{
ID: "pqr678st",
Name: "Karcher Hose Set",
Category: "GARDEN",
Description: "Hose + nozzles + winder for tidy storage",
},
})
if err != nil {
log.Fatal(err)
}
Java(Sync)

Create the Template App创建模板应用程序

Before you begin following an aggregation tutorial, you must set up a new Java app. You can use this app to connect to a MongoDB deployment, insert sample data into MongoDB, and run the aggregation pipeline.在开始学习聚合教程之前,您必须设置一个新的Java应用程序。您可以使用此应用程序连接到MongoDB部署,将示例数据插入MongoDB,并运行聚合管道。

Tip

To learn how to install the driver and connect to MongoDB, see the Get Started with the Java Driver guide.要了解如何安装驱动程序并连接到MongoDB,请参阅Java驱动程序入门指南

To learn more about performing aggregations in the Java Sync Driver, see the Aggregation guide.要了解有关在Java同步驱动程序中执行聚合的更多信息,请参阅聚合指南

After you install the driver, create a file called AggTutorial.java. Paste the following code in this file to create an app template for the aggregation tutorials.安装驱动程序后,创建一个名为AggTutorial.java的文件。将以下代码粘贴到此文件中,为聚合教程创建应用程序模板。

Important

In the following code, read the code comments to find the sections of the code that you must modify for the tutorial you are following.在下面的代码中,阅读代码注释,找到您必须为正在学习的教程修改的代码部分。

If you attempt to run the code without making any changes, you will encounter a connection error.如果您尝试在不进行任何更改的情况下运行代码,您将遇到连接错误。

package org.example;

// Modify imports for each tutorial as needed.
import com.mongodb.client.*;
import com.mongodb.client.model.Accumulators;
import com.mongodb.client.model.Aggregates;
import com.mongodb.client.model.Field;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Sorts;
import com.mongodb.client.model.Variable;
import org.bson.Document;
import org.bson.conversions.Bson;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class AggTutorial {
public static void main(String[] args) {
// Replace the placeholder with your connection string.
String uri = "<connection string>";

try (MongoClient mongoClient = MongoClients.create(uri)) {
MongoDatabase aggDB = mongoClient.getDatabase("agg_tutorials_db");

// Get a reference to relevant collections.
// ... MongoCollection<Document> someColl = ...
// ... MongoCollection<Document> anotherColl = ...

// Insert sample data into the collection or collections.
// ... someColl.insertMany(...);

// Create an empty pipeline array.
List<Bson> pipeline = new ArrayList<>();

// Add code to create pipeline stages.
// ... pipeline.add(...);

// Run the aggregation.
// ... AggregateIterable<Document> aggregationResult =
// someColl.aggregate(pipeline);

// Print the aggregation results.
for (Document document : aggregationResult) {
System.out.println(document.toJson());
}
}
}
}

For every tutorial, you must replace the connection string placeholder with your deployment's connection string.对于每个教程,您必须将连接字符串占位符替换为部署的连接字符串。

Tip

To learn how to locate your deployment's connection string, see the Create a Connection String step of the Java Sync Quick Start guide.要了解如何定位部署的连接字符串,请参阅《Java Sync快速入门》指南的创建连接字符串步骤。

For example, if your connection string is "mongodb+srv://mongodb-example:27017", your connection string assignment resembles the following:例如,如果连接字符串是"mongodb+srv://mongodb-example:27017",连接字符串分配类似于以下内容:

String uri = "mongodb+srv://mongodb-example:27017";

Create the Collection创建集合

This example uses two collections:此示例使用两个集合:

  • orders: documents that describe individual orders for products in a shop:描述商店中单个产品订单的文档
  • products: documents that describe the products that a shop sells:描述商店销售产品的文档

An order can only contain one product. The aggregation uses a one-to-one join to match an order document to the corresponding product document. The aggregation joins the collections by the product_id field that exists in documents in both collections.一个订单只能包含一个产品。聚合使用一对一连接将订单文档与相应的产品文档相匹配。聚合通过两个集合中文档中存在的product_id字段将集合连接起来。

To create the orders and products collections and insert the sample data, add the following code to your application:要创建ordersproducts集合并插入示例数据,请将以下代码添加到应用程序中:

MongoDatabase aggDB = mongoClient.getDatabase("agg_tutorials_db");
MongoCollection<Document> orders = aggDB.getCollection("orders");
MongoCollection<Document> products = aggDB.getCollection("products");

orders.insertMany(
Arrays.asList(
new Document("customer_id", "elise_smith@myemail.com")
.append("orderdate", LocalDateTime.parse("2020-05-30T08:35:52"))
.append("product_id", "a1b2c3d4")
.append("value", 431.43),
new Document("customer_id", "tj@wheresmyemail.com")
.append("orderdate", LocalDateTime.parse("2019-05-28T19:13:32"))
.append("product_id", "z9y8x7w6")
.append("value", 5.01),
new Document("customer_id", "oranieri@warmmail.com")
.append("orderdate", LocalDateTime.parse("2020-01-01T08:25:37"))
.append("product_id", "ff11gg22hh33")
.append("value", 63.13),
new Document("customer_id", "jjones@tepidmail.com")
.append("orderdate", LocalDateTime.parse("2020-12-26T08:55:46"))
.append("product_id", "a1b2c3d4")
.append("value", 429.65)
)
);

products.insertMany(
Arrays.asList(
new Document("id", "a1b2c3d4")
.append("name", "Asus Laptop")
.append("category", "ELECTRONICS")
.append("description", "Good value laptop for students"),
new Document("id", "z9y8x7w6")
.append("name", "The Day Of The Triffids")
.append("category", "BOOKS")
.append("description", "Classic post-apocalyptic novel"),
new Document("id", "ff11gg22hh33")
.append("name", "Morphy Richardds Food Mixer")
.append("category", "KITCHENWARE")
.append("description", "Luxury mixer turning good cakes into great"),
new Document("id", "pqr678st")
.append("name", "Karcher Hose Set")
.append("category", "GARDEN")
.append("description", "Hose + nozzles + winder for tidy storage")
)
);
Kotlin(Coroutine)

Create the Template App创建模板应用程序

Before you begin following an aggregation tutorial, you must set up a new Kotlin app. You can use this app to connect to a MongoDB deployment, insert sample data into MongoDB, and run the aggregation pipeline.在开始学习聚合教程之前,您必须设置一个新的Kotlin应用程序。您可以使用此应用程序连接到MongoDB部署,将示例数据插入MongoDB,并运行聚合管道。

Tip

To learn how to install the driver and connect to MongoDB, see the Kotlin Driver Quick Start guide.要了解如何安装驱动程序并连接到MongoDB,请参阅Kotlin驱动程序快速入门指南

To learn more about performing aggregations in the Kotlin Driver, see the Aggregation guide.要了解有关在Kotlin驱动程序中执行聚合的更多信息,请参阅聚合指南

In addition to the driver, you must also add the following dependencies to your build.gradle.kts file and reload your project:除了驱动程序,您还必须将以下依赖项添加到build.gradle.kts文件中并重新加载项目:

dependencies {
// Implements Kotlin serialization
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.5.1")
// Implements Kotlin date and time handling
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.1")
}

After you install the driver, create a file called AggTutorial.kt. Paste the following code in this file to create an app template for the aggregation tutorials.安装驱动程序后,创建一个名为AggTutorial.kt的文件。将以下代码粘贴到此文件中,为聚合教程创建应用程序模板。

Important

In the following code, read the code comments to find the sections of the code that you must modify for the tutorial you are following.在下面的代码中,阅读代码注释,找到您必须为正在学习的教程修改的代码部分。

If you attempt to run the code without making any changes, you will encounter a connection error.如果您尝试在不进行任何更改的情况下运行代码,您将遇到连接错误。

package org.example

// Modify imports for each tutorial as needed.
import com.mongodb.client.model.*
import com.mongodb.kotlin.client.coroutine.MongoClient
import kotlinx.coroutines.runBlocking
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.toJavaLocalDateTime
import kotlinx.serialization.Contextual
import kotlinx.serialization.Serializable
import org.bson.Document
import org.bson.conversions.Bson

// Define data classes.
@Serializable
data class MyClass(
...
)

suspend fun main() {
// Replace the placeholder with your connection string.
val uri = "<connection string>"

MongoClient.create(uri).use { mongoClient ->
val aggDB = mongoClient.getDatabase("agg_tutorials_db")

// Get a reference to relevant collections.
// ... val someColl = ...

// Delete any existing documents in collections if needed.
// ... someColl.deleteMany(empty())

// Insert sample data into the collection or collections.
// ... someColl.insertMany( ... )

// Create an empty pipeline.
val pipeline = mutableListOf<Bson>()

// Add code to create pipeline stages.
// ... pipeline.add(...)

// Run the aggregation.
// ... val aggregationResult = someColl.aggregate<Document>(pipeline)

// Print the aggregation results.
aggregationResult.collect { println(it) }
}
}

For every tutorial, you must replace the connection string placeholder with your deployment's connection string.对于每个教程,您必须将连接字符串占位符替换为部署的连接字符串。

Tip

To learn how to locate your deployment's connection string, see the Connect to your Cluster step of the Kotlin Driver Quick Start guide.要了解如何定位部署的连接字符串,请参阅Kotlin驱动程序快速入门指南的连接到集群步骤。

For example, if your connection string is "mongodb+srv://mongodb-example:27017", your connection string assignment resembles the following:例如,如果连接字符串是"mongodb+srv://mongodb-example:27017",连接字符串分配类似于以下内容:

val uri = "mongodb+srv://mongodb-example:27017"

Create the Collection创建集合

This example uses two collections:此示例使用两个集合:

  • orders: documents that describe individual orders for products in a shop:描述商店中单个产品订单的文档
  • products: documents that describe the products that a shop sells:描述商店销售产品的文档

An order can only contain one product. The aggregation uses a one-to-one join to match an order document to the corresponding product document. The aggregation joins the collections by the product_id field that exists in documents in both collections.一个订单只能包含一个产品。聚合使用一对一连接将订单文档与相应的产品文档相匹配。聚合通过两个集合中文档中存在的product_id字段将集合连接起来。

First, create Kotlin data classes to model the data in the orders and products collections:首先,创建Kotlin数据类来对ordersproducts集合中的数据进行建模:

@Serializable
data class Order(
val customerID: String,
@Contextual val orderDate: LocalDateTime,
val productID: String,
val value: Double
)

@Serializable
data class Product(
val ID: String,
val name: String,
val category: String,
val description: String
)

To create the orders and products collections and insert the sample data, add the following code to your application:要创建ordersproducts集合并插入示例数据,请将以下代码添加到应用程序中:

val orders = aggDB.getCollection<Order>("orders")
val products = aggDB.getCollection<Product>("products")

orders.deleteMany(Filters.empty());
products.deleteMany(Filters.empty());

orders.insertMany(
listOf(
Order("elise_smith@myemail.com", LocalDateTime.parse("2020-05-30T08:35:52"), "a1b2c3d4", 431.43),
Order("tj@wheresmyemail.com", LocalDateTime.parse("2019-05-28T19:13:32"), "z9y8x7w6", 5.01),
Order("oranieri@warmmail.com", LocalDateTime.parse("2020-01-01T08:25:37"), "ff11gg22hh33", 63.13),
Order("jjones@tepidmail.com", LocalDateTime.parse("2020-12-26T08:55:46"), "a1b2c3d4", 429.65)
)
)

products.insertMany(
listOf(
Product("a1b2c3d4", "Asus Laptop", "ELECTRONICS", "Good value laptop for students"),
Product("z9y8x7w6", "The Day Of The Triffids", "BOOKS", "Classic post-apocalyptic novel"),
Product(
"ff11gg22hh33",
"Morphy Richardds Food Mixer",
"KITCHENWARE",
"Luxury mixer turning good cakes into great"
),
Product("pqr678st", "Karcher Hose Set", "GARDEN", "Hose + nozzles + winder for tidy storage")
)
)
Node.js

Create the Template App创建模板应用程序

Before you begin following this aggregation tutorial, you must set up a new Node.js app. You can use this app to connect to a MongoDB deployment, insert sample data into MongoDB, and run the aggregation pipeline.在开始学习本聚合教程之前,您必须设置一个新的Node.js应用程序。您可以使用此应用程序连接到MongoDB部署,将示例数据插入MongoDB,并运行聚合管道。

Tip

To learn how to install the driver and connect to MongoDB, see the Node.js Driver Quick Start guide.要了解如何安装驱动程序并连接到MongoDB,请参阅Node.js驱动程序快速入门指南

To learn more about performing aggregations in the Node.js Driver, see the Aggregation guide.要了解有关在Node.js驱动程序中执行聚合的更多信息,请参阅聚合指南

After you install the driver, create a file to run the tutorial template. Paste the following code in this file to create an app template for the aggregation tutorials.安装驱动程序后,创建一个文件来运行教程模板。将以下代码粘贴到此文件中,为聚合教程创建应用程序模板。

Important

In the following code, read the code comments to find the sections of the code that you must modify for the tutorial you are following.在下面的代码中,阅读代码注释,找到您必须为正在学习的教程修改的代码部分。

If you attempt to run the code without making any changes, you will encounter a connection error.如果您尝试在不进行任何更改的情况下运行代码,您将遇到连接错误。

const { MongoClient } = require('mongodb');
// Replace the placeholder with your connection string.
const uri = '<connection-string>';
const client = new MongoClient(uri);
export async function run() {
try {
const aggDB = client.db('agg_tutorials_db');

// Get a reference to relevant collections.
// ... const someColl =
// ... const anotherColl =

// Delete any existing documents in collections.
// ... await someColl.deleteMany({});

// Insert sample data into the collection or collections.
// ... const someData = [ ... ];
// ... await someColl.insertMany(someData);

// Create an empty pipeline array.
const pipeline = [];

// Add code to create pipeline stages.
// ... pipeline.push({ ... })

// Run the aggregation.
// ... const aggregationResult = ...

// Print the aggregation results.
for await (const document of aggregationResult) {
console.log(document);
}
} finally {
await client.close();
}
}

run().catch(console.dir);

For every tutorial, you must replace the connection string placeholder with your deployment's connection string.对于每个教程,您必须将连接字符串占位符替换为部署的连接字符串。

Tip

To learn how to locate your deployment's connection string, see the Create a Connection String step of the Node.js Quick Start guide.要了解如何定位部署的连接字符串,请参阅Node.js快速入门指南的创建连接字符串步骤。

For example, if your connection string is "mongodb+srv://mongodb-example:27017", your connection string assignment resembles the following:例如,如果连接字符串是"mongodb+srv://mongodb-example:27017",连接字符串分配类似于以下内容:

const uri = "mongodb+srv://mongodb-example:27017";

Create the Collection创建集合

This example uses two collections:此示例使用两个集合:

  • orders: documents that describe individual orders for products in a shop:描述商店中单个产品订单的文档
  • products: documents that describe the products that a shop sells:描述商店销售产品的文档

An order can only contain one product. The aggregation uses a one-to-one join to match an order document to the corresponding product document. The aggregation joins the collections by the product_id field that exists in documents in both collections.一个订单只能包含一个产品。聚合使用一对一连接将订单文档与相应的产品文档相匹配。聚合通过两个集合中文档中存在的product_id字段将集合连接起来。

To create the orders and products collections and insert the sample data, add the following code to your application:要创建ordersproducts集合并插入示例数据,请将以下代码添加到应用程序中:

const orders = aggDB.collection('orders');
const products = aggDB.collection('products');

await orders.insertMany([
{
customer_id: 'elise_smith@myemail.com',
orderdate: new Date('2020-05-30T08:35:52Z'),
product_id: 'a1b2c3d4',
value: 431.43,
},
{
customer_id: 'tj@wheresmyemail.com',
orderdate: new Date('2019-05-28T19:13:32Z'),
product_id: 'z9y8x7w6',
value: 5.01,
},
{
customer_id: 'oranieri@warmmail.com',
orderdate: new Date('2020-01-01T08:25:37Z'),
product_id: 'ff11gg22hh33',
value: 63.13,
},
{
customer_id: 'jjones@tepidmail.com',
orderdate: new Date('2020-12-26T08:55:46Z'),
product_id: 'a1b2c3d4',
value: 429.65,
},
]);

await products.insertMany([
{
id: 'a1b2c3d4',
name: 'Asus Laptop',
category: 'ELECTRONICS',
description: 'Good value laptop for students',
},
{
id: 'z9y8x7w6',
name: 'The Day Of The Triffids',
category: 'BOOKS',
description: 'Classic post-apocalyptic novel',
},
{
id: 'ff11gg22hh33',
name: 'Morphy Richardds Food Mixer',
category: 'KITCHENWARE',
description: 'Luxury mixer turning good cakes into great',
},
{
id: 'pqr678st',
name: 'Karcher Hose Set',
category: 'GARDEN',
description: 'Hose + nozzles + winder for tidy storage',
},
]);
PHP

Create the Template App创建模板应用程序

Before you begin following this aggregation tutorial, you must set up a new PHP app. You can use this app to connect to a MongoDB deployment, insert sample data into MongoDB, and run the aggregation pipeline.在开始学习本聚合教程之前,您必须设置一个新的PHP应用程序。您可以使用此应用程序连接到MongoDB部署,将示例数据插入MongoDB,并运行聚合管道。

Tip

To learn how to install the PHP library and connect to MongoDB, see the Get Started with the PHP Library tutorial.要了解如何安装PHP库并连接到MongoDB,请参阅PHP库入门教程

To learn more about performing aggregations in the PHP library, see the Aggregation guide.要了解有关在PHP库中执行聚合的更多信息,请参阅聚合指南

After you install the library, create a file called agg_tutorial.php. Paste the following code in this file to create an app template for the aggregation tutorials.安装库后,创建一个名为agg_tutorial.php的文件。将以下代码粘贴到此文件中,为聚合教程创建应用程序模板。

Important

In the following code, read the code comments to find the sections of the code that you must modify for the tutorial you are following.在下面的代码中,阅读代码注释,找到您必须为正在学习的教程修改的代码部分。

If you attempt to run the code without making any changes, you will encounter a connection error.如果您尝试在不进行任何更改的情况下运行代码,您将遇到连接错误。

<?php

require 'vendor/autoload.php';

// Modify imports for each tutorial as needed.
use MongoDB\Client;
use MongoDB\BSON\UTCDateTime;
use MongoDB\Builder\Pipeline;
use MongoDB\Builder\Stage;
use MongoDB\Builder\Type\Sort;
use MongoDB\Builder\Query;
use MongoDB\Builder\Expression;
use MongoDB\Builder\Accumulator;

use function MongoDB\object;

// Replace the placeholder with your connection string.
$uri = '<connection string>';
$client = new Client($uri);

// Get a reference to relevant collections.
// ... $someColl = $client->agg_tutorials_db->someColl;
// ... $anotherColl = $client->agg_tutorials_db->anotherColl;

// Delete any existing documents in collections if needed.
// ... $someColl->deleteMany([]);

// Insert sample data into the collection or collections.
// ... $someColl->insertMany(...);

// Add code to create pipeline stages within the Pipeline instance.
// ... $pipeline = new Pipeline(...);

// Run the aggregation.
// ... $cursor = $someColl->aggregate($pipeline);

// Print the aggregation results.
foreach ($cursor as $doc) {
echo json_encode($doc, JSON_PRETTY_PRINT), PHP_EOL;
}

For every tutorial, you must replace the connection string placeholder with your deployment's connection string.对于每个教程,您必须将连接字符串占位符替换为部署的连接字符串。

Tip

To learn how to locate your deployment's connection string, see the Create a Connection String step of the Get Started with the PHP Library tutorial.要了解如何定位部署的连接字符串,请参阅PHP库入门教程的创建连接字符串步骤。

For example, if your connection string is "mongodb+srv://mongodb-example:27017", your connection string assignment resembles the following:例如,如果连接字符串是"mongodb+srv://mongodb-example:27017",连接字符串分配类似于以下内容:

$uri = 'mongodb+srv://mongodb-example:27017';

Create the Collection创建集合

This example uses two collections:此示例使用两个集合:

  • orders: documents that describe individual orders for products in a shop:描述商店中单个产品订单的文档
  • products: documents that describe the products that a shop sells:描述商店销售产品的文档

An order can only contain one product. The aggregation uses a one-to-one join to match an order document to the corresponding product document. The aggregation joins the collections by the product_id field that exists in documents in both collections.一个订单只能包含一个产品。聚合使用一对一连接将订单文档与相应的产品文档相匹配。聚合通过两个集合中文档中存在的product_id字段将集合连接起来。

To create the orders and products collections and insert the sample data, add the following code to your application:要创建ordersproducts集合并插入示例数据,请将以下代码添加到应用程序中:

$orders = $client->agg_tutorials_db->orders;
$products = $client->agg_tutorials_db->products;

$orders->deleteMany([]);
$products->deleteMany([]);

$orders->insertMany(
[
[
'customer_id' => 'elise_smith@myemail.com',
'orderdate' => new UTCDateTime(new DateTimeImmutable('2020-05-30T08:35:52')),
'product_id' => 'a1b2c3d4',
'value' => 431.43
],
[
'customer_id' => 'tj@wheresmyemail.com',
'orderdate' => new UTCDateTime(new DateTimeImmutable('2019-05-28T19:13:32')),
'product_id' => 'z9y8x7w6',
'value' => 5.01
],
[
'customer_id' => 'oranieri@warmmail.com',
'orderdate' => new UTCDateTime(new DateTimeImmutable('2020-01-01T08:25:37')),
'product_id' => 'ff11gg22hh33',
'value' => 63.13,
],
[
'customer_id' => 'jjones@tepidmail.com',
'orderdate' => new UTCDateTime(new DateTimeImmutable('2020-12-26T08:55:46')),
'product_id' => 'a1b2c3d4',
'value' => 429.65
],
]
);

$products->insertMany(
[
[
'id' => 'a1b2c3d4',
'name' => 'Asus Laptop',
'category' => 'ELECTRONICS',
'description' => 'Good value laptop for students',
],
[
'id' => 'z9y8x7w6',
'name' => 'The Day Of The Triffids',
'category' => 'BOOKS',
'description' => 'Classic post-apocalyptic novel',
],
[
'id' => 'ff11gg22hh33',
'name' => 'Morphy Richardds Food Mixer',
'category' => 'KITCHENWARE',
'description' => 'Luxury mixer turning good cakes into great',
],
[
'id' => 'pqr678st',
'name' => 'Karcher Hose Set',
'category' => 'GARDEN',
'description' => 'Hose + nozzles + winder for tidy storage',
],
]
);
Python

Create the Template App创建模板应用程序

Before you begin following this aggregation tutorial, you must set up a new Python app. You can use this app to connect to a MongoDB deployment, insert sample data into MongoDB, and run the aggregation pipeline.在开始学习本聚合教程之前,您必须设置一个新的Python应用程序。您可以使用此应用程序连接到MongoDB部署,将示例数据插入MongoDB,并运行聚合管道。

Tip

To learn how to install PyMongo and connect to MongoDB, see the Get Started with PyMongo tutorial.要了解如何安装PyMongo并连接到MongoDB,请参阅PyMongo入门教程

To learn more about performing aggregations in PyMongo, see the Aggregation guide.要了解有关在PyMongo中执行聚合的更多信息,请参阅聚合指南

After you install the library, create a file called agg_tutorial.py. Paste the following code in this file to create an app template for the aggregation tutorials.安装库后,创建一个名为agg_tutorial.py的文件。将以下代码粘贴到此文件中,为聚合教程创建应用程序模板。

Important

In the following code, read the code comments to find the sections of the code that you must modify for the tutorial you are following.在下面的代码中,阅读代码注释,找到您必须为正在学习的教程修改的代码部分。

If you attempt to run the code without making any changes, you will encounter a connection error.如果您尝试在不进行任何更改的情况下运行代码,您将遇到连接错误。

# Modify imports for each tutorial as needed.
from pymongo import MongoClient

# Replace the placeholder with your connection string.
uri = "<connection-string>"
client = MongoClient(uri)

try:
agg_db = client["agg_tutorials_db"]

# Get a reference to relevant collections.
# ... some_coll = agg_db["some_coll"]
# ... another_coll = agg_db["another_coll"]

# Delete any existing documents in collections if needed.
# ... some_coll.delete_many({})

# Insert sample data into the collection or collections.
# ... some_coll.insert_many(...)

# Create an empty pipeline array.
pipeline = []

# Add code to create pipeline stages.
# ... pipeline.append({...})

# Run the aggregation.
# ... aggregation_result = ...

# Print the aggregation results.
for document in aggregation_result:
print(document)

finally:
client.close()

For every tutorial, you must replace the connection string placeholder with your deployment's connection string.对于每个教程,您必须将连接字符串占位符替换为部署的连接字符串。

Tip

To learn how to locate your deployment's connection string, see the Create a Connection String step of the Get Started with the PHP Library tutorial.要了解如何定位部署的连接字符串,请参阅PHP库入门教程的创建连接字符串步骤。

For example, if your connection string is "mongodb+srv://mongodb-example:27017", your connection string assignment resembles the following:例如,如果连接字符串是"mongodb+srv://mongodb-example:27017",连接字符串分配类似于以下内容:

uri = "mongodb+srv://mongodb-example:27017"

Create the Collection创建集合

This example uses two collections:此示例使用两个集合:

  • orders: documents that describe individual orders for products in a shop:描述商店中单个产品订单的文档
  • products: documents that describe the products that a shop sells:描述商店销售产品的文档

An order can only contain one product. The aggregation uses a one-to-one join to match an order document to the corresponding product document. The aggregation joins the collections by the product_id field that exists in documents in both collections.一个订单只能包含一个产品。聚合使用一对一连接将订单文档与相应的产品文档相匹配。聚合通过两个集合中文档中存在的product_id字段将集合连接起来。

To create the orders and products collections and insert the sample data, add the following code to your application:要创建ordersproducts集合并插入示例数据,请将以下代码添加到应用程序中:

orders_coll = agg_db["orders"]
products_coll = agg_db["products"]

order_data = [
{
"customer_id": "elise_smith@myemail.com",
"orderdate": datetime(2020, 5, 30, 8, 35, 52),
"product_id": "a1b2c3d4",
"value": 431.43,
},
{
"customer_id": "tj@wheresmyemail.com",
"orderdate": datetime(2019, 5, 28, 19, 13, 32),
"product_id": "z9y8x7w6",
"value": 5.01,
},
{
"customer_id": "oranieri@warmmail.com",
"orderdate": datetime(2020, 1, 1, 8, 25, 37),
"product_id": "ff11gg22hh33",
"value": 63.13,
},
{
"customer_id": "jjones@tepidmail.com",
"orderdate": datetime(2020, 12, 26, 8, 55, 46),
"product_id": "a1b2c3d4",
"value": 429.65,
},
]

orders_coll.insert_many(order_data)

product_data = [
{
"id": "a1b2c3d4",
"name": "Asus Laptop",
"category": "ELECTRONICS",
"description": "Good value laptop for students",
},
{
"id": "z9y8x7w6",
"name": "The Day Of The Triffids",
"category": "BOOKS",
"description": "Classic post-apocalyptic novel",
},
{
"id": "ff11gg22hh33",
"name": "Morphy Richardds Food Mixer",
"category": "KITCHENWARE",
"description": "Luxury mixer turning good cakes into great",
},
{
"id": "pqr678st",
"name": "Karcher Hose Set",
"category": "GARDEN",
"description": "Hose + nozzles + winder for tidy storage",
},
]

products_coll.insert_many(product_data)
Ruby

Create the Template App创建模板应用程序

Before you begin following this aggregation tutorial, you must set up a new Ruby app. You can use this app to connect to a MongoDB deployment, insert sample data into MongoDB, and run the aggregation pipeline.在开始学习本聚合教程之前,您必须设置一个新的Ruby应用程序。您可以使用此应用程序连接到MongoDB部署,将示例数据插入MongoDB,并运行聚合管道。

Tip

To learn how to install the Ruby Driver and connect to MongoDB, see the Get Started with the Ruby Driver guide.要了解如何安装Ruby驱动程序并连接到MongoDB,请参阅Ruby驱动程序入门指南

To learn more about performing aggregations in the Ruby Driver, see the Aggregation guide.要了解有关在Ruby驱动程序中执行聚合的更多信息,请参阅聚合指南

After you install the driver, create a file called agg_tutorial.rb. Paste the following code in this file to create an app template for the aggregation tutorials.安装驱动程序后,创建一个名为agg_tutorial.rb的文件。将以下代码粘贴到此文件中,为聚合教程创建应用程序模板。

Important

In the following code, read the code comments to find the sections of the code that you must modify for the tutorial you are following.在下面的代码中,阅读代码注释,找到您必须为正在学习的教程修改的代码部分。

If you attempt to run the code without making any changes, you will encounter a connection error.如果您尝试在不进行任何更改的情况下运行代码,您将遇到连接错误。

# typed: strict
require 'mongo'
require 'bson'

# Replace the placeholder with your connection string.
uri = "<connection string>"

Mongo::Client.new(uri) do |client|

agg_db = client.use('agg_tutorials_db')

# Get a reference to relevant collections.
# ... some_coll = agg_db[:some_coll]

# Delete any existing documents in collections if needed.
# ... some_coll.delete_many({})

# Insert sample data into the collection or collections.
# ... some_coll.insert_many( ... )

# Add code to create pipeline stages within the array.
# ... pipeline = [ ... ]

# Run the aggregation.
# ... aggregation_result = some_coll.aggregate(pipeline)

# Print the aggregation results.
aggregation_result.each do |doc|
puts doc
end

end

For every tutorial, you must replace the connection string placeholder with your deployment's connection string.对于每个教程,您必须将连接字符串占位符替换为部署的连接字符串。

Tip

To learn how to locate your deployment's connection string, see the Create a Connection String step of the Ruby Get Started guide.要了解如何定位部署的连接字符串,请参阅Ruby入门指南的创建连接字符串步骤。

For example, if your connection string is "mongodb+srv://mongodb-example:27017", your connection string assignment resembles the following:例如,如果连接字符串是"mongodb+srv://mongodb-example:27017",连接字符串分配类似于以下内容:

uri = "mongodb+srv://mongodb-example:27017"

Create the Collection创建集合

This example uses two collections:此示例使用两个集合:

  • orders: documents that describe individual orders for products in a shop:描述商店中单个产品订单的文档
  • products: documents that describe the products that a shop sells:描述商店销售产品的文档

An order can only contain one product. The aggregation uses a one-to-one join to match an order document to the corresponding product document. The aggregation joins the collections by the product_id field that exists in documents in both collections.一个订单只能包含一个产品。聚合使用一对一连接将订单文档与相应的产品文档相匹配。聚合通过两个集合中文档中存在的product_id字段将集合连接起来。

To create the orders and products collections and insert the sample data, add the following code to your application:要创建ordersproducts集合并插入示例数据,请将以下代码添加到应用程序中:

orders = agg_db[:orders]
products = agg_db[:products]

orders.delete_many({})
products.delete_many({})

orders.insert_many(
[
{
customer_id: "elise_smith@myemail.com",
orderdate: DateTime.parse("2020-05-30T08:35:52Z"),
product_id: "a1b2c3d4",
value: 431.43,
},
{
customer_id: "tj@wheresmyemail.com",
orderdate: DateTime.parse("2019-05-28T19:13:32Z"),
product_id: "z9y8x7w6",
value: 5.01,
},
{
customer_id: "oranieri@warmmail.com",
orderdate: DateTime.parse("2020-01-01T08:25:37Z"),
product_id: "ff11gg22hh33",
value: 63.13,
},
{
customer_id: "jjones@tepidmail.com",
orderdate: DateTime.parse("2020-12-26T08:55:46Z"),
product_id: "a1b2c3d4",
value: 429.65,
},
]
)

products.insert_many(
[
{
id: "a1b2c3d4",
name: "Asus Laptop",
category: "ELECTRONICS",
description: "Good value laptop for students",
},
{
id: "z9y8x7w6",
name: "The Day Of The Triffids",
category: "BOOKS",
description: "Classic post-apocalyptic novel",
},
{
id: "ff11gg22hh33",
name: "Morphy Richardds Food Mixer",
category: "KITCHENWARE",
description: "Luxury mixer turning good cakes into great",
},
{
id: "pqr678st",
name: "Karcher Hose Set",
category: "GARDEN",
description: "Hose + nozzles + winder for tidy storage",
},
]
)
Rust

Create the Template App创建模板应用程序

Before you begin following this aggregation tutorial, you must set up a new Rust app. You can use this app to connect to a MongoDB deployment, insert sample data into MongoDB, and run the aggregation pipeline.在开始学习本聚合教程之前,您必须设置一个新的Rust应用程序。您可以使用此应用程序连接到MongoDB部署,将示例数据插入MongoDB,并运行聚合管道。

Tip

To learn how to install the driver and connect to MongoDB, see the Rust Driver Quick Start guide.要了解如何安装驱动程序并连接到MongoDB,请参阅Rust驱动程序快速入门指南

To learn more about performing aggregations in the Rust Driver, see the Aggregation guide.要了解有关在Rust驱动程序中执行聚合的更多信息,请参阅聚合指南

After you install the driver, create a file called agg-tutorial.rs. Paste the following code in this file to create an app template for the aggregation tutorials.安装驱动程序后,创建一个名为agg-tutorial.rs的文件。将以下代码粘贴到此文件中,为聚合教程创建应用程序模板。

Important

In the following code, read the code comments to find the sections of the code that you must modify for the tutorial you are following.在下面的代码中,阅读代码注释,找到您必须为正在学习的教程修改的代码部分。

If you attempt to run the code without making any changes, you will encounter a connection error.如果您尝试在不进行任何更改的情况下运行代码,您将遇到连接错误。

use mongodb::{
bson::{doc, Document},
options::ClientOptions,
Client,
};
use futures::stream::TryStreamExt;
use std::error::Error;

// Define structs.
// #[derive(Debug, Serialize, Deserialize)]
// struct MyStruct { ... }

#[tokio::main]
async fn main() mongodb::error::Result<()> {
// Replace the placeholder with your connection string.
let uri = "<connection string>";
let client = Client::with_uri_str(uri).await?;

let agg_db = client.database("agg_tutorials_db");

// Get a reference to relevant collections.
// ... let some_coll: Collection<T> = agg_db.collection("...");
// ... let another_coll: Collection<T> = agg_db.collection("...");

// Delete any existing documents in collections if needed.
// ... some_coll.delete_many(doc! {}).await?;

// Insert sample data into the collection or collections.
// ... some_coll.insert_many(vec![...]).await?;

// Create an empty pipeline.
let mut pipeline = Vec::new();

// Add code to create pipeline stages.
// pipeline.push(doc! { ... });

// Run the aggregation and print the results.
let mut results = some_coll.aggregate(pipeline).await?;
while let Some(result) = results.try_next().await? {
println!("{:?}\n", result);
}
Ok(())
}

For every tutorial, you must replace the connection string placeholder with your deployment's connection string.对于每个教程,您必须将连接字符串占位符替换为部署的连接字符串。

Tip

To learn how to locate your deployment's connection string, see the Create a Connection String step of the Rust Quick Start guide.要了解如何定位部署的连接字符串,请参阅Rust快速入门指南的创建连接字符串步骤

For example, if your connection string is "mongodb+srv://mongodb-example:27017", your connection string assignment resembles the following:例如,如果连接字符串是"mongodb+srv://mongodb-example:27017",连接字符串分配类似于以下内容:

let uri = "mongodb+srv://mongodb-example:27017";

Create the Collection创建集合

This example uses two collections:此示例使用两个集合:

  • orders: documents that describe individual orders for products in a shop:描述商店中单个产品订单的文档
  • products: documents that describe the products that a shop sells:描述商店销售产品的文档

An order can only contain one product. The aggregation uses a one-to-one join to match an order document to the corresponding product document. The aggregation joins the collections by the product_id field that exists in documents in both collections.一个订单只能包含一个产品。聚合使用一对一连接将订单文档与相应的产品文档相匹配。聚合通过两个集合中文档中存在的product_id字段将集合连接起来。

First, create Rust structs to model the data in the orders and products collections:首先,创建Rust结构体来对ordersproducts集合中的数据进行建模:

#[derive(Debug, Serialize, Deserialize)]
struct Order {
customer_id: String,
order_date: DateTime,
product_id: String,
value: f32,
}

#[derive(Debug, Serialize, Deserialize)]
struct Product {
id: String,
name: String,
category: String,
description: String,
}

To create the orders and products collections and insert the sample data, add the following code to your application:要创建ordersproducts集合并插入示例数据,请将以下代码添加到应用程序中:

let orders: Collection<Order> = agg_db.collection("orders");
let products: Collection<Product> = agg_db.collection("products");

orders.delete_many(doc! {}).await?;
products.delete_many(doc! {}).await?;

let order_docs = vec![
Order {
customer_id: "elise_smith@myemail.com".to_string(),
order_date: DateTime::builder().year(2020).month(5).day(30).hour(8).minute(35).second(52).build().unwrap(),
product_id: "a1b2c3d4".to_string(),
value: 431.43,
},
Order {
customer_id: "tj@wheresmyemail.com".to_string(),
order_date: DateTime::builder().year(2019).month(5).day(28).hour(19).minute(13).second(32).build().unwrap(),
product_id: "z9y8x7w6".to_string(),
value: 5.01,
},
Order {
customer_id: "oranieri@warmmail.com".to_string(),
order_date: DateTime::builder().year(2020).month(1).day(1).hour(8).minute(25).second(37).build().unwrap(),
product_id: "ff11gg22hh33".to_string(),
value: 63.13,
},
Order {
customer_id: "jjones@tepidmail.com".to_string(),
order_date: DateTime::builder().year(2020).month(12).day(26).hour(8).minute(55).second(46).build().unwrap(),
product_id: "a1b2c3d4".to_string(),
value: 429.65,
},
];
orders.insert_many(order_docs).await?;

let product_docs = vec![
Product {
id: "a1b2c3d4".to_string(),
name: "Asus Laptop".to_string(),
category: "ELECTRONICS".to_string(),
description: "Good value laptop for students".to_string(),
},
Product {
id: "z9y8x7w6".to_string(),
name: "The Day Of The Triffids".to_string(),
category: "BOOKS".to_string(),
description: "Classic post-apocalyptic novel".to_string(),
},
Product {
id: "ff11gg22hh33".to_string(),
name: "Morphy Richardds Food Mixer".to_string(),
category: "KITCHENWARE".to_string(),
description: "Luxury mixer turning good cakes into great".to_string(),
},
Product {
id: "pqr678st".to_string(),
name: "Karcher Hose Set".to_string(),
category: "GARDEN".to_string(),
description: "Hose + nozzles + winder for tidy storage".to_string(),
},
];
products.insert_many(product_docs).await?;
scala

Create the Template App创建模板应用程序

Before you begin following an aggregation tutorial, you must set up a new Scala app. You can use this app to connect to a MongoDB deployment, insert sample data into MongoDB, and run the aggregation pipeline.在开始学习聚合教程之前,您必须设置一个新的Scala应用程序。您可以使用此应用程序连接到MongoDB部署,将示例数据插入MongoDB,并运行聚合管道。

Tip

To learn how to install the driver and connect to MongoDB, see the Get Started with the Scala Driver guide.要了解如何安装驱动程序并连接到MongoDB,请参阅Scala驱动程序入门指南

To learn more about performing aggregations in the Scala Driver, see the Aggregation guide.要了解有关在Scala驱动程序中执行聚合的更多信息,请参阅聚合指南

After you install the driver, create a file called AggTutorial.scala. Paste the following code in this file to create an app template for the aggregation tutorials.安装驱动程序后,创建一个名为AggTutorial.scala的文件。将以下代码粘贴到此文件中,为聚合教程创建应用程序模板。

Important

In the following code, read the code comments to find the sections of the code that you must modify for the tutorial you are following.在下面的代码中,阅读代码注释,找到您必须为正在学习的教程修改的代码部分。

If you attempt to run the code without making any changes, you will encounter a connection error.如果您尝试在不进行任何更改的情况下运行代码,您将遇到连接错误。

package org.example;

// Modify imports for each tutorial as needed.
import org.mongodb.scala.MongoClient
import org.mongodb.scala.bson.Document
import org.mongodb.scala.model.{Accumulators, Aggregates, Field, Filters, Variable}

import java.text.SimpleDateFormat

object FilteredSubset {

def main(args: Array[String]): Unit = {

// Replace the placeholder with your connection string.
val uri = "<connection string>"
val mongoClient = MongoClient(uri)
Thread.sleep(1000)

val aggDB = mongoClient.getDatabase("agg_tutorials_db")

// Get a reference to relevant collections.
// ... val someColl = aggDB.getCollection("someColl")
// ... val anotherColl = aggDB.getCollection("anotherColl")

// Delete any existing documents in collections if needed.
// ... someColl.deleteMany(Filters.empty()).subscribe(...)

// If needed, create the date format template.
val dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss")

// Insert sample data into the collection or collections.
// ... someColl.insertMany(...).subscribe(...)

Thread.sleep(1000)

// Add code to create pipeline stages within the Seq.
// ... val pipeline = Seq(...)

// Run the aggregation and print the results.
// ... someColl.aggregate(pipeline).subscribe(...)

Thread.sleep(1000)
mongoClient.close()
}
}

For every tutorial, you must replace the connection string placeholder with your deployment's connection string.对于每个教程,您必须将连接字符串占位符替换为部署的连接字符串。

Tip

To learn how to locate your deployment's connection string, see the Create a Connection String step of the Scala Driver Get Started guide.要了解如何定位部署的连接字符串,请参阅《Scala驱动程序入门》指南的创建连接字符串步骤。

For example, if your connection string is "mongodb+srv://mongodb-example:27017", your connection string assignment resembles the following:例如,如果连接字符串是"mongodb+srv://mongodb-example:27017",连接字符串分配类似于以下内容:

val uri = "mongodb+srv://mongodb-example:27017"

Create the Collection创建集合

This example uses two collections:此示例使用两个集合:

  • orders: documents that describe individual orders for products in a shop:描述商店中单个产品订单的文档
  • products: documents that describe the products that a shop sells:描述商店销售产品的文档

An order can only contain one product. The aggregation uses a one-to-one join to match an order document to the corresponding product document. The aggregation joins the collections by the product_id field that exists in documents in both collections.一个订单只能包含一个产品。聚合使用一对一连接将订单文档与相应的产品文档相匹配。聚合通过两个集合中文档中存在的product_id字段将集合连接起来。

To create the orders and products collections and insert the sample data, add the following code to your application:要创建ordersproducts集合并插入示例数据,请将以下代码添加到应用程序中:

val orders = aggDB.getCollection("orders")
val products = aggDB.getCollection("products")

orders.deleteMany(Filters.empty()).subscribe(
_ => {},
e => println("Error: " + e.getMessage),
)

products.deleteMany(Filters.empty()).subscribe(
_ => {},
e => println("Error: " + e.getMessage),
)

val dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss")

orders.insertMany(
Seq(
Document(
"customer_id" -> "elise_smith@myemail.com",
"orderdate" -> dateFormat.parse("2020-05-30T08:35:52"),
"product_id" -> "a1b2c3d4",
"value" -> 431.43
),
Document(
"customer_id" -> "tj@wheresmyemail.com",
"orderdate" -> dateFormat.parse("2019-05-28T19:13:32"),
"product_id" -> "z9y8x7w6",
"value" -> 5.01
),
Document(
"customer_id" -> "oranieri@warmmail.com",
"orderdate" -> dateFormat.parse("2020-01-01T08:25:37"),
"product_id" -> "ff11gg22hh33",
"value" -> 63.13
),
Document(
"customer_id" -> "jjones@tepidmail.com",
"orderdate" -> dateFormat.parse("2020-12-26T08:55:46"),
"product_id" -> "a1b2c3d4",
"value" -> 429.65
)
)
).subscribe(
_ => {},
e => println("Error: " + e.getMessage),
)

products.insertMany(
Seq(
Document(
"id" -> "a1b2c3d4",
"name" -> "Asus Laptop",
"category" -> "ELECTRONICS",
"description" -> "Good value laptop for students"
),
Document(
"id" -> "z9y8x7w6",
"name" -> "The Day Of The Triffids",
"category" -> "BOOKS",
"description" -> "Classic post-apocalyptic novel"
),
Document(
"id" -> "ff11gg22hh33",
"name" -> "Morphy Richardds Food Mixer",
"category" -> "KITCHENWARE",
"description" -> "Luxury mixer turning good cakes into great"
),
Document(
"id" -> "pqr678st",
"name" -> "Karcher Hose Set",
"category" -> "GARDEN",
"description" -> "Hose + nozzles + winder for tidy storage"
)
)
).subscribe(
_ => {},
e => println("Error: " + e.getMessage),
)

Steps步骤

The following steps demonstrate how to create and run an aggregation pipeline to join collections on a single common field.以下步骤演示了如何创建和运行聚合管道,以连接单个公共字段上的集合。

MongoDB Shell
1

Run the aggregation pipeline.运行聚合管道。

db.orders.aggregate( [

// Stage 1: Match orders that were placed in 2020
{ $match: {
orderdate: {
$gte: new Date("2020-01-01T00:00:00Z"),
$lt: new Date("2021-01-01T00:00:00Z")
}
} },

// Stage 2: Link the collections
{ $lookup: {
from: "products",
localField: "product_id",
foreignField: "p_id",
as: "product_mapping"
} },

// Stage 3: Create new document fields
{ $set: {
product_mapping: { $first: "$product_mapping" }
} },
{ $set: {
product_name: "$product_mapping.name",
product_category: "$product_mapping.category"
} },

// Stage 4: Remove unneeded fields
{ $unset: ["_id", "product_id", "product_mapping"] }
] )

In this example, the $lookup stage always outputs a product_mapping array that contains one document. The $set stage after the $lookup stage uses $first to extract the document from the product_mapping array. 在此示例中,$lookup阶段始终输出一个包含一个文档的product_mapping数组。$lookup阶段之后的$set阶段使用$firstproduct_mapping数组中提取文档。If you use this pipeline in a setting where the $lookup stage outputs an array of more than one document, consider using an explicit { $limit: 1 } stage in the $lookup stage.如果在$lookup阶段输出多个文档的数组的设置中使用此管道,请考虑在$lookup步骤中使用显式的{ $limit: 1 }阶段。

Note

If a supporting index on the foreignField does not exist, a $lookup operation that performs an equality match with a single join will likely have poor performance. For more information, see and Lookup Performance Considerations and Create an Index.如果foreignField上不存在支持索引,则与单个联接执行相等匹配的$lookup操作的性能可能会很差。有关更多信息,请参阅查找性能考虑因素创建索引

2

Interpret the aggregation results.解释聚合结果。

The aggregated results contain three documents. The documents represent customer orders that occurred in 2020, with the product_name and product_category of the ordered product:汇总结果包含三个文档。这些文档表示2020年发生的客户订单,包括订购产品的product_nameproduct_category

{
customer_id: 'elise_smith@myemail.com',
orderdate: ISODate('2020-05-30T08:35:52.000Z'),
value: 431.43,
product_name: 'Asus Laptop',
product_category: 'ELECTRONICS'
}
{
customer_id: 'oranieri@warmmail.com',
orderdate: ISODate('2020-01-01T08:25:37.000Z'),
value: 63.13,
product_name: 'Morphy Richardds Food Mixer',
product_category: 'KITCHENWARE'
}
{
customer_id: 'jjones@tepidmail.com',
orderdate: ISODate('2020-12-26T08:55:46.000Z'),
value: 429.65,
product_name: 'Asus Laptop',
product_category: 'ELECTRONICS'
}

The result consists of documents that contain fields from documents in the orders collection and the products collection joined by matching the product_id field present in each original document.结果由包含orders集合和products集合中文档字段的文档组成,这些字段通过匹配每个原始文档中存在的product_id字段而连接在一起。

C
1

Add a match stage for orders in 2020.为2020年的订单添加匹配阶段。

Add a $match stage that matches orders placed in 2020:

"{", "$match", "{",
"orderdate", "{",
"$gte", BCON_DATE_TIME(1577836800000UL),
"$lt", BCON_DATE_TIME(1609459200000UL),
"}",
"}", "}",
2

Add a lookup stage to link the collections.添加查找阶段以链接集合。

Next, add a $lookup stage. The $lookup stage joins the product_id field in the orders collection to the id field in the products collection:接下来,添加一个$lookup阶段。$lookup阶段将orders集合中的product_id字段与products集合中的id字段连接起来:

"{", "$lookup", "{",
"from", BCON_UTF8("products"),
"localField", BCON_UTF8("product_id"),
"foreignField", BCON_UTF8("id"),
"as", BCON_UTF8("product_mapping"),
"}", "}",
3

Add set stages to create new document fields.添加设置阶段以创建新的文档字段。

Next, add two $set stages to the pipeline.接下来,向管道中添加两个$set阶段。

The first $set stage sets the product_mapping field to the first element in the product_mapping object created in the previous $lookup stage.第一个$set阶段将product_mapping字段设置为在上一个$lookup阶段创建的product_mappings对象中的第一个元素。

The second $set stage creates two new fields, product_name and product_category, from the values in the product_mapping object field:第二个$set阶段根据product_mapping对象字段中的值创建两个新字段product_nameproduct_category

"{", "$set", "{", "product_mapping", "{", "$first", BCON_UTF8("$product_mapping"), "}", "}", "}",
"{", "$set", "{",
"product_name", BCON_UTF8("$product_mapping.name"),
"product_category", BCON_UTF8("$product_mapping.category"),
"}", "}",

Tip

Because this is a one-to-one join, the $lookup stage adds only one array element to the input document. 因为这是一个一对一的连接,$lookup阶段只向输入文档添加一个数组元素。The pipeline uses the $first operator to retrieve the data from this element.管道使用$first运算符从该元素检索数据。

4

Add an unset stage to remove unneeded fields.添加未设置的阶段以删除不需要的字段。

Finally, add an $unset stage. The $unset stage removes unnecessary fields from the document:最后,添加一个$unset阶段。$unset阶段从文档中删除不必要的字段:

"{", "$unset", "[", BCON_UTF8("_id"), BCON_UTF8("product_id"), BCON_UTF8("product_mapping"), "]", "}",
5

Run the aggregation pipeline.运行聚合管道。

Add the following code to the end of your application to perform the aggregation on the orders collection:将以下代码添加到应用程序的末尾,以对orders集合执行聚合:

mongoc_cursor_t *results =
mongoc_collection_aggregate(orders, MONGOC_QUERY_NONE, pipeline, NULL, NULL);

bson_destroy(pipeline);

Ensure that you clean up the collection resources by adding the following line to your cleanup statements:通过在清理语句中添加以下行来确保清理集合资源:

mongoc_collection_destroy(orders);
mongoc_collection_destroy(products);

Finally, run the following commands in your shell to generate and run the executable:最后,在shell中运行以下命令以生成并运行可执行文件:

gcc -o aggc agg-tutorial.c $(pkg-config --libs --cflags libmongoc-1.0)
./aggc

Tip

If you encounter connection errors by running the preceding commands in one call, you can run them separately.如果在一次调用中运行上述命令时遇到连接错误,可以单独运行它们。

6

Interpret the aggregation results.解释聚合结果。

The aggregated result contains three documents. The documents represent customer orders that occurred in 2020, with the product_name and product_category of the ordered product:汇总结果包含三个文档。这些文档表示2020年发生的客户订单,包括订购产品的product_nameproduct_category

{ "customer_id" : "elise_smith@myemail.com", "orderdate" : { "$date" : { "$numberLong" : "1590822952000" } }, "value" : { "$numberDouble" : "431.43000000000000682" }, "product_name" : "Asus Laptop", "product_category" : "ELECTRONICS" }
{ "customer_id" : "oranieri@warmmail.com", "orderdate" : { "$date" : { "$numberLong" : "1577869537000" } }, "value" : { "$numberDouble" : "63.130000000000002558" }, "product_name" : "Morphy Richardds Food Mixer", "product_category" : "KITCHENWARE" }
{ "customer_id" : "jjones@tepidmail.com", "orderdate" : { "$date" : { "$numberLong" : "1608976546000" } }, "value" : { "$numberDouble" : "429.64999999999997726" }, "product_name" : "Asus Laptop", "product_category" : "ELECTRONICS" }

The result consists of documents that contain fields from documents in the orders collection and the products collection, joined by matching the product_id field present in each original document.结果由包含orders集合和products集合中文档字段的文档组成,这些字段通过匹配每个原始文档中存在的product_id字段连接在一起。

C++11
1

Add a match stage for orders in 2020.为2020年的订单添加匹配阶段。

Add a $match stage that matches orders placed in 2020:添加一个匹配2020年订单的$match阶段:

pipeline.match(bsoncxx::from_json(R"({
"orderdate": {
"$gte": {"$date": 1577836800},
"$lt": {"$date": 1609459200000}
}
})"));
2

Add a lookup stage to link the collections.添加查找阶段以链接集合。

Next, add a $lookup stage. The $lookup stage joins the product_id field in the orders collection to the id field in the products collection:接下来,添加一个$lookup阶段。$lookup阶段将orders集合中的product_id字段与products集合中的id字段连接起来:

pipeline.lookup(bsoncxx::from_json(R"({
"from": "products",
"localField": "product_id",
"foreignField": "id",
"as": "product_mapping"
})"));
3

Add addFields stages to create new document fields.添加addFields阶段以创建新的文档字段。

Next, add two $addFields stages to the pipeline.接下来,将两个$addFields阶段添加到管道中。

The first $addFields stage sets the product_mapping field to the first element in the product_mapping object created in the previous $lookup stage.第一个$addFields阶段将product_mapping字段设置为在上一个$lookup阶段创建的product_mappings对象中的第一个元素。

The second $addFields stage creates two new fields, product_name and product_category, from the values in the product_mapping object field:第二个$addFields阶段根据product_mapping对象字段中的值创建两个新字段,product_nameproduct_category

pipeline.add_fields(bsoncxx::from_json(R"({
"product_mapping": {"$first": "$product_mapping"}
})"));
pipeline.add_fields(bsoncxx::from_json(R"({
"product_name": "$product_mapping.name",
"product_category": "$product_mapping.category"
})"));

Tip

Because this is a one-to-one join, the $lookup stage adds only one array element to the input document. The pipeline uses the $first operator to retrieve the data from this element.因为这是一个一对一的连接,$lookup阶段只向输入文档添加一个数组元素。管道使用$first运算符从该元素检索数据。

4

Add an unset stage to remove unneeded fields.添加未设置的阶段以删除不需要的字段。

Finally, add an $unset stage. The $unset stage removes unnecessary fields from the document:最后,添加一个$unset阶段。$unset阶段从文档中删除不必要的字段:

pipeline.append_stage(bsoncxx::from_json(R"({
"$unset": ["_id", "product_id", "product_mapping"]
})"));
5

Run the aggregation pipeline.运行聚合管道。

Add the following code to the end of your application to perform the aggregation on the orders collection:将以下代码添加到应用程序的末尾,以对orders集合执行聚合:

auto cursor = orders.aggregate(pipeline);

Finally, run the following command in your shell to start your application:最后,在shell中运行以下命令以启动应用程序:

c++ --std=c++17 agg-tutorial.cpp $(pkg-config --cflags --libs libmongocxx) -o ./app.out
./app.out
6

Interpret the aggregation results.解释聚合结果。

The aggregated result contains three documents. The documents represent customer orders that occurred in 2020, with the product_name and product_category of the ordered product:汇总结果包含三个文档。这些文档表示2020年发生的客户订单,包括订购产品的product_nameproduct_category

{ "customer_id" : "elise_smith@myemail.com", "orderdate" : { "$date" : "2020-05-30T06:55:52Z" },
"value" : 431.43000000000000682, "product_name" : "Asus Laptop", "product_category" : "ELECTRONICS" }
{ "customer_id" : "oranieri@warmmail.com", "orderdate" : { "$date" : "1970-01-19T06:17:41.137Z" },
"value" : 63.130000000000002558, "product_name" : "Morphy Richardds Food Mixer", "product_category" : "KITCHENWARE" }
{ "customer_id" : "jjones@tepidmail.com", "orderdate" : { "$date" : "2020-12-26T08:55:46Z" },
"value" : 429.64999999999997726, "product_name" : "Asus Laptop", "product_category" : "ELECTRONICS" }

The result consists of documents that contain fields from documents in the orders collection and the products collection, joined by matching the product_id field present in each original document.结果由包含orders集合和products集合中文档字段的文档组成,这些字段通过匹配每个原始文档中存在的product_id字段连接在一起。

C#
1

Add a match stage for orders in 2020.为2020年的订单添加匹配阶段。

First, start the aggregation on the orders collection and chain a $match stage that matches orders placed in 2020:首先,启动orders集合的聚合,并链接一个匹配2020年下订单的$match阶段:

var results = orders.Aggregate()
.Match(o => o.OrderDate >= DateTime.Parse("2020-01-01T00:00:00Z") &&
o.OrderDate < DateTime.Parse("2021-01-01T00:00:00Z"))
2

Add a lookup stage to link the collections.添加查找阶段以链接集合。

Next, add a $lookup stage. 接下来,添加一个$lookup阶段。The $lookup stage joins the ProductId field in the orders collection to the Id field in the products collection:$lookup阶段将orders集合中的ProductId字段连接到products集合中的Id字段:

.Lookup<Product, Order>(
foreignCollectionName: "products",
localField: "ProductId",
foreignField: "Id",
@as: "ProductMapping"
)
3

Add a projection stage to create new document fields and omit unneeded fields.添加投影阶段以创建新的文档字段并省略不需要的字段。

Next, add a $project stage to the pipeline.接下来,将$project阶段添加到管道中。

The $project stage creates two new fields, ProductName and ProductCategory, from the first entries of the respective values in the ProductMapping object field. The stage also specifies which fields to include and exclude from the output documents:$project阶段从ProductMapping对象字段中相应值的第一个条目创建两个新字段ProductNameProductCategory。该阶段还指定了要在输出文档中包含和排除哪些字段:

.Project(new BsonDocument
{
{ "ProductName", new BsonDocument("$first", "$ProductMapping.Name") },
{ "ProductCategory", new BsonDocument("$first", "$ProductMapping.Category") },
{ "OrderDate", 1 },
{ "CustomerId", 1 },
{ "Value", 1 },
{ "_id", 0 },
});

Tip

Because this is a one-to-one join, the $lookup stage adds only one array element to the input document. The pipeline uses the $first operator to retrieve the data from this element.因为这是一个一对一的连接,$lookup阶段只向输入文档添加一个数组元素。管道使用$first运算符从该元素检索数据。

4

Run the aggregation and interpret the results.运行聚合并解释结果。

Finally, run the application in your IDE and inspect the results.最后,在IDE中运行应用程序并检查结果。

The aggregated result contains three documents. The documents represent customer orders that occurred in 2020, with the ProductName and ProductCategory of the ordered product:汇总结果包含三个文档。这些文档表示2020年发生的客户订单,其中包含订购产品的ProductNameProductCategory

{ "CustomerId" : "elise_smith@myemail.com", "OrderDate" : { "$date" : "2020-05-30T08:35:52Z" }, "Value" : 431.43000000000001, "ProductName" : "Asus Laptop", "ProductCategory" : "ELECTRONICS" }
{ "CustomerId" : "oranieri@warmmail.com", "OrderDate" : { "$date" : "2020-01-01T08:25:37Z" }, "Value" : 63.130000000000003, "ProductName" : "Morphy Richardds Food Mixer", "ProductCategory" : "KITCHENWARE" }
{ "CustomerId" : "jjones@tepidmail.com", "OrderDate" : { "$date" : "2020-12-26T08:55:46Z" }, "Value" : 429.64999999999998, "ProductName" : "Asus Laptop", "ProductCategory" : "ELECTRONICS" }

The result consists of documents that contain fields from documents in the orders collection and the products collection, joined by matching the ProductId field present in each original document.结果由包含orders集合和products集合中文档字段的文档组成,这些字段通过匹配每个原始文档中存在的ProductId字段连接在一起。

Go
1

Add a match stage for orders in 2020.为2020年的订单添加匹配阶段。

Add a $match stage that matches orders placed in 2020:添加一个匹配2020年订单的$match阶段:

matchStage := bson.D{{Key: "$match", Value: bson.D{
{Key: "orderdate", Value: bson.D{
{Key: "$gte", Value: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)},
{Key: "$lt", Value: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC)},
}},
}}}
2

Add a lookup stage to link the collections.添加查找阶段以链接集合。

Next, add a $lookup stage. The $lookup stage joins the product_id field in the orders collection to the id field in the products collection:接下来,添加一个$lookup阶段。$lookup阶段将orders集合中的product_id字段与products集合中的id字段连接起来:

lookupStage := bson.D{{Key: "$lookup", Value: bson.D{
{Key: "from", Value: "products"},
{Key: "localField", Value: "product_id"},
{Key: "foreignField", Value: "id"},
{Key: "as", Value: "product_mapping"},
}}}
3

Add set stages to create new document fields.添加设置阶段以创建新的文档字段。

Next, add two $set stages to the pipeline.接下来,向管道中添加两个$set阶段。

The first $set stage sets the product_mapping field to the first element in the product_mapping object created in the previous $lookup stage.第一个$set阶段将product_mapping字段设置为在上一个$lookup阶段创建的product_mappings对象中的第一个元素。

The second $set stage creates two new fields, product_name and product_category, from the values in the product_mapping object field:第二个$set阶段根据product_mapping对象字段中的值创建两个新字段product_nameproduct_category

setProductMappingStage := bson.D{{Key: "$set", Value: bson.D{
{Key: "product_mapping", Value: bson.D{{Key: "$first", Value: "$product_mapping"}}},
}}}

setProductNameCategoryStage := bson.D{{Key: "$set", Value: bson.D{
{Key: "product_name", Value: "$product_mapping.name"},
{Key: "product_category", Value: "$product_mapping.category"},
}}}

Tip

Because this is a one-to-one join, the $lookup stage adds only one array element to the input document. The pipeline uses the $first operator to retrieve the data from this element.因为这是一个一对一的连接,$lookup阶段只向输入文档添加一个数组元素。管道使用$first运算符从该元素检索数据。

4

Add an unset stage to remove unneeded fields.添加未设置的阶段以删除不需要的字段。

Finally, add an $unset stage. The $unset stage removes unnecessary fields from the document:最后,添加一个$unset阶段。$unset阶段从文档中删除不必要的字段:

unsetStage := bson.D{{Key: "$unset", Value: bson.A{"_id", "product_id", "product_mapping"}}}
5

Run the aggregation pipeline.运行聚合管道。

Add the following code to the end of your application to perform the aggregation on the orders collection:将以下代码添加到应用程序的末尾,以对orders集合执行聚合:

pipeline := mongo.Pipeline{
matchStage,
lookupStage,
setProductMappingStage,
setProductNameCategoryStage,
unsetStage,
}
cursor, err := orders.Aggregate(ctx, pipeline)

Finally, run the application and inspect the results.最后,运行应用程序并检查结果。

6

Interpret the aggregation results.解释聚合结果。

The aggregated result contains three documents. The documents represent customer orders that occurred in 2020, with the product_name and product_category of the ordered product:汇总结果包含三个文档。这些文档表示2020年发生的客户订单,包括订购产品的product_nameproduct_category

{"customer_id":"elise_smith@myemail.com","orderdate":{"$date":"2020-05-30T08:35:52Z"},"value":431.42999267578125,"product_name":"Asus Laptop","product_category":"ELECTRONICS"}
{"customer_id":"oranieri@warmmail.com","orderdate":{"$date":"2020-01-01T08:25:37Z"},"value":63.130001068115234,"product_name":"Morphy Richardds Food Mixer","product_category":"KITCHENWARE"}
{"customer_id":"jjones@tepidmail.com","orderdate":{"$date":"2020-12-26T08:55:46Z"},"value":429.6499938964844,"product_name":"Asus Laptop","product_category":"ELECTRONICS"}

The result consists of documents that contain fields from documents in the orders collection and the products collection, joined by matching the product_id field present in each original document.结果由包含orders集合和products集合中文档字段的文档组成,这些字段通过匹配每个原始文档中存在的product_id字段连接在一起。

Java(Sync)
1

Add a match stage for orders in 2020.为2020年的订单添加匹配阶段。

Add a $match stage that matches orders placed in 2020:添加一个匹配2020年订单的$match阶段:

pipeline.add(Aggregates.match(Filters.and(
Filters.gte("orderdate", LocalDateTime.parse("2020-01-01T00:00:00")),
Filters.lt("orderdate", LocalDateTime.parse("2021-01-01T00:00:00"))
)));
2

Add a lookup stage to link the collections.添加查找阶段以链接集合。

Next, add a $lookup stage. The $lookup stage joins the product_id field in the orders collection to the id field in the products collection:接下来,添加一个$lookup阶段。$lookup阶段将orders集合中的product_id字段与products集合中的id字段连接起来:

pipeline.add(Aggregates.lookup(
"products",
"product_id",
"id",
"product_mapping"
));
3

Add set stages to create new document fields.添加设置阶段以创建新的文档字段。

Next, add two $set stages to the pipeline.接下来,向管道中添加两个$set阶段。

The first $set stage sets the product_mapping field to the first element in the product_mapping object created in the previous $lookup stage.第一个$set阶段将product_mapping字段设置为在上一个$lookup阶段创建的product_mappings对象中的第一个元素。

The second $set stage creates two new fields, product_name and product_category, from the values in the product_mapping object field:第二个$set阶段根据product_mapping对象字段中的值创建两个新字段product_nameproduct_category

pipeline.add(Aggregates.set(
new Field<>(
"product_mapping",
new Document("$first", "$product_mapping")
)
));

pipeline.add(Aggregates.set(
new Field<>("product_name", "$product_mapping.name"),
new Field<>("product_category", "$product_mapping.category")
));

Tip

Because this is a one-to-one join, the $lookup stage adds only one array element to the input document. The pipeline uses the $first operator to retrieve the data from this element.因为这是一个一对一的连接,$lookup阶段只向输入文档添加一个数组元素。管道使用$first运算符从该元素检索数据。

4

Add an unset stage to remove unneeded fields.添加未设置的阶段以删除不需要的字段。

Finally, add an $unset stage. The $unset stage removes unnecessary fields from the document:最后,添加一个$unset阶段。$unset阶段从文档中删除不必要的字段:

pipeline.add(Aggregates.unset("_id", "product_id", "product_mapping"));
5

Run the aggregation pipeline.运行聚合管道。

Add the following code to the end of your application to perform the aggregation on the orders collection:将以下代码添加到应用程序的末尾,以对orders集合执行聚合:

AggregateIterable<Document> aggregationResult = orders.aggregate(pipeline);

Finally, run the application in your IDE.最后,在IDE中运行应用程序。

6

Interpret the aggregation results.解释聚合结果。

The aggregated result contains three documents. The documents represent customer orders that occurred in 2020, with the product_name and product_category of the ordered product:汇总结果包含三个文档。这些文档表示2020年发生的客户订单,包括订购产品的product_nameproduct_category

{"customer_id": "elise_smith@myemail.com", "orderdate": {"$date": "2020-05-30T08:35:52Z"}, "value": 431.43, "product_name": "Asus Laptop", "product_category": "ELECTRONICS"}
{"customer_id": "oranieri@warmmail.com", "orderdate": {"$date": "2020-01-01T08:25:37Z"}, "value": 63.13, "product_name": "Morphy Richardds Food Mixer", "product_category": "KITCHENWARE"}
{"customer_id": "jjones@tepidmail.com", "orderdate": {"$date": "2020-12-26T08:55:46Z"}, "value": 429.65, "product_name": "Asus Laptop", "product_category": "ELECTRONICS"}

The result consists of documents that contain fields from documents in the orders collection and the products collection, joined by matching the product_id field present in each original document.结果由包含orders集合和products集合中文档字段的文档组成,这些字段通过匹配每个原始文档中存在的product_id字段连接在一起。

Kotlin(Coroutine)
1

Add a match stage for orders in 2020.为2020年的订单添加匹配阶段。

Add a $match stage that matches orders placed in 2020:添加一个匹配2020年订单的$match阶段:

pipeline.add(
Aggregates.match(
Filters.and(
Filters.gte(
Order::orderDate.name,
LocalDateTime.parse("2020-01-01T00:00:00").toJavaLocalDateTime()
),
Filters.lt(Order::orderDate.name, LocalDateTime.parse("2021-01-01T00:00:00").toJavaLocalDateTime())
)
)
)
2

Add a lookup stage to link the collections.添加查找阶段以链接集合。

Next, add a $lookup stage. The $lookup stage joins the productID field in the orders collection to the ID field in the products collection:接下来,添加一个$lookup阶段。$lookup阶段将orders集合中的productID字段与products集合中的ID字段连接起来:

pipeline.add(
Aggregates.lookup(
"products",
Order::productID.name,
Product::ID.name,
"product_mapping"
)
)
3

Add set stages to create new document fields.添加设置阶段以创建新的文档字段。

Next, add two $set stages to the pipeline.接下来,向管道中添加两个$set阶段。

The first $set stage sets the product_mapping field to the first element in the product_mapping object created in the previous $lookup stage.第一个$set阶段将product_mapping字段设置为在上一个$lookup阶段创建的product_mappings对象中的第一个元素。

The second $set stage creates two new fields, product_name and product_category, from the values in the product_mapping object field:第二个$set阶段根据product_mapping对象字段中的值创建两个新字段product_nameproduct_category

pipeline.add(
Aggregates.set(Field("product_mapping", Document("\$first", "\$product_mapping")))
)

pipeline.add(
Aggregates.set(
Field("product_name", "\$product_mapping.name"),
Field("product_category", "\$product_mapping.category")
)
)

Tip

Because this is a one-to-one join, the $lookup stage adds only one array element to the input document. The pipeline uses the $first operator to retrieve the data from this element.因为这是一个一对一的连接,$lookup阶段只向输入文档添加一个数组元素。管道使用$first运算符从该元素检索数据。

4

Add an unset stage to remove unneeded fields.添加未设置的阶段以删除不需要的字段。

Finally, add an $unset stage. The $unset stage removes unnecessary fields from the document:最后,添加一个$unset阶段。$unset阶段从文档中删除不必要的字段:

pipeline.add(Aggregates.unset("_id", Order::productID.name, "product_mapping"))
5

Run the aggregation pipeline.运行聚合管道。

Add the following code to the end of your application to perform the aggregation on the orders collection:将以下代码添加到应用程序的末尾,以对orders集合执行聚合:

val aggregationResult = orders.aggregate<Document>(pipeline)

Finally, run the application in your IDE.最后,在IDE中运行应用程序。

6

Interpret the aggregation results.解释聚合结果。

The aggregated result contains three documents. The documents represent customer orders that occurred in 2020, with the product_name and product_category of the ordered product:汇总结果包含三个文档。这些文档表示2020年发生的客户订单,包括订购产品的product_nameproduct_category

Document{{customerID=elise_smith@myemail.com, orderDate=Sat May 30 04:35:52 EDT 2020, value=431.43, product_name=Asus Laptop, product_category=ELECTRONICS}}
Document{{customerID=oranieri@warmmail.com, orderDate=Wed Jan 01 03:25:37 EST 2020, value=63.13, product_name=Morphy Richardds Food Mixer, product_category=KITCHENWARE}}
Document{{customerID=jjones@tepidmail.com, orderDate=Sat Dec 26 03:55:46 EST 2020, value=429.65, product_name=Asus Laptop, product_category=ELECTRONICS}}

The result consists of documents that contain fields from documents in the orders collection and the products collection, joined by matching the product_id field present in each original document.结果由包含orders集合和products集合中文档字段的文档组成,这些字段通过匹配每个原始文档中存在的product_id字段连接在一起。

Node.js
1

Add a match stage for orders in 2020.为2020年的订单添加匹配阶段。

Add a $match stage that matches orders placed in 2020:添加一个匹配2020年订单的$match阶段:

pipeline.push({
$match: {
orderdate: {
$gte: new Date('2020-01-01T00:00:00Z'),
$lt: new Date('2021-01-01T00:00:00Z'),
},
},
});
2

Add a lookup stage to link the collections.添加查找阶段以链接集合。

Next, add a $lookup stage. The $lookup stage joins the product_id field in the orders collection to the id field in the products collection:接下来,添加一个$lookup阶段。$lookup阶段将orders集合中的product_id字段与products集合中的id字段连接起来:

pipeline.push({
$lookup: {
from: 'products',
localField: 'product_id',
foreignField: 'id',
as: 'product_mapping',
},
});
3

Add set stages to create new document fields.添加设置阶段以创建新的文档字段。

Next, add two $set stages to the pipeline.接下来,向管道中添加两个$set阶段。

The first $set stage sets the product_mapping field to the first element in the product_mapping object created in the previous $lookup stage.第一个$set阶段将product_mapping字段设置为在上一个$lookup阶段创建的product_mappings对象中的第一个元素。

The second $set stage creates two new fields, product_name and product_category, from the values in the product_mapping object field:第二个$set阶段根据product_mapping对象字段中的值创建两个新字段product_nameproduct_category

pipeline.push(
{
$set: {
product_mapping: { $first: '$product_mapping' },
},
},
{
$set: {
product_name: '$product_mapping.name',
product_category: '$product_mapping.category',
},
}
);

Tip

Because this is a one-to-one join, the $lookup stage adds only one array element to the input document. The pipeline uses the $first operator to retrieve the data from this element.因为这是一个一对一的连接,$lookup阶段只向输入文档添加一个数组元素。管道使用$first运算符从该元素检索数据。

4

Add an unset stage to remove unneeded fields.添加未设置的阶段以删除不需要的字段。

Finally, add an $unset stage. The $unset stage removes unnecessary fields from the document:最后,添加一个$unset阶段。$unset阶段从文档中删除不必要的字段:

pipeline.push({ $unset: ['_id', 'product_id', 'product_mapping'] });
5

Run the aggregation pipeline.运行聚合管道。

Add the following code to the end of your application to perform the aggregation on the orders collection:将以下代码添加到应用程序的末尾,以对orders集合执行聚合:

const aggregationResult = await orders.aggregate(pipeline);

Finally, execute the code in the file using your IDE or the command line.最后,使用IDE或命令行执行文件中的代码。

6

Interpret the aggregation results.解释聚合结果。

The aggregated result contains three documents. The documents represent customer orders that occurred in 2020, with the product_name and product_category of the ordered product:汇总结果包含三个文档。这些文档表示2020年发生的客户订单,包括订购产品的product_nameproduct_category

{
customer_id: 'elise_smith@myemail.com',
orderdate: 2020-05-30T08:35:52.000Z,
value: 431.43,
product_name: 'Asus Laptop',
product_category: 'ELECTRONICS'
}
{
customer_id: 'oranieri@warmmail.com',
orderdate: 2020-01-01T08:25:37.000Z,
value: 63.13,
product_name: 'Morphy Richardds Food Mixer',
product_category: 'KITCHENWARE'
}
{
customer_id: 'jjones@tepidmail.com',
orderdate: 2020-12-26T08:55:46.000Z,
value: 429.65,
product_name: 'Asus Laptop',
product_category: 'ELECTRONICS'
}

The result consists of documents that contain fields from documents in the orders collection and the products collection, joined by matching the product_id field present in each original document.结果由包含orders集合和products集合中文档字段的文档组成,这些字段通过匹配每个原始文档中存在的product_id字段连接在一起。

PHP
1

Add a match stage for orders in 2020.为2020年的订单添加匹配阶段。

Add a $match stage that matches orders placed in 2020:添加一个匹配2020年订单的$match阶段:

Stage::match(
orderdate: [
Query::gte(new UTCDateTime(new DateTimeImmutable('2020-01-01T00:00:00'))),
Query::lt(new UTCDateTime(new DateTimeImmutable('2021-01-01T00:00:00'))),
]
),
2

Add a lookup stage to link the collections.添加查找阶段以链接集合。

Outside of your Pipeline instance, create a $lookup stage in a factory function. The $lookup stage joins the product_id field in the orders collection to the id field in the products collection:Pipeline实例之外,在工厂函数中创建一个$lookup阶段。$lookup阶段将orders集合中的product_id字段与products集合中的id字段连接起来:

function lookupProductsStage()
{
return Stage::lookup(
from: 'products',
localField: 'product_id',
foreignField: 'id',
as: 'product_mapping',
);
}

Then, in your Pipeline instance, call the lookupProductsStage() function:然后,在Pipeline实例中,调用lookupProductsStage()函数:

lookupProductsStage(),
3

Add set stages to create new document fields.添加设置阶段以创建新的文档字段。

Next, add two $set stages to the pipeline.接下来,向管道中添加两个$set阶段。

The first $set stage sets the product_mapping field to the first element in the product_mapping object created in the previous $lookup stage.第一个$set阶段将product_mapping字段设置为在上一个$lookup阶段创建的product_mappings对象中的第一个元素。

The second $set stage creates two new fields, product_name and product_category, from the values in the product_mapping object field:第二个$set阶段根据product_mapping对象字段中的值创建两个新字段product_nameproduct_category

Stage::set(
product_mapping: Expression::first(
Expression::arrayFieldPath('product_mapping')
)
),
Stage::set(
product_name: Expression::stringFieldPath('product_mapping.name'),
product_category: Expression::stringFieldPath('product_mapping.category')
),

Tip

Because this is a one-to-one join, the $lookup stage adds only one array element to the input document. The pipeline uses the $first operator to retrieve the data from this element.因为这是一个一对一的连接,$lookup阶段只向输入文档添加一个数组元素。管道使用$first运算符从该元素检索数据。

4

Add an unset stage to remove unneeded fields.添加未设置的阶段以删除不需要的字段。

Finally, add an $unset stage. The $unset stage removes unnecessary fields from the document:最后,添加一个$unset阶段。$unset阶段从文档中删除不必要的字段:

Stage::unset('_id', 'product_id', 'product_mapping')
5

Run the aggregation pipeline.运行聚合管道。

Add the following code to the end of your application to perform the aggregation on the orders collection:将以下代码添加到应用程序的末尾,以对orders集合执行聚合:

$cursor = $orders->aggregate($pipeline);

Finally, run the following command in your shell to start your application:最后,在shell中运行以下命令以启动应用程序:

php agg_tutorial.php
6

Interpret the aggregation results.解释聚合结果。

The aggregated result contains three documents. The documents represent customer orders that occurred in 2020, with the product_name and product_category of the ordered product:汇总结果包含三个文档。这些文档表示2020年发生的客户订单,包括订购产品的product_nameproduct_category

{
"customer_id": "elise_smith@myemail.com",
"orderdate": {
"$date": {
"$numberLong": "1590827752000"
}
},
"value": 431.43,
"product_name": "Asus Laptop",
"product_category": "ELECTRONICS"
}
{
"customer_id": "oranieri@warmmail.com",
"orderdate": {
"$date": {
"$numberLong": "1577867137000"
}
},
"value": 63.13,
"product_name": "Morphy Richardds Food Mixer",
"product_category": "KITCHENWARE"
}
{
"customer_id": "jjones@tepidmail.com",
"orderdate": {
"$date": {
"$numberLong": "1608972946000"
}
},
"value": 429.65,
"product_name": "Asus Laptop",
"product_category": "ELECTRONICS"
}

The result consists of documents that contain fields from documents in the orders collection and the products collection, joined by matching the product_id field present in each original document.结果由包含orders集合和products集合中文档字段的文档组成,这些字段通过匹配每个原始文档中存在的product_id字段连接在一起。

Python
1

Add a match stage for orders in 2020.为2020年的订单添加匹配阶段。

Add a $match stage that matches orders placed in 2020:添加一个匹配2020年订单的$match阶段:

pipeline.append(
{
"$match": {
"orderdate": {
"$gte": datetime(2020, 1, 1, 0, 0, 0),
"$lt": datetime(2021, 1, 1, 0, 0, 0),
}
}
}
)
2

Add a lookup stage to link the collections.添加查找阶段以链接集合。

Next, add a $lookup stage. The $lookup stage joins the product_id field in the orders collection to the id field in the products collection:接下来,添加一个$lookup阶段。$lookup阶段将orders集合中的product_id字段与产品集合中的id字段连接起来:

pipeline.append(
{
"$lookup": {
"from": "products",
"localField": "product_id",
"foreignField": "id",
"as": "product_mapping",
}
}
)
3

Add set stages to create new document fields.添加设置阶段以创建新的文档字段。

Next, add two $set stages to the pipeline.接下来,向管道中添加两个$set阶段。

The first $set stage sets the product_mapping field to the first element in the product_mapping object created in the previous $lookup stage.第一个$set阶段将product_mapping字段设置为在上一个$lookup阶段创建的product_mappings对象中的第一个元素。

The second $set stage creates two new fields, product_name and product_category, from the values in the product_mapping object field:第二个$set阶段根据product_mapping对象字段中的值创建两个新字段product_nameproduct_category

pipeline.extend(
[
{"$set": {"product_mapping": {"$first": "$product_mapping"}}},
{
"$set": {
"product_name": "$product_mapping.name",
"product_category": "$product_mapping.category",
}
},
]
)

Tip

Because this is a one-to-one join, the $lookup stage adds only one array element to the input document. The pipeline uses the $first operator to retrieve the data from this element.因为这是一个一对一的连接,$lookup阶段只向输入文档添加一个数组元素。管道使用$first运算符从该元素检索数据。

4

Add an unset stage to remove unneeded fields.添加未设置的阶段以删除不需要的字段。

Finally, add an $unset stage. The $unset stage removes unnecessary fields from the document:最后,添加一个$unset阶段。$unset阶段从文档中删除不必要的字段:

pipeline.append({"$unset": ["_id", "product_id", "product_mapping"]})
5

Run the aggregation pipeline.运行聚合管道。

Add the following code to the end of your application to perform the aggregation on the orders collection:将以下代码添加到应用程序的末尾,以对orders集合执行聚合:

aggregation_result = orders_coll.aggregate(pipeline)

Finally, run the following command in your shell to start your application:最后,在shell中运行以下命令以启动应用程序:

python3 agg_tutorial.py
6

Interpret the aggregation results.解释聚合结果。

The aggregated result contains three documents. The documents represent customer orders that occurred in 2020, with the product_name and product_category of the ordered product:汇总结果包含三个文档。这些文档表示2020年发生的客户订单,包括订购产品的product_nameproduct_category

{'customer_id': 'elise_smith@myemail.com', 'orderdate': datetime.datetime(2020, 5, 30, 8, 35, 52), 'value': 431.43, 'product_name': 'Asus Laptop', 'product_category': 'ELECTRONICS'}
{'customer_id': 'oranieri@warmmail.com', 'orderdate': datetime.datetime(2020, 1, 1, 8, 25, 37), 'value': 63.13, 'product_name': 'Morphy Richardds Food Mixer', 'product_category': 'KITCHENWARE'}
{'customer_id': 'jjones@tepidmail.com', 'orderdate': datetime.datetime(2020, 12, 26, 8, 55, 46), 'value': 429.65, 'product_name': 'Asus Laptop', 'product_category': 'ELECTRONICS'}

The result consists of documents that contain fields from documents in the orders collection and the products collection, joined by matching the product_id field present in each original document.结果由包含orders集合和products集合中文档字段的文档组成,这些字段通过匹配每个原始文档中存在的product_id字段连接在一起。

Ruby
1

Add a match stage for orders in 2020.为2020年的订单添加匹配阶段。

Add a $match stage that matches orders placed in 2020:添加一个匹配2020年订单的$match阶段:

{
"$match": {
orderdate: {
"$gte": DateTime.parse("2020-01-01T00:00:00Z"),
"$lt": DateTime.parse("2021-01-01T00:00:00Z"),
},
},
},
2

Add a lookup stage to link the collections.添加查找阶段以链接集合。

Next, add a $lookup stage. The $lookup stage joins the product_id field in the orders collection to the id field in the products collection:接下来,添加一个$lookup阶段。$lookup阶段将orders集合中的product_id字段与产品集合中的id字段连接起来:

{
"$lookup": {
from: "products",
localField: "product_id",
foreignField: "id",
as: "product_mapping",
},
},
3

Add set stages to create new document fields.添加设置阶段以创建新的文档字段。

Next, add two $set stages to the pipeline.接下来,向管道中添加两个$set阶段。

The first $set stage sets the product_mapping field to the first element in the product_mapping object created in the previous $lookup stage.第一个$set阶段将product_mapping字段设置为在上一个$lookup阶段创建的product_mappings对象中的第一个元素。

The second $set stage creates two new fields, product_name and product_category, from the values in the product_mapping object field:第二个$set阶段根据product_mapping对象字段中的值创建两个新字段product_nameproduct_category

{
"$set": {
product_mapping: { "$first": "$product_mapping" },
},
},
{
"$set": {
product_name: "$product_mapping.name",
product_category: "$product_mapping.category",
},
},

Tip

Because this is a one-to-one join, the $lookup stage adds only one array element to the input document. The pipeline uses the $first operator to retrieve the data from this element.因为这是一个一对一的连接,$lookup阶段只向输入文档添加一个数组元素。管道使用$first运算符从该元素检索数据。

4

Add an unset stage to remove unneeded fields.添加未设置的阶段以删除不需要的字段。

Finally, add an $unset stage. The $unset stage removes unnecessary fields from the document:最后,添加一个$unset阶段。$unset阶段从文档中删除不必要的字段:

{ "$unset": ["_id", "product_id", "product_mapping"] },
5

Run the aggregation pipeline.运行聚合管道。

Add the following code to the end of your application to perform the aggregation on the orders collection:将以下代码添加到应用程序的末尾,以对orders集合执行聚合:

aggregation_result = orders.aggregate(pipeline)

Finally, run the following command in your shell to start your application:最后,在shell中运行以下命令以启动应用程序:

ruby agg_tutorial.rb
6

Interpret the aggregation results.解释聚合结果。

The aggregated result contains three documents. The documents represent customer orders that occurred in 2020, with the product_name and product_category of the ordered product:汇总结果包含三个文档。这些文档表示2020年发生的客户订单,包括订购产品的product_nameproduct_category

{"customer_id"=>"elise_smith@myemail.com", "orderdate"=>2020-05-30 08:35:52 UTC, "value"=>431.43, "product_name"=>"Asus Laptop", "product_category"=>"ELECTRONICS"}
{"customer_id"=>"oranieri@warmmail.com", "orderdate"=>2020-01-01 08:25:37 UTC, "value"=>63.13, "product_name"=>"Morphy Richardds Food Mixer", "product_category"=>"KITCHENWARE"}
{"customer_id"=>"jjones@tepidmail.com", "orderdate"=>2020-12-26 08:55:46 UTC, "value"=>429.65, "product_name"=>"Asus Laptop", "product_category"=>"ELECTRONICS"}

The result consists of documents that contain fields from documents in the orders collection and the products collection, joined by matching the product_id field present in each original document.结果由包含orders集合和products集合中文档字段的文档组成,这些字段通过匹配每个原始文档中存在的product_id字段连接在一起。

Rust
1

Add a match stage for orders in 2020.为2020年的订单添加匹配阶段。

Add a $match stage that matches orders placed in 2020:添加一个匹配2020年订单的$match阶段:

pipeline.push(doc! {
"$match": {
"order_date": {
"$gte": DateTime::builder().year(2020).month(1).day(1).build().unwrap(),
"$lt": DateTime::builder().year(2021).month(1).day(1).build().unwrap()
}
}
});
2

Add a lookup stage to link the collections.添加查找阶段以链接集合。

Next, add a $lookup stage. The $lookup stage joins the product_id field in the orders collection to the id field in the products collection:接下来,添加一个$lookup阶段。$lookup阶段将orders集合中的product_id字段与产品集合中的id字段连接起来:

pipeline.push(doc! {
"$lookup": {
"from": "products",
"localField": "product_id",
"foreignField": "id",
"as": "product_mapping"
}
});
3

Add set stages to create new document fields.添加设置阶段以创建新的文档字段。

Next, add two $set stages to the pipeline.接下来,向管道中添加两个$set阶段。

The first $set stage sets the product_mapping field to the first element in the product_mapping object created in the previous $lookup stage.第一个$set阶段将product_mapping字段设置为在上一个$lookup阶段创建的product_mappings对象中的第一个元素。

The second $set stage creates two new fields, product_name and product_category, from the values in the product_mapping object field:第二个$set阶段根据product_mapping对象字段中的值创建两个新字段product_nameproduct_category

pipeline.push(doc! {
"$set": {
"product_mapping": { "$first": "$product_mapping" }
}
});

pipeline.push(doc! {
"$set": {
"product_name": "$product_mapping.name",
"product_category": "$product_mapping.category"
}
});

Tip

Because this is a one-to-one join, the $lookup stage adds only one array element to the input document. The pipeline uses the $first operator to retrieve the data from this element.因为这是一个一对一的连接,$lookup阶段只向输入文档添加一个数组元素。管道使用$first运算符从该元素检索数据。

4

Add an unset stage to remove unneeded fields.添加未设置的阶段以删除不需要的字段。

Finally, add an $unset stage. The $unset stage removes unnecessary fields from the document:最后,添加一个$unset阶段。$unset阶段从文档中删除不必要的字段:

pipeline.push(doc! {
"$unset": ["_id", "product_id", "product_mapping"]
});
5

Run the aggregation pipeline.运行聚合管道。

Add the following code to the end of your application to perform the aggregation on the orders collection:将以下代码添加到应用程序的末尾,以对orders集合执行聚合:

let mut cursor = orders.aggregate(pipeline).await?;

Finally, run the following command in your shell to start your application:最后,在shell中运行以下命令以启动应用程序:

cargo run
6

Interpret the aggregation results.解释聚合结果。

The aggregated result contains three documents. The documents represent customer orders that occurred in 2020, with the product_name and product_category of the ordered product:汇总结果包含三个文档。这些文档表示2020年发生的客户订单,包括订购产品的product_nameproduct_category

Document({"customer_id": String("elise_smith@myemail.com"), "order_date": DateTime(2020-05-30 8:35:52.0 +00:00:00),
"value": Double(431.42999267578125), "product_name": String("Asus Laptop"), "product_category": String("ELECTRONICS")})

Document({"customer_id": String("oranieri@warmmail.com"), "order_date": DateTime(2020-01-01 8:25:37.0 +00:00:00),
"value": Double(63.130001068115234), "product_name": String("Morphy Richardds Food Mixer"), "product_category": String("KITCHENWARE")})

Document({"customer_id": String("jjones@tepidmail.com"), "order_date": DateTime(2020-12-26 8:55:46.0 +00:00:00),
"value": Double(429.6499938964844), "product_name": String("Asus Laptop"), "product_category": String("ELECTRONICS")})

The result consists of documents that contain fields from documents in the orders collection and the products collection, joined by matching the product_id field present in each original document.结果由包含orders集合和products集合中文档字段的文档组成,这些字段通过匹配每个原始文档中存在的product_id字段连接在一起。

scala
1

Add a match stage for orders in 2020.为2020年的订单添加匹配阶段。

Add a $match stage that matches orders placed in 2020:添加一个匹配2020年订单的$match阶段:

Aggregates.filter(Filters.and(
Filters.gte("orderdate", dateFormat.parse("2020-01-01T00:00:00")),
Filters.lt("orderdate", dateFormat.parse("2021-01-01T00:00:00"))
)),
2

Add a lookup stage to link the collections.添加查找阶段以链接集合。

Next, add a $lookup stage. The $lookup stage joins the product_id field in the orders collection to the id field in the products collection:接下来,添加一个$lookup阶段。$lookup阶段将orders集合中的product_id字段与products集合中的id字段连接起来:

Aggregates.lookup(
"products",
"product_id",
"id",
"product_mapping"
),
3

Add set stages to create new document fields.添加设置阶段以创建新的文档字段。

Next, add two $set stages to the pipeline.接下来,向管道中添加两个$set阶段。

The first $set stage sets the product_mapping field to the first element in the product_mapping object created in the previous $lookup stage.第一个$set阶段将product_mapping字段设置为在上一个$lookup阶段创建的product_mappings对象中的第一个元素。

The second $set stage creates two new fields, product_name and product_category, from the values in the product_mapping object field:第二个$set阶段根据product_mapping对象字段中的值创建两个新字段product_nameproduct_category

Aggregates.set(Field("product_mapping", Document("$first" -> "$product_mapping"))),
Aggregates.set(
Field("product_name", "$product_mapping.name"),
Field("product_category", "$product_mapping.category")
),

Tip

Because this is a one-to-one join, the $lookup stage adds only one array element to the input document. The pipeline uses the $first operator to retrieve the data from this element.因为这是一个一对一的连接,$lookup阶段只向输入文档添加一个数组元素。管道使用$first运算符从该元素检索数据。

4

Add an unset stage to remove unneeded fields.添加未设置的阶段以删除不需要的字段。

Finally, add an $unset stage. The $unset stage removes unnecessary fields from the document:最后,添加一个$unset阶段。$unset阶段从文档中删除不必要的字段:

Aggregates.unset("_id", "product_id", "product_mapping")
5

Run the aggregation pipeline.运行聚合管道。

Add the following code to the end of your application to perform the aggregation on the orders collection:将以下代码添加到应用程序的末尾,以对orders集合执行聚合:

orders.aggregate(pipeline)
.subscribe(
(doc: Document) => println(doc.toJson()),
(e: Throwable) => println(s"Error: $e"),
)

Finally, run the application in your IDE.最后,在IDE中运行应用程序。

6

Interpret the aggregation results.解释聚合结果。

The aggregated result contains three documents. The documents represent customer orders that occurred in 2020, with the product_name and product_category of the ordered product:汇总结果包含三个文档。这些文档表示2020年发生的客户订单,包括订购产品的product_nameproduct_category

{"customer_id": "elise_smith@myemail.com", "orderdate": {"$date": "2020-05-30T12:35:52Z"}, "value": 431.43, "product_name": "Asus Laptop", "product_category": "ELECTRONICS"}
{"customer_id": "oranieri@warmmail.com", "orderdate": {"$date": "2020-01-01T13:25:37Z"}, "value": 63.13, "product_name": "Morphy Richardds Food Mixer", "product_category": "KITCHENWARE"}
{"customer_id": "jjones@tepidmail.com", "orderdate": {"$date": "2020-12-26T13:55:46Z"}, "value": 429.65, "product_name": "Asus Laptop", "product_category": "ELECTRONICS"}

The result consists of documents that contain fields from documents in the orders collection and the products collection, joined by matching the product_id field present in each original document.结果由包含orders集合和products集合中文档字段的文档组成,这些字段通过匹配每个原始文档中存在的product_id字段连接在一起。