本教程说明了如何构建聚合管道、对集合执行聚合以及使用您选择的语言显示结果。
关于此任务
本教程演示如何将描述产品信息的集合与描述客户订单的另一个集合中的数据组合起来。结果显示在 2020 中下的所有订单的列表,并包括与每个订单相关的产品详细信息。
此聚合执行一对一联接。 当一个collection中的文档的字段值与另一个collection中具有相同字段值的单个文档相匹配时,就会发生一对一连接。聚合根据字段值匹配这些文档,并将两个来源的信息组合成一个结果。
注意
一对一联接不要求文档具有一对一的关系。要学习;了解有关此数据关系的更多信息,请参阅有关 一对一(数据模型)的 Wikipedia 条目。
开始之前
➤ 使用右上角的 Select your 语言)下拉菜单设立以下示例的语言,或选择MongoDB Shell。
此示例使用两个集合:
orders
:描述商店中产品的单个订单的文档products
:描述商店销售的产品的文档
一份订单只能包含一种产品。聚合使用一对一联接将订单文档与相应的产品文档进行匹配。聚合通过两个集合中的文档中存在的 product_id
字段连接两个集合。
要创建 orders
和 products
集合,请使用 insertMany()
方法:
db.orders.deleteMany({}) 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.deleteMany({}) 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 + nosels + winder for tidy storage" } ] )
创建模板应用
在开始学习本聚合教程之前,您必须设立一个新的C应用。您可以使用此应用连接到MongoDB 部署,将示例数据插入MongoDB,然后运行聚合管道。
提示
要学习;了解如何安装驾驶员并连接到MongoDB,请参阅C驱动程序入门指南。
要学习;了解有关在C驱动程序中执行聚合的更多信息,请参阅聚合指南。
安装驾驶员后,创建一个名为 agg-tutorial.c
的文件。将以下代码粘贴到此文件中,为聚合教程创建应用模板。
重要
在以下代码中,阅读代码注释,找到必须根据教程修改的代码部分。
如果您尝试在不进行任何更改的情况下运行代码,则会遇到连接错误。
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; }
对于每个教程,您必须用部署的连接字符串替换连接字符串占位符。
提示
要学习;了解如何找到部署的连接字符串,请参阅C语言入门指南中的创建连接字符串步骤。
例如,如果连接字符串为 "mongodb+srv://mongodb-example:27017"
,则其赋值应如下所示:
char *uri = "mongodb+srv://mongodb-example:27017";
创建集合
此示例使用两个集合:
orders
:描述商店中产品的单个订单的文档products
:描述商店销售的产品的文档
一份订单只能包含一种产品。聚合使用一对一联接将订单文档与相应的产品文档进行匹配。聚合通过两个集合中的文档中存在的 product_id
字段连接两个集合。
要创建 orders
和 products
集合并插入示例数据,请将以下代码添加到您的应用程序中:
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 + nosels + 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++应用。您可以使用此应用连接到MongoDB 部署,将示例数据插入MongoDB,然后运行聚合管道。
提示
要学习;了解如何安装驾驶员并连接到MongoDB,请参阅C++入门教程。
要学习;了解有关使用C++驾驶员的更多信息,请参阅API文档。
要学习;了解有关在C++驱动程序中执行聚合的更多信息,请参阅聚合指南。
安装驾驶员后,创建一个名为 agg-tutorial.cpp
的文件。将以下代码粘贴到此文件中,为聚合教程创建应用模板。
重要
在以下代码中,阅读代码注释,找到必须根据教程修改的代码部分。
如果您尝试在不进行任何更改的情况下运行代码,则会遇到连接错误。
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; } }
对于每个教程,您必须用部署的连接字符串替换连接字符串占位符。
提示
要学习;了解如何找到部署的连接字符串,请参阅C++入门教程中的创建连接字符串步骤。
例如,如果连接字符串为 "mongodb+srv://mongodb-example:27017"
,则其赋值应如下所示:
mongocxx::uri uri{"mongodb+srv://mongodb-example:27017"};
创建集合
此示例使用两个集合:
orders
:描述商店中产品的单个订单的文档products
:描述商店销售的产品的文档
一份订单只能包含一种产品。聚合使用一对一联接将订单文档与相应的产品文档进行匹配。聚合通过两个集合中的文档中存在的 product_id
字段连接两个集合。
要创建 orders
和 products
集合并插入示例数据,请将以下代码添加到您的应用程序中:
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 + nosels + winder for tidy storage" })") }; products.insert_many(product_docs); // Might throw an exception
创建模板应用
在开始学习此聚合教程之前,必须设立一个新的C#/ .NET应用。您可以使用此应用连接到MongoDB 部署,将示例数据插入MongoDB,然后运行聚合管道。
提示
要学习;了解如何安装驾驶员和连接到MongoDB,请参阅C#/.NET驱动程序快速入门指南。
要学习;了解有关在C#/. .NET驱动程序中执行聚合的更多信息,请参阅聚合指南。
安装驾驶员后,将以下代码粘贴到 Program.cs
文件中,为聚合教程创建应用模板。
重要
在以下代码中,阅读代码注释,找到必须根据教程修改的代码部分。
如果您尝试在不进行任何更改的情况下运行代码,则会遇到连接错误。
using MongoDB.Driver; using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; // 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); }
对于每个教程,您必须用部署的连接字符串替换连接字符串占位符。
提示
要学习;了解如何找到部署的连接字符串,请参阅C#快速入门指南中的在Atlas中设置免费层级集群步骤。
例如,如果连接字符串为 "mongodb+srv://mongodb-example:27017"
,则其赋值应如下所示:
var uri = "mongodb+srv://mongodb-example:27017";
创建集合
此示例使用两个集合:
orders
:描述商店中产品的单个订单的文档products
:描述商店销售的产品的文档
一份订单只能包含一种产品。聚合使用一对一联接将订单文档与相应的产品文档进行匹配。聚合通过两个集合中的文档中存在的 ProductId
字段连接两个集合。
首先,创建C#类来对 orders
和 products
集合中的数据进行建模:
public class Order { [ ] public ObjectId Id { get; set; } public string CustomerId { get; set; } public DateTime OrderDate { get; set; } public string ProductId { get; set; } public double Value { get; set; } } public class Product { [ ] public string Id { get; set; } public string Name { get; set; } public string Category { get; set; } public string Description { get; set; } }
要创建 orders
和 products
集合并插入示例数据,请将以下代码添加到您的应用程序中:
var orders = aggDB.GetCollection<Order>("orders"); var products = aggDB.GetCollection<Product>("products"); orders.DeleteMany(Builders<Order>.Filter.Empty); products.DeleteMany(Builders<Product>.Filter.Empty); 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 + nosels + winder for tidy storage" } });
创建模板应用
在开始学习此聚合教程之前,您必须设立一个新的Go应用。您可以使用此应用连接到MongoDB 部署,将示例数据插入MongoDB,然后运行聚合管道。
提示
要学习;了解如何安装驾驶员并连接到MongoDB,请参阅Go驱动程序快速入门指南。
要学习;了解有关在Go驱动程序中执行聚合的更多信息,请参阅聚合指南。
安装驾驶员后,创建一个名为 agg_tutorial.go
的文件。将以下代码粘贴到此文件中,为聚合教程创建应用模板。
重要
在以下代码中,阅读代码注释,找到必须根据教程修改的代码部分。
如果您尝试在不进行任何更改的情况下运行代码,则会遇到连接错误。
package main import ( "context" "fmt" "log" "time" "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() { // 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(context.TODO()); 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(context.TODO(), 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(context.TODO(), pipeline) if err != nil { log.Fatal(err) } defer func() { if err := cursor.Close(context.TODO()); err != nil { log.Fatalf("failed to close cursor: %v", err) } }() // Decode the aggregation results. var results []bson.D if err = cursor.All(context.TODO(), &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)) } }
对于每个教程,您必须用部署的连接字符串替换连接字符串占位符。
提示
要学习;了解如何找到部署的连接字符串,请参阅Go快速入门指南中的创建MongoDB集群步骤。
例如,如果连接字符串为 "mongodb+srv://mongodb-example:27017"
,则其赋值应如下所示:
const uri = "mongodb+srv://mongodb-example:27017";
创建集合
此示例使用两个集合:
orders
:描述商店中产品的单个订单的文档products
:描述商店销售的产品的文档
一份订单只能包含一种产品。聚合使用一对一联接将订单文档与相应的产品文档进行匹配。聚合通过两个集合中的文档中存在的 product_id
字段连接两个集合。
首先,创建Go结构体以对 orders
和 products
集合中的数据进行建模:
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"` }
要创建 orders
和 products
集合并插入示例数据,请将以下代码添加到您的应用程序中:
orders := aggDB.Collection("orders") products := aggDB.Collection("products") orders.DeleteMany(context.TODO(), bson.D{}) products.DeleteMany(context.TODO(), bson.D{}) _, err = orders.InsertMany(context.TODO(), []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(context.TODO(), []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 + nosels + winder for tidy storage", }, }) if err != nil { log.Fatal(err) }
创建模板应用
在开始学习聚合教程之前,您必须设立一个新的Java应用。您可以使用此应用连接到MongoDB 部署,将示例数据插入MongoDB,然后运行聚合管道。
提示
要学习;了解如何安装驾驶员并连接到MongoDB,请参阅Java驱动程序入门指南。
要学习;了解有关在Java Sync 驱动程序中执行聚合的更多信息,请参阅聚合指南。
安装驾驶员后,创建一个名为 AggTutorial.java
的文件。将以下代码粘贴到此文件中,为聚合教程创建应用模板。
重要
在以下代码中,阅读代码注释,找到必须根据教程修改的代码部分。
如果您尝试在不进行任何更改的情况下运行代码,则会遇到连接错误。
package org.example; // Modify imports for each tutorial as needed. import com.mongodb.client.*; import com.mongodb.client.model.Aggregates; import com.mongodb.client.model.Filters; import com.mongodb.client.model.Sorts; import org.bson.Document; import org.bson.conversions.Bson; import java.util.ArrayList; import java.util.Arrays; 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 = ... // Delete any existing documents in collections if needed. // ... someColl.deleteMany(Filters.empty()); // 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()); } } } }
对于每个教程,您必须用部署的连接字符串替换连接字符串占位符。
提示
要学习;了解如何找到部署的连接字符串,请参阅Java Sync 快速入门指南的创建连接字符串步骤。
例如,如果连接字符串为 "mongodb+srv://mongodb-example:27017"
,则其赋值应如下所示:
String uri = "mongodb+srv://mongodb-example:27017";
创建集合
此示例使用两个集合:
orders
:描述商店中产品的单个订单的文档products
:描述商店销售的产品的文档
一份订单只能包含一种产品。聚合使用一对一联接将订单文档与相应的产品文档进行匹配。聚合通过两个集合中的文档中存在的 product_id
字段连接两个集合。
要创建 orders
和 products
集合并插入示例数据,请将以下代码添加到您的应用程序中:
MongoCollection<Document> orders = aggDB.getCollection("orders"); MongoCollection<Document> products = aggDB.getCollection("products"); orders.deleteMany(Filters.empty()); products.deleteMany(Filters.empty()); 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 + nosels + winder for tidy storage") ) );
创建模板应用
在开始学习聚合教程之前,您必须设立一个新的Kotlin应用。您可以使用此应用连接到MongoDB 部署,将示例数据插入MongoDB,然后运行聚合管道。
提示
要学习;了解如何安装驾驶员并连接到MongoDB,请参阅Kotlin驱动程序快速入门指南。
要学习;了解有关在Kotlin驱动程序中执行聚合的更多信息,请参阅聚合指南。
除驾驶员外,您还必须将以下依赖项添加到 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") }
安装驾驶员后,创建一个名为 AggTutorial.kt
的文件。将以下代码粘贴到此文件中,为聚合教程创建应用模板。
重要
在以下代码中,阅读代码注释,找到必须根据教程修改的代码部分。
如果您尝试在不进行任何更改的情况下运行代码,则会遇到连接错误。
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. 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) } } }
对于每个教程,您必须用部署的连接字符串替换连接字符串占位符。
提示
要学习;了解如何找到部署的连接字符串,请参阅Kotlin驱动程序快速入门指南中的连接到集群步骤。
例如,如果连接字符串为 "mongodb+srv://mongodb-example:27017"
,则其赋值应如下所示:
val uri = "mongodb+srv://mongodb-example:27017"
创建集合
此示例使用两个集合:
orders
:描述商店中产品的单个订单的文档products
:描述商店销售的产品的文档
一份订单只能包含一种产品。聚合使用一对一联接将订单文档与相应的产品文档进行匹配。聚合通过两个集合中的文档中存在的 product_id
字段连接两个集合。
首先,创建Kotlin数据类,对 orders
和 products
集合中的数据进行建模:
data class Order( val customerID: String, val orderDate: LocalDateTime, val productID: String, val value: Double ) data class Product( val ID: String, val name: String, val category: String, val description: String )
要创建 orders
和 products
集合并插入示例数据,请将以下代码添加到您的应用程序中:
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 + nosels + winder for tidy storage") ) )
创建模板应用
在开始学习此聚合教程之前,您必须设立一个新的 Node.js应用。您可以使用此应用连接到MongoDB 部署,将示例数据插入MongoDB,然后运行聚合管道。
提示
要学习;了解如何安装驾驶员和连接到MongoDB,请参阅 Node.js驱动程序快速入门指南。
要学习;了解有关在 Node.js驱动程序中执行聚合的更多信息,请参阅聚合指南。
安装驾驶员后,创建一个名为 agg_tutorial.js
的文件。将以下代码粘贴到此文件中,为聚合教程创建应用模板。
重要
在以下代码中,阅读代码注释,找到必须根据教程修改的代码部分。
如果您尝试在不进行任何更改的情况下运行代码,则会遇到连接错误。
const { MongoClient } = require("mongodb"); // Replace the placeholder with your connection string. const uri = "<connection string>"; const client = new MongoClient(uri); 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);
对于每个教程,您必须用部署的连接字符串替换连接字符串占位符。
提示
要学习;了解如何查找部署的连接字符串,请参阅 Node.js 快速入门指南的创建连接字符串步骤。
例如,如果连接字符串为 "mongodb+srv://mongodb-example:27017"
,则其赋值应如下所示:
const uri = "mongodb+srv://mongodb-example:27017";
创建集合
此示例使用两个集合:
orders
:描述商店中产品的单个订单的文档products
:描述商店销售的产品的文档
一份订单只能包含一种产品。聚合使用一对一联接将订单文档与相应的产品文档进行匹配。聚合通过两个集合中的文档中存在的 product_id
字段连接两个集合。
要创建 orders
和 products
集合并插入示例数据,请将以下代码添加到您的应用程序中:
const orders = aggDB.collection("orders"); const products = aggDB.collection("products"); await orders.deleteMany({}); await products.deleteMany({}); 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 + nosels + winder for tidy storage", }, ]);
创建模板应用
在开始学习此聚合教程之前,您必须设立一个新的PHP应用。您可以使用此应用连接到MongoDB 部署,将示例数据插入MongoDB,然后运行聚合管道。
安装该库后,创建一个名为 agg_tutorial.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; }
对于每个教程,您必须用部署的连接字符串替换连接字符串占位符。
提示
要学习;了解如何找到部署的连接字符串,请参阅PHP库入门教程中的创建连接字符串步骤。
例如,如果连接字符串为 "mongodb+srv://mongodb-example:27017"
,则其赋值应如下所示:
$uri = 'mongodb+srv://mongodb-example:27017';
创建集合
此示例使用两个集合:
orders
:描述商店中产品的单个订单的文档products
:描述商店销售的产品的文档
一份订单只能包含一种产品。聚合使用一对一联接将订单文档与相应的产品文档进行匹配。聚合通过两个集合中的文档中存在的 product_id
字段连接两个集合。
要创建 orders
和 products
集合并插入示例数据,请将以下代码添加到您的应用程序中:
$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 + nosels + winder for tidy storage', ], ] );
创建模板应用
在开始学习本聚合教程之前,您必须设立一个新的Python应用。您可以使用此应用连接到MongoDB 部署,将示例数据插入MongoDB,然后运行聚合管道。
提示
要学习;了解如何安装PyMongo并连接到MongoDB,请参阅PyMongo入门教程。
要学习;了解有关在PyMongo中执行聚合的更多信息,请参阅聚合指南。
安装该库后,创建一个名为 agg_tutorial.py
的文件。将以下代码粘贴到此文件中,为聚合教程创建应用模板。
重要
在以下代码中,阅读代码注释,找到必须根据教程修改的代码部分。
如果您尝试在不进行任何更改的情况下运行代码,则会遇到连接错误。
# 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()
对于每个教程,您必须用部署的连接字符串替换连接字符串占位符。
提示
要学习;了解如何找到部署的连接字符串,请参阅PHP库入门教程中的创建连接字符串步骤。
例如,如果连接字符串为 "mongodb+srv://mongodb-example:27017"
,则其赋值应如下所示:
uri = "mongodb+srv://mongodb-example:27017"
创建集合
此示例使用两个集合:
orders
:描述商店中产品的单个订单的文档products
:描述商店销售的产品的文档
一份订单只能包含一种产品。聚合使用一对一联接将订单文档与相应的产品文档进行匹配。聚合通过两个集合中的文档中存在的 product_id
字段连接两个集合。
要创建 orders
和 products
集合并插入示例数据,请将以下代码添加到您的应用程序中:
orders_coll = agg_db["orders"] products_coll = agg_db["products"] orders_coll.delete_many({}) products_coll.delete_many({}) 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 + nosels + winder for tidy storage", }, ] products_coll.insert_many(product_data)
创建模板应用
在开始学习此聚合教程之前,您必须设立一个新的Ruby应用。您可以使用此应用连接到MongoDB 部署,将示例数据插入MongoDB,然后运行聚合管道。
提示
要学习;了解如何安装Ruby驱动程序并连接到MongoDB,请参阅Ruby驱动程序入门指南。
要学习;了解有关在Ruby驱动程序中执行聚合的更多信息,请参阅聚合指南。
安装驾驶员后,创建一个名为 agg_tutorial.rb
的文件。将以下代码粘贴到此文件中,为聚合教程创建应用模板。
重要
在以下代码中,阅读代码注释,找到必须根据教程修改的代码部分。
如果您尝试在不进行任何更改的情况下运行代码,则会遇到连接错误。
# 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
对于每个教程,您必须用部署的连接字符串替换连接字符串占位符。
提示
要学习;了解如何查找部署的连接字符串,请参阅Ruby入门指南的创建连接字符串步骤。
例如,如果连接字符串为 "mongodb+srv://mongodb-example:27017"
,则其赋值应如下所示:
uri = "mongodb+srv://mongodb-example:27017"
创建集合
此示例使用两个集合:
orders
:描述商店中产品的单个订单的文档products
:描述商店销售的产品的文档
一份订单只能包含一种产品。聚合使用一对一联接将订单文档与相应的产品文档进行匹配。聚合通过两个集合中的文档中存在的 product_id
字段连接两个集合。
要创建 orders
和 products
集合并插入示例数据,请将以下代码添加到您的应用程序中:
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 + nosels + winder for tidy storage", }, ] )
创建模板应用
在开始学习本聚合教程之前,您必须设立一个新的Rust应用。您可以使用此应用连接到MongoDB 部署,将示例数据插入MongoDB,然后运行聚合管道。
提示
要学习;了解如何安装驾驶员并连接到MongoDB,请参阅Rust驱动程序快速入门指南。
要学习;了解有关在Rust驱动程序中执行聚合的更多信息,请参阅聚合指南。
安装驾驶员后,创建一个名为 agg-tutorial.rs
的文件。将以下代码粘贴到此文件中,为聚合教程创建应用模板。
重要
在以下代码中,阅读代码注释,找到必须根据教程修改的代码部分。
如果您尝试在不进行任何更改的情况下运行代码,则会遇到连接错误。
use mongodb::{ bson::{doc, Document}, options::ClientOptions, Client, }; use futures::stream::TryStreamExt; use std::error::Error; // Define structs. // #[derive(Debug, Serialize, Deserialize)] // struct MyStruct { ... } 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(()) }
对于每个教程,您必须用部署的连接字符串替换连接字符串占位符。
提示
要学习;了解如何找到部署的连接字符串,请参阅Rust快速入门指南的创建连接字符串步骤。
例如,如果连接字符串为 "mongodb+srv://mongodb-example:27017"
,则其赋值应如下所示:
let uri = "mongodb+srv://mongodb-example:27017";
创建集合
此示例使用两个集合:
orders
:描述商店中产品的单个订单的文档products
:描述商店销售的产品的文档
一份订单只能包含一种产品。聚合使用一对一联接将订单文档与相应的产品文档进行匹配。聚合通过两个集合中的文档中存在的 product_id
字段连接两个集合。
首先,创建Rust结构体以对 orders
和 products
集合中的数据进行建模:
struct Order { customer_id: String, order_date: DateTime, product_id: String, value: f32, } struct Product { id: String, name: String, category: String, description: String, }
要创建 orders
和 products
集合并插入示例数据,请将以下代码添加到您的应用程序中:
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 + nosels + winder for tidy storage".to_string(), }, ]; products.insert_many(product_docs).await?;
创建模板应用
在开始学习聚合教程之前,您必须设立一个新的Scala应用。您可以使用此应用连接到MongoDB 部署,将示例数据插入MongoDB,然后运行聚合管道。
提示
要学习;了解如何安装驾驶员并连接到MongoDB,请参阅Scala驱动程序指南。
要学习;了解有关在Scala驱动程序中执行聚合的更多信息,请参阅聚合指南。
安装驾驶员后,创建一个名为 AggTutorial.scala
的文件。将以下代码粘贴到此文件中,为聚合教程创建应用模板。
重要
在以下代码中,阅读代码注释,找到必须根据教程修改的代码部分。
如果您尝试在不进行任何更改的情况下运行代码,则会遇到连接错误。
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() } }
对于每个教程,您必须用部署的连接字符串替换连接字符串占位符。
提示
要学习;了解如何找到部署的连接字符串,请参阅Scala驱动程序入门指南中的创建连接字符串步骤。
例如,如果连接字符串为 "mongodb+srv://mongodb-example:27017"
,则其赋值应如下所示:
val uri = "mongodb+srv://mongodb-example:27017"
创建集合
此示例使用两个集合:
orders
:描述商店中产品的单个订单的文档products
:描述商店销售的产品的文档
一份订单只能包含一种产品。聚合使用一对一联接将订单文档与相应的产品文档进行匹配。聚合通过两个集合中的文档中存在的 product_id
字段连接两个集合。
要创建 orders
和 products
集合并插入示例数据,请将以下代码添加到您的应用程序中:
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 + nosels + winder for tidy storage" ) ) ).subscribe( _ => {}, e => println("Error: " + e.getMessage), )
步骤
以下步骤演示如何创建和运行聚合管道,以在单个公共字段上连接集合。
运行聚合管道。
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"] } ] )
在此示例中,$lookup
阶段始终输出包含一份文档的 product_mapping
大量。$lookup
阶段之后的 $set
阶段使用 $first
从 product_mapping
大量中提取文档。如果在 $lookup
阶段输出包含多个文档的大量的设置中使用此管道,请考虑在 $lookup
阶段使用显式 { $limit:
1 }
阶段。
解释聚合结果。
聚合结果包含三个文档。这些文档表示 2020 中发生的客户订单,以及所订购产品的 product_name
和 product_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' }
结果由一些文档组成,这些文档包含 orders
集合和 products
集合中文档的字段,该集合通过匹配每个原始文档中存在的 product_id
字段而连接起来。
为 2020 中的订单添加匹配阶段。
添加与 2020 中所下订单相匹配的 $match
阶段:
"{", "$match", "{", "orderdate", "{", "$gte", BCON_DATE_TIME(1577836800000UL), "$lt", BCON_DATE_TIME(1609459200000UL), "}", "}", "}",
添加查找阶段以链接集合。
接下来,添加一个 $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"), "}", "}",
添加设立阶段以创建新的文档字段。
接下来,向管道添加两个$set
阶段。
第一个$set
阶段将product_mapping
字段设置为上一个$lookup
阶段中创建的product_mapping
对象中的第一个元素。
第二个$set
阶段根据product_mapping
对象字段中的值创建两个新字段product_name
和product_category
:
"{", "$set", "{", "product_mapping", "{", "$first", BCON_UTF8("$product_mapping"), "}", "}", "}", "{", "$set", "{", "product_name", BCON_UTF8("$product_mapping.name"), "product_category", BCON_UTF8("$product_mapping.category"), "}", "}",
提示
由于这是一对一连接,因此 $lookup
阶段仅向输入文档添加一个大量元素。管道使用$first
操作符检索此元素中的数据。
添加未设置阶段以删除不需要的字段。
最后,添加一个$unset
阶段。$unset
阶段从文档中删除不必要的字段:
"{", "$unset", "[", BCON_UTF8("_id"), BCON_UTF8("product_id"), BCON_UTF8("product_mapping"), "]", "}",
运行聚合管道。
将以下代码添加到应用程序末尾,以对orders
collection执行聚合:
mongoc_cursor_t *results = mongoc_collection_aggregate(orders, MONGOC_QUERY_NONE, pipeline, NULL, NULL); bson_destroy(pipeline);
通过将以下行添加到清理语句中,确保清理集合资源:
mongoc_collection_destroy(orders); mongoc_collection_destroy(products);
最后,在Shell中运行以下命令,生成并运行可执行文件:
gcc -o aggc agg-tutorial.c $(pkg-config --libs --cflags libmongoc-1.0) ./aggc
提示
如果在一次调用中运行上述命令时遇到连接错误,可以单独运行。
解释聚合结果。
聚合结果包含三个文档。 这些文档表示 2020 年发生的客户订单,以及所订购产品的product_name
和product_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" }
结果由包含来自orders
集合和products
集合中的文档字段的文档组成,通过匹配每个原始文档中存在的product_id
字段来连接这些集合。
为 2020 中的订单添加匹配阶段。
添加与 2020 中所下订单相匹配的 $match
阶段:
pipeline.match(bsoncxx::from_json(R"({ "orderdate": { "$gte": {"$date": 1577836800}, "$lt": {"$date": 1609459200000} } })"));
添加查找阶段以链接集合。
接下来,添加一个 $lookup
阶段。$lookup
阶段将 orders
集合中的 product_id
字段连接到 products
集合中的 id
字段:
pipeline.lookup(bsoncxx::from_json(R"({ "from": "products", "localField": "product_id", "foreignField": "id", "as": "product_mapping" })"));
添加 addFields 阶段以创建新的文档字段。
接下来,向管道添加两个$addFields
阶段。
第一个$addFields
阶段将product_mapping
字段设置为上一个$lookup
阶段中创建的product_mapping
对象中的第一个元素。
第二个$addFields
阶段根据product_mapping
对象字段中的值创建两个新字段product_name
和product_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" })"));
提示
由于这是一对一连接,因此 $lookup
阶段仅向输入文档添加一个大量元素。管道使用$first
操作符检索此元素中的数据。
添加未设置阶段以删除不需要的字段。
最后,添加一个$unset
阶段。$unset
阶段从文档中删除不必要的字段:
pipeline.append_stage(bsoncxx::from_json(R"({ "$unset": ["_id", "product_id", "product_mapping"] })"));
解释聚合结果。
聚合结果包含三个文档。 这些文档表示 2020 年发生的客户订单,以及所订购产品的product_name
和product_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" }
结果由包含来自orders
集合和products
集合中的文档字段的文档组成,通过匹配每个原始文档中存在的product_id
字段来连接这些集合。
为 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"))
添加查找阶段以链接集合。
接下来,添加一个 $lookup
阶段。$lookup
阶段将 orders
集合中的 ProductId
字段连接到 products
集合中的 Id
字段:
.Lookup<Product, Order>( foreignCollectionName: "products", localField: "ProductId", foreignField: "Id", @as: "ProductMapping" )
添加投影阶段以创建新的文档字段并省略不需要的字段。
接下来,向管道添加一个 $project
阶段。
$project
阶段根据 ProductMapping
对象字段中相应值的第一个条目创建两个新字段 ProductName
和 ProductCategory
。该阶段还指定了输出文档中要包含和排除的字段:
.Project(new BsonDocument { { "ProductName", new BsonDocument("$first", "$ProductMapping.Name") }, { "ProductCategory", new BsonDocument("$first", "$ProductMapping.Category") }, { "OrderDate", 1 }, { "CustomerId", 1 }, { "Value", 1 }, { "_id", 0 }, });
提示
由于这是一对一连接,因此 $lookup
阶段仅向输入文档添加一个大量元素。管道使用$first
操作符检索此元素中的数据。
运行聚合并解释结果。
最后,在 IDE 中运行应用程序并检查结果。
聚合结果包含三个文档。 这些文档表示 2020 年发生的客户订单,以及所订购产品的ProductName
和ProductCategory
:
{ "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" }
结果由包含来自orders
集合和products
集合中的文档字段的文档组成,通过匹配每个原始文档中存在的ProductId
字段来连接这些集合。
为 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)}, }}, }}}
添加查找阶段以链接集合。
接下来,添加一个 $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"}, }}}
添加设立阶段以创建新的文档字段。
接下来,向管道添加两个$set
阶段。
第一个$set
阶段将product_mapping
字段设置为上一个$lookup
阶段中创建的product_mapping
对象中的第一个元素。
第二个$set
阶段根据product_mapping
对象字段中的值创建两个新字段product_name
和product_category
:
setStage1 := bson.D{{Key: "$set", Value: bson.D{ {Key: "product_mapping", Value: bson.D{{Key: "$first", Value: "$product_mapping"}}}, }}} setStage2 := bson.D{{Key: "$set", Value: bson.D{ {Key: "product_name", Value: "$product_mapping.name"}, {Key: "product_category", Value: "$product_mapping.category"}, }}}
提示
由于这是一对一连接,因此 $lookup
阶段仅向输入文档添加一个大量元素。管道使用$first
操作符检索此元素中的数据。
添加未设置阶段以删除不需要的字段。
最后,添加一个$unset
阶段。$unset
阶段从文档中删除不必要的字段:
unsetStage := bson.D{{Key: "$unset", Value: bson.A{"_id", "product_id", "product_mapping"}}}
解释聚合结果。
聚合结果包含三个文档。 这些文档表示 2020 年发生的客户订单,以及所订购产品的product_name
和product_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"}
结果由包含来自orders
集合和products
集合中的文档字段的文档组成,通过匹配每个原始文档中存在的product_id
字段来连接这些集合。
为 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")) )));
添加查找阶段以链接集合。
接下来,添加一个 $lookup
阶段。$lookup
阶段将 orders
集合中的 product_id
字段连接到 products
集合中的 id
字段:
pipeline.add(Aggregates.lookup( "products", "product_id", "id", "product_mapping" ));
添加设立阶段以创建新的文档字段。
接下来,向管道添加两个$set
阶段。
第一个$set
阶段将product_mapping
字段设置为上一个$lookup
阶段中创建的product_mapping
对象中的第一个元素。
第二个$set
阶段根据product_mapping
对象字段中的值创建两个新字段product_name
和product_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") ));
提示
由于这是一对一连接,因此 $lookup
阶段仅向输入文档添加一个大量元素。管道使用$first
操作符检索此元素中的数据。
添加未设置阶段以删除不需要的字段。
最后,添加一个$unset
阶段。$unset
阶段从文档中删除不必要的字段:
pipeline.add(Aggregates.unset("_id", "product_id", "product_mapping"));
解释聚合结果。
聚合结果包含三个文档。 这些文档表示 2020 年发生的客户订单,以及所订购产品的product_name
和product_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"}
结果由包含来自orders
集合和products
集合中的文档字段的文档组成,通过匹配每个原始文档中存在的product_id
字段来连接这些集合。
为 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()) ) ) )
添加查找阶段以链接集合。
接下来,添加一个 $lookup
阶段。$lookup
阶段将 orders
集合中的 productID
字段连接到 products
集合中的 ID
字段:
pipeline.add( Aggregates.lookup( "products", Order::productID.name, Product::ID.name, "product_mapping" ) )
添加设立阶段以创建新的文档字段。
接下来,向管道添加两个$set
阶段。
第一个$set
阶段将product_mapping
字段设置为上一个$lookup
阶段中创建的product_mapping
对象中的第一个元素。
第二个$set
阶段根据product_mapping
对象字段中的值创建两个新字段product_name
和product_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") ) )
提示
由于这是一对一连接,因此 $lookup
阶段仅向输入文档添加一个大量元素。管道使用$first
操作符检索此元素中的数据。
添加未设置阶段以删除不需要的字段。
最后,添加一个$unset
阶段。$unset
阶段从文档中删除不必要的字段:
pipeline.add(Aggregates.unset("_id", Order::productID.name, "product_mapping"))
解释聚合结果。
聚合结果包含三个文档。 这些文档表示 2020 年发生的客户订单,以及所订购产品的product_name
和product_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}}
结果由包含来自orders
集合和products
集合中的文档字段的文档组成,通过匹配每个原始文档中存在的product_id
字段来连接这些集合。
为 2020 中的订单添加匹配阶段。
添加与 2020 中所下订单相匹配的 $match
阶段:
pipeline.push({ $match: { orderdate: { $gte: new Date("2020-01-01T00:00:00Z"), $lt: new Date("2021-01-01T00:00:00Z"), }, }, });
添加查找阶段以链接集合。
接下来,添加一个 $lookup
阶段。$lookup
阶段将 orders
集合中的 product_id
字段连接到 products
集合中的 id
字段:
pipeline.push({ $lookup: { from: "products", localField: "product_id", foreignField: "id", as: "product_mapping", }, });
添加设立阶段以创建新的文档字段。
接下来,向管道添加两个$set
阶段。
第一个$set
阶段将product_mapping
字段设置为上一个$lookup
阶段中创建的product_mapping
对象中的第一个元素。
第二个$set
阶段根据product_mapping
对象字段中的值创建两个新字段product_name
和product_category
:
pipeline.push( { $set: { product_mapping: { $first: "$product_mapping" }, }, }, { $set: { product_name: "$product_mapping.name", product_category: "$product_mapping.category", }, } );
提示
由于这是一对一连接,因此 $lookup
阶段仅向输入文档添加一个大量元素。管道使用$first
操作符检索此元素中的数据。
添加未设置阶段以删除不需要的字段。
最后,添加一个$unset
阶段。$unset
阶段从文档中删除不必要的字段:
pipeline.push({ $unset: ["_id", "product_id", "product_mapping"] });
解释聚合结果。
聚合结果包含三个文档。 这些文档表示 2020 年发生的客户订单,以及所订购产品的product_name
和product_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' }
结果由包含来自orders
集合和products
集合中的文档字段的文档组成,通过匹配每个原始文档中存在的product_id
字段来连接这些集合。
为 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'))), ] ),
添加查找阶段以链接集合。
在 Pipeline
实例之外,在工厂函数中创建一个$lookup
阶段。``$lookup`` 阶段将 orders
集合中的 product_id
字段连接到 products
集合中的 id
字段:
function lookupProductsStage() { return Stage::lookup( from: 'products', localField: 'product_id', foreignField: 'id', as: 'product_mapping', ); }
然后,在 Pipeline
实例中调用 lookupProductsStage()
函数:
lookupProductsStage(),
添加设立阶段以创建新的文档字段。
接下来,向管道添加两个$set
阶段。
第一个$set
阶段将product_mapping
字段设置为上一个$lookup
阶段中创建的product_mapping
对象中的第一个元素。
第二个$set
阶段根据product_mapping
对象字段中的值创建两个新字段product_name
和product_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') ),
提示
由于这是一对一连接,因此 $lookup
阶段仅向输入文档添加一个大量元素。管道使用$first
操作符检索此元素中的数据。
添加未设置阶段以删除不需要的字段。
最后,添加一个$unset
阶段。$unset
阶段从文档中删除不必要的字段:
Stage::unset('_id', 'product_id', 'product_mapping')
解释聚合结果。
聚合结果包含三个文档。 这些文档表示 2020 年发生的客户订单,以及所订购产品的product_name
和product_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" }
结果由包含来自orders
集合和products
集合中的文档字段的文档组成,通过匹配每个原始文档中存在的product_id
字段来连接这些集合。
为 2020 中的订单添加匹配阶段。
添加与 2020 中所下订单相匹配的 $match
阶段:
pipeline.append( { "$match": { "orderdate": { "$gte": datetime(2020, 1, 1, 0, 0, 0), "$lt": datetime(2021, 1, 1, 0, 0, 0), } } } )
添加查找阶段以链接集合。
接下来,添加一个 $lookup
阶段。$lookup
阶段将 orders
集合中的 product_id
字段连接到 products
集合中的 id
字段:
pipeline.append( { "$lookup": { "from": "products", "localField": "product_id", "foreignField": "id", "as": "product_mapping", } } )
添加设立阶段以创建新的文档字段。
接下来,向管道添加两个$set
阶段。
第一个$set
阶段将product_mapping
字段设置为上一个$lookup
阶段中创建的product_mapping
对象中的第一个元素。
第二个$set
阶段根据product_mapping
对象字段中的值创建两个新字段product_name
和product_category
:
pipeline.extend( [ {"$set": {"product_mapping": {"$first": "$product_mapping"}}}, { "$set": { "product_name": "$product_mapping.name", "product_category": "$product_mapping.category", } }, ] )
提示
由于这是一对一连接,因此 $lookup
阶段仅向输入文档添加一个大量元素。管道使用$first
操作符检索此元素中的数据。
添加未设置阶段以删除不需要的字段。
最后,添加一个$unset
阶段。$unset
阶段从文档中删除不必要的字段:
pipeline.append({"$unset": ["_id", "product_id", "product_mapping"]})
解释聚合结果。
聚合结果包含三个文档。 这些文档表示 2020 年发生的客户订单,以及所订购产品的product_name
和product_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'}
结果由包含来自orders
集合和products
集合中的文档字段的文档组成,通过匹配每个原始文档中存在的product_id
字段来连接这些集合。
为 2020 中的订单添加匹配阶段。
添加与 2020 中所下订单相匹配的 $match
阶段:
{ "$match": { orderdate: { "$gte": DateTime.parse("2020-01-01T00:00:00Z"), "$lt": DateTime.parse("2021-01-01T00:00:00Z"), }, }, },
添加查找阶段以链接集合。
接下来,添加一个 $lookup
阶段。$lookup
阶段将 orders
集合中的 product_id
字段连接到 products
集合中的 id
字段:
{ "$lookup": { from: "products", localField: "product_id", foreignField: "id", as: "product_mapping", }, },
添加设立阶段以创建新的文档字段。
接下来,向管道添加两个$set
阶段。
第一个$set
阶段将product_mapping
字段设置为上一个$lookup
阶段中创建的product_mapping
对象中的第一个元素。
第二个$set
阶段根据product_mapping
对象字段中的值创建两个新字段product_name
和product_category
:
{ "$set": { product_mapping: { "$first": "$product_mapping" }, }, }, { "$set": { product_name: "$product_mapping.name", product_category: "$product_mapping.category", }, },
提示
由于这是一对一连接,因此 $lookup
阶段仅向输入文档添加一个大量元素。管道使用$first
操作符检索此元素中的数据。
添加未设置阶段以删除不需要的字段。
最后,添加一个$unset
阶段。$unset
阶段从文档中删除不必要的字段:
{ "$unset": ["_id", "product_id", "product_mapping"] },
解释聚合结果。
聚合结果包含三个文档。 这些文档表示 2020 年发生的客户订单,以及所订购产品的product_name
和product_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"}
结果由包含来自orders
集合和products
集合中的文档字段的文档组成,通过匹配每个原始文档中存在的product_id
字段来连接这些集合。
为 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() } } });
添加查找阶段以链接集合。
接下来,添加一个 $lookup
阶段。$lookup
阶段将 orders
集合中的 product_id
字段连接到 products
集合中的 id
字段:
pipeline.push(doc! { "$lookup": { "from": "products", "localField": "product_id", "foreignField": "id", "as": "product_mapping" } });
添加设立阶段以创建新的文档字段。
接下来,向管道添加两个$set
阶段。
第一个$set
阶段将product_mapping
字段设置为上一个$lookup
阶段中创建的product_mapping
对象中的第一个元素。
第二个$set
阶段根据product_mapping
对象字段中的值创建两个新字段product_name
和product_category
:
pipeline.push(doc! { "$set": { "product_mapping": { "$first": "$product_mapping" } } }); pipeline.push(doc! { "$set": { "product_name": "$product_mapping.name", "product_category": "$product_mapping.category" } });
提示
由于这是一对一连接,因此 $lookup
阶段仅向输入文档添加一个大量元素。管道使用$first
操作符检索此元素中的数据。
添加未设置阶段以删除不需要的字段。
最后,添加一个$unset
阶段。$unset
阶段从文档中删除不必要的字段:
pipeline.push(doc! { "$unset": ["_id", "product_id", "product_mapping"] });
解释聚合结果。
聚合结果包含三个文档。 这些文档表示 2020 年发生的客户订单,以及所订购产品的product_name
和product_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")})
结果由包含来自orders
集合和products
集合中的文档字段的文档组成,通过匹配每个原始文档中存在的product_id
字段来连接这些集合。
为 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")) )),
添加查找阶段以链接集合。
接下来,添加一个 $lookup
阶段。$lookup
阶段将 orders
集合中的 product_id
字段连接到 products
集合中的 id
字段:
Aggregates.lookup( "products", "product_id", "id", "product_mapping" ),
添加设立阶段以创建新的文档字段。
接下来,向管道添加两个$set
阶段。
第一个$set
阶段将product_mapping
字段设置为上一个$lookup
阶段中创建的product_mapping
对象中的第一个元素。
第二个$set
阶段根据product_mapping
对象字段中的值创建两个新字段product_name
和product_category
:
Aggregates.set(Field("product_mapping", Document("$first" -> "$product_mapping"))), Aggregates.set( Field("product_name", "$product_mapping.name"), Field("product_category", "$product_mapping.category") ),
提示
由于这是一对一连接,因此 $lookup
阶段仅向输入文档添加一个大量元素。管道使用$first
操作符检索此元素中的数据。
添加未设置阶段以删除不需要的字段。
最后,添加一个$unset
阶段。$unset
阶段从文档中删除不必要的字段:
Aggregates.unset("_id", "product_id", "product_mapping")
解释聚合结果。
聚合结果包含三个文档。 这些文档表示 2020 年发生的客户订单,以及所订购产品的product_name
和product_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"}
结果由包含来自orders
集合和products
集合中的文档字段的文档组成,通过匹配每个原始文档中存在的product_id
字段来连接这些集合。