如何使用Mongocxx将集合加入文档

时间:2018-08-15 00:24:18

标签: join aggregate lookup aggregation mongo-cxx-driver

我有一个名为“ main”的文档(或集合,以最能解决问题的方式为准):

{
    "field1":"value1",
    "objects":[ {"key":1}, {"key":2} ]
}

我还有另一个名为“ foreign”的集合,其中包含以下三个文档:

//document 1
{
    "foreignKey":1,
    "name": "Mike"
}
//document 2     {
    "foreignKey":2,
    "name": "Michael"
}
//document 3
{
    "foreignKey":3,
    "name": "Mick"
}

我希望合并结果为:

//results
{
    "field1":"value1",
    "objects":[ 
        {
            "foreignKey":1,
            "name": "Mike"
        }, 
        {
            "foreignKey":2,
            "name": "Michael"
        }
    ]
}

我仅在MongoDB中找到了几乎可以完成此操作的示例,但是示例中只有一个值数组。但是我有一系列对象。

我不知道如何将其翻译为Mongo-cxx

为方便起见,我从MongoDB site复制了以下示例

------------------------------------------------
//Consider a collection orders with the following //document:
({ "_id" : 1, "item" : "MON1003", "price" : 350, "quantity" : 2, "specs" :
[ "27 inch", "Retina display", "1920x1080" ], "type" : "Monitor" }

//Another collection inventory contains the following //documents:
{ "_id" : 1, "sku" : "MON1003", "type" : "Monitor", "instock" : 120,
"size" : "27 inch", "resolution" : "1920x1080" }
{ "_id" : 2, "sku" : "MON1012", "type" : "Monitor", "instock" : 85,
"size" : "23 inch", "resolution" : "1280x800" }
{ "_id" : 3, "sku" : "MON1031", "type" : "Monitor", "instock" : 60,
"size" : "23 inch", "display_type" : "LED" }
(
//The following aggregation operation performs a join //on documents in the orders collection which match a //particular element of the specs array to the size //field in the inventory collection.
db.orders.aggregate([
   //stage
   {
      $unwind: "$specs"
   },
   //stage
   {
      $lookup:
         {
            from: "inventory",
            localField: "specs",
            foreignField: "size",
            as: "inventory_docs"
        }
   },
   //stage
   {
      $match: { "inventory_docs": { $ne: [] } }
   }
])

//The operation returns the following document:
{
   "_id" : 1,
   "item" : "MON1003",
   "price" : 350,
   "quantity" : 2,
   "specs" : "27 inch",
   "type" : "Monitor",
   "inventory_docs" : [
      {
         "_id" : 1,
         "sku" : "MON1003",
         "type" : "Monitor",
         "instock" : 120,
         "size" : "27 inch",
         "resolution" : "1920x1080"
      }
   ]
}

1 个答案:

答案 0 :(得分:0)

使用您从MongoDB的$lookup with an array链接的示例,并基于aggregation_examples.cpptest/collection.cpp,以下代码使用$ unwind,$ lookup和$ match实现了一个聚合操作,该操作返回与示例中的文档相同:

#include <iostream>

#include <bsoncxx/json.hpp>

#include <mongocxx/client.hpp>
#include <mongocxx/instance.hpp>
#include <mongocxx/uri.hpp>

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

int main(int, char**)
{
    std::cout << "Start program" << std::endl;

    mongocxx::instance instance{};
    mongocxx::client client{ mongocxx::uri{} };

    mongocxx::database db = client["stack"];
    mongocxx::collection colInventory = db["inventory"];

    // Pipeline stages: $unwind, $lookup and $match
    mongocxx::pipeline pipe{};
    pipe.unwind("$specs");
    pipe.lookup(
        make_document(
            kvp("from",         colInventory.name()),
            kvp("localField",   "specs"),
            kvp("foreignField", "size"),
            kvp("as",           "inventory_docs")
        )
    );
    pipe.match(
        make_document(
            kvp("inventory_docs", make_document(kvp("$ne", array{})))
        )
    );

    auto cursor = db["orders"].aggregate(pipe, mongocxx::options::aggregate{});

    for (auto doc : cursor) {
        std::cout << bsoncxx::to_json(doc) << std::endl;
    }

    std::cout << "End program" << std::endl;
}

输出:

Start program
{ "_id" : 1.0, "item" : "MON1003", "price" : 350.0, "quantity" : 2.0, "specs" : "27 inch", "type" : "Monitor", "inventory_docs" : [ { "_id" : 1.0, "sku" : "MON1003", "type" : "Monitor", "instock" : 120.0, "size" : "27 inch", "resolution" : "1920x1080" } ] }
End program

精美打印:

{
    "_id": 1.0,
    "item": "MON1003",
    "price": 350.0,
    "quantity": 2.0,
    "specs": "27 inch",
    "type": "Monitor",
    "inventory_docs": [
        {
            "_id": 1.0,
            "sku": "MON1003",
            "type": "Monitor",
            "instock": 120.0,
            "size": "27 inch",
            "resolution": "1920x1080"
        }
    ]
}