web-dev-qa-db-ja.com

MongoDB:複数のコレクションからのデータを1つにまとめます。

MongoDBで複数のコレクションのデータを1つのコレクションにまとめるにはどうすればよいですか。

Map-reduceを使えますか?できればどうすればいいですか?

私は初心者なので、私はいくつかの例を大いに感謝するでしょう。

199
user697697

このリアルタイムを行うことはできませんが、MongoDB 1.8+ map/reduceの「reduce」オプションを使用して、map-reduceを複数回実行してデータをマージすることができます( http:// www。 mongodb.org/display/DOCS/MapReduce#MapReduce-Outputoptions )。 _idとして使用できる両方のコレクションにいくつかのキーが必要です。

たとえば、usersコレクションとcommentsコレクションがあり、各コメントのユーザー属性情報を含む新しいコレクションが必要だとします。

usersコレクションに次のフィールドがあるとします。

  • _id
  • ファーストネーム
  • 苗字
  • 性別
  • 年齢

そして、commentsコレクションには次のフィールドがあります。

  • _id
  • ユーザーID
  • コメント
  • 作成した

このmap/reduceを実行します:

var mapUsers, mapComments, reduce;
db.users_comments.remove();

// setup sample data - wouldn't actually use this in production
db.users.remove();
db.comments.remove();
db.users.save({firstName:"Rich",lastName:"S",gender:"M",country:"CA",age:"18"});
db.users.save({firstName:"Rob",lastName:"M",gender:"M",country:"US",age:"25"});
db.users.save({firstName:"Sarah",lastName:"T",gender:"F",country:"US",age:"13"});
var users = db.users.find();
db.comments.save({userId: users[0]._id, "comment": "Hey, what's up?", created: new ISODate()});
db.comments.save({userId: users[1]._id, "comment": "Not much", created: new ISODate()});
db.comments.save({userId: users[0]._id, "comment": "Cool", created: new ISODate()});
// end sample data setup

mapUsers = function() {
    var values = {
        country: this.country,
        gender: this.gender,
        age: this.age
    };
    emit(this._id, values);
};
mapComments = function() {
    var values = {
        commentId: this._id,
        comment: this.comment,
        created: this.created
    };
    emit(this.userId, values);
};
reduce = function(k, values) {
    var result = {}, commentFields = {
        "commentId": '', 
        "comment": '',
        "created": ''
    };
    values.forEach(function(value) {
        var field;
        if ("comment" in value) {
            if (!("comments" in result)) {
                result.comments = [];
            }
            result.comments.Push(value);
        } else if ("comments" in value) {
            if (!("comments" in result)) {
                result.comments = [];
            }
            result.comments.Push.apply(result.comments, value.comments);
        }
        for (field in value) {
            if (value.hasOwnProperty(field) && !(field in commentFields)) {
                result[field] = value[field];
            }
        }
    });
    return result;
};
db.users.mapReduce(mapUsers, reduce, {"out": {"reduce": "users_comments"}});
db.comments.mapReduce(mapComments, reduce, {"out": {"reduce": "users_comments"}});
db.users_comments.find().pretty(); // see the resulting collection

この時点で、マージされたデータを含むusers_commentsという新しいコレクションが作成され、それを使用できるようになります。これらの縮小されたコレクションはすべて、マップ関数で発行したキーである_idを持ち、すべての値はvalueキー内のサブオブジェクトです-値は最上位にありませんこれらの削減されたドキュメントの。

これはやや単純な例です。縮小されたコレクションを構築し続けたい限り、より多くのコレクションでこれを繰り返すことができます。また、プロセスでデータの要約と集計を行うこともできます。既存のフィールドを集約して保持するためのロジックが複雑になるため、複数のリデュース関数を定義する可能性があります。

また、ユーザーごとに1つのドキュメントがあり、そのユーザーのコメントがすべて配列に含まれていることにも注意してください。 1対多ではなく1対1の関係を持つデータをマージする場合、フラットになり、次のようなreduce関数を使用できます。

reduce = function(k, values) {
    var result = {};
    values.forEach(function(value) {
        var field;
        for (field in value) {
            if (value.hasOwnProperty(field)) {
                result[field] = value[field];
            }
        }
    });
    return result;
};

users_commentsコレクションをフラット化してコメントごとに1つのドキュメントにする場合は、さらに次を実行します。

var map, reduce;
map = function() {
    var debug = function(value) {
        var field;
        for (field in value) {
            print(field + ": " + value[field]);
        }
    };
    debug(this);
    var that = this;
    if ("comments" in this.value) {
        this.value.comments.forEach(function(value) {
            emit(value.commentId, {
                userId: that._id,
                country: that.value.country,
                age: that.value.age,
                comment: value.comment,
                created: value.created,
            });
        });
    }
};
reduce = function(k, values) {
    var result = {};
    values.forEach(function(value) {
        var field;
        for (field in value) {
            if (value.hasOwnProperty(field)) {
                result[field] = value[field];
            }
        }
    });
    return result;
};
db.users_comments.mapReduce(map, reduce, {"out": "comments_with_demographics"});

この手法は、即座に実行されるべきではありません。 cronジョブなど、マージされたデータを定期的に更新するようなものに適しています。おそらく、新しいコレクションに対してensureIndexを実行して、それに対して実行するクエリを確実に迅速に実行することをお勧めします(データがまだvalueキー内にあることに留意してください。 comments_with_demographicsコメントのcreated時間、それはdb.comments_with_demographics.ensureIndex({"value.created": 1});になります

140
rmarscher

MongoDB 3.2では、 $ lookup aggregation stage によって、複数のコレクションのデータを1つにまとめることができます。実用的な例として、本に関するデータが2つの異なるコレクションに分割されているとしましょう。

以下のデータを持つbooksという最初のコレクション。

{
    "isbn": "978-3-16-148410-0",
    "title": "Some cool book",
    "author": "John Doe"
}
{
    "isbn": "978-3-16-148999-9",
    "title": "Another awesome book",
    "author": "Jane Roe"
}

そしてbooks_selling_dataという2番目のコレクションは、以下のデータを持ちます。

{
    "_id": ObjectId("56e31bcf76cdf52e541d9d26"),
    "isbn": "978-3-16-148410-0",
    "copies_sold": 12500
}
{
    "_id": ObjectId("56e31ce076cdf52e541d9d28"),
    "isbn": "978-3-16-148999-9",
    "copies_sold": 720050
}
{
    "_id": ObjectId("56e31ce076cdf52e541d9d29"),
    "isbn": "978-3-16-148999-9",
    "copies_sold": 1000
}

両方のコレクションをマージすることは、単に$ lookupを次のように使用することの問題です。

db.books.aggregate([{
    $lookup: {
            from: "books_selling_data",
            localField: "isbn",
            foreignField: "isbn",
            as: "copies_sold"
        }
}])

この集約後、booksコレクションは次のようになります。

{
    "isbn": "978-3-16-148410-0",
    "title": "Some cool book",
    "author": "John Doe",
    "copies_sold": [
        {
            "_id": ObjectId("56e31bcf76cdf52e541d9d26"),
            "isbn": "978-3-16-148410-0",
            "copies_sold": 12500
        }
    ]
}
{
    "isbn": "978-3-16-148999-9",
    "title": "Another awesome book",
    "author": "Jane Roe",
    "copies_sold": [
        {
            "_id": ObjectId("56e31ce076cdf52e541d9d28"),
            "isbn": "978-3-16-148999-9",
            "copies_sold": 720050
        },
        {
            "_id": ObjectId("56e31ce076cdf52e541d9d28"),
            "isbn": "978-3-16-148999-9",
            "copies_sold": 1000
        }
    ]
}

いくつか注意することが重要です。

  1. "from"コレクション、この場合はbooks_selling_dataは、分割できません。
  2. 上記の例のように、 "as"フィールドは配列になります。
  3. $ lookupステージ の "localField"と "foreignField"オプションは、それぞれのコレクションに存在しない場合、マッチングのためにnullとして扱われます( $ lookup docs =についての完全な例があります)。

したがって、結論として、両方のコレクションを統合したい場合、この場合は販売された総コピー数を含む平らなcopies_soldフィールドを使用し、もう少し作業を進める必要があります。おそらく中間コレクションを使用します。最終的なコレクションに $ out となります。

104
Bruno Krebs

Mongodbへの一括挿入がない場合は、small_collection内のすべてのオブジェクトをループし、それらを1つずつbig_collectionに挿入します。

db.small_collection.find().forEach(function(obj){ 
   db.big_collection.insert(obj)
});
12
Hieu Le

$ lookupを使った非常に基本的な例。

db.getCollection('users').aggregate([
    {
        $lookup: {
            from: "userinfo",
            localField: "userId",
            foreignField: "userId",
            as: "userInfoData"
        }
    },
    {
        $lookup: {
            from: "userrole",
            localField: "userId",
            foreignField: "userId",
            as: "userRoleData"
        }
    },
    { $unwind: { path: "$userInfoData", preserveNullAndEmptyArrays: true }},
    { $unwind: { path: "$userRoleData", preserveNullAndEmptyArrays: true }}
])

こちらが使われています

 { $unwind: { path: "$userInfoData", preserveNullAndEmptyArrays: true }}, 
 { $unwind: { path: "$userRoleData", preserveNullAndEmptyArrays: true }}

の代わりに

{ $unwind:"$userRoleData"} 
{ $unwind:"$userRoleData"}

{$ unwind: "$ userRoleData"}これは空を返すか、$ lookupで一致するレコードが見つからない場合は0を返します。

9
Anish Agarwal

集約内の複数のコレクションに対して複数の$ lookupを使用する

query:

db.getCollection('servicelocations').aggregate([
  {
    $match: {
      serviceLocationId: {
        $in: ["36728"]
      }
    }
  },
  {
    $lookup: {
      from: "orders",
      localField: "serviceLocationId",
      foreignField: "serviceLocationId",
      as: "orders"
    }
  },
  {
    $lookup: {
      from: "timewindowtypes",
      localField: "timeWindow.timeWindowTypeId",
      foreignField: "timeWindowTypeId",
      as: "timeWindow"
    }
  },
  {
    $lookup: {
      from: "servicetimetypes",
      localField: "serviceTimeTypeId",
      foreignField: "serviceTimeTypeId",
      as: "serviceTime"
    }
  },
  {
    $unwind: "$orders"
  },
  {
    $unwind: "$serviceTime"
  },
  {
    $limit: 14
  }
])

結果:

{
    "_id" : ObjectId("59c3ac4bb7799c90ebb3279b"),
    "serviceLocationId" : "36728",
    "regionId" : 1.0,
    "zoneId" : "DXBZONE1",
    "description" : "AL HALLAB REST EMIRATES MALL",
    "locationPriority" : 1.0,
    "accountTypeId" : 1.0,
    "locationType" : "SERVICELOCATION",
    "location" : {
        "makani" : "",
        "lat" : 25.119035,
        "lng" : 55.198694
    },
    "deliveryDays" : "MTWRFSU",
    "timeWindow" : [ 
        {
            "_id" : ObjectId("59c3b0a3b7799c90ebb32cde"),
            "timeWindowTypeId" : "1",
            "Description" : "MORNING",
            "timeWindow" : {
                "openTime" : "06:00",
                "closeTime" : "08:00"
            },
            "accountId" : 1.0
        }, 
        {
            "_id" : ObjectId("59c3b0a3b7799c90ebb32cdf"),
            "timeWindowTypeId" : "1",
            "Description" : "MORNING",
            "timeWindow" : {
                "openTime" : "09:00",
                "closeTime" : "10:00"
            },
            "accountId" : 1.0
        }, 
        {
            "_id" : ObjectId("59c3b0a3b7799c90ebb32ce0"),
            "timeWindowTypeId" : "1",
            "Description" : "MORNING",
            "timeWindow" : {
                "openTime" : "10:30",
                "closeTime" : "11:30"
            },
            "accountId" : 1.0
        }
    ],
    "address1" : "",
    "address2" : "",
    "phone" : "",
    "city" : "",
    "county" : "",
    "state" : "",
    "country" : "",
    "zipcode" : "",
    "imageUrl" : "",
    "contact" : {
        "name" : "",
        "email" : ""
    },
    "status" : "ACTIVE",
    "createdBy" : "",
    "updatedBy" : "",
    "updateDate" : "",
    "accountId" : 1.0,
    "serviceTimeTypeId" : "1",
    "orders" : [ 
        {
            "_id" : ObjectId("59c3b291f251c77f15790f92"),
            "orderId" : "AQ18O1704264",
            "serviceLocationId" : "36728",
            "orderNo" : "AQ18O1704264",
            "orderDate" : "18-Sep-17",
            "description" : "AQ18O1704264",
            "serviceType" : "Delivery",
            "orderSource" : "Import",
            "takenBy" : "KARIM",
            "plannedDeliveryDate" : ISODate("2017-08-26T00:00:00.000Z"),
            "plannedDeliveryTime" : "",
            "actualDeliveryDate" : "",
            "actualDeliveryTime" : "",
            "deliveredBy" : "",
            "size1" : 296.0,
            "size2" : 3573.355,
            "size3" : 240.811,
            "jobPriority" : 1.0,
            "cancelReason" : "",
            "cancelDate" : "",
            "cancelBy" : "",
            "reasonCode" : "",
            "reasonText" : "",
            "status" : "",
            "lineItems" : [ 
                {
                    "ItemId" : "BNWB020",
                    "size1" : 15.0,
                    "size2" : 78.6,
                    "size3" : 6.0
                }, 
                {
                    "ItemId" : "BNWB021",
                    "size1" : 20.0,
                    "size2" : 252.0,
                    "size3" : 11.538
                }, 
                {
                    "ItemId" : "BNWB023",
                    "size1" : 15.0,
                    "size2" : 285.0,
                    "size3" : 16.071
                }, 
                {
                    "ItemId" : "CPMW112",
                    "size1" : 3.0,
                    "size2" : 25.38,
                    "size3" : 1.731
                }, 
                {
                    "ItemId" : "MMGW001",
                    "size1" : 25.0,
                    "size2" : 464.375,
                    "size3" : 46.875
                }, 
                {
                    "ItemId" : "MMNB218",
                    "size1" : 50.0,
                    "size2" : 920.0,
                    "size3" : 60.0
                }, 
                {
                    "ItemId" : "MMNB219",
                    "size1" : 50.0,
                    "size2" : 630.0,
                    "size3" : 40.0
                }, 
                {
                    "ItemId" : "MMNB220",
                    "size1" : 50.0,
                    "size2" : 416.0,
                    "size3" : 28.846
                }, 
                {
                    "ItemId" : "MMNB270",
                    "size1" : 50.0,
                    "size2" : 262.0,
                    "size3" : 20.0
                }, 
                {
                    "ItemId" : "MMNB302",
                    "size1" : 15.0,
                    "size2" : 195.0,
                    "size3" : 6.0
                }, 
                {
                    "ItemId" : "MMNB373",
                    "size1" : 3.0,
                    "size2" : 45.0,
                    "size3" : 3.75
                }
            ],
            "accountId" : 1.0
        }, 
        {
            "_id" : ObjectId("59c3b291f251c77f15790f9d"),
            "orderId" : "AQ137O1701240",
            "serviceLocationId" : "36728",
            "orderNo" : "AQ137O1701240",
            "orderDate" : "18-Sep-17",
            "description" : "AQ137O1701240",
            "serviceType" : "Delivery",
            "orderSource" : "Import",
            "takenBy" : "KARIM",
            "plannedDeliveryDate" : ISODate("2017-08-26T00:00:00.000Z"),
            "plannedDeliveryTime" : "",
            "actualDeliveryDate" : "",
            "actualDeliveryTime" : "",
            "deliveredBy" : "",
            "size1" : 28.0,
            "size2" : 520.11,
            "size3" : 52.5,
            "jobPriority" : 1.0,
            "cancelReason" : "",
            "cancelDate" : "",
            "cancelBy" : "",
            "reasonCode" : "",
            "reasonText" : "",
            "status" : "",
            "lineItems" : [ 
                {
                    "ItemId" : "MMGW001",
                    "size1" : 25.0,
                    "size2" : 464.38,
                    "size3" : 46.875
                }, 
                {
                    "ItemId" : "MMGW001-F1",
                    "size1" : 3.0,
                    "size2" : 55.73,
                    "size3" : 5.625
                }
            ],
            "accountId" : 1.0
        }, 
        {
            "_id" : ObjectId("59c3b291f251c77f15790fd8"),
            "orderId" : "AQ110O1705036",
            "serviceLocationId" : "36728",
            "orderNo" : "AQ110O1705036",
            "orderDate" : "18-Sep-17",
            "description" : "AQ110O1705036",
            "serviceType" : "Delivery",
            "orderSource" : "Import",
            "takenBy" : "KARIM",
            "plannedDeliveryDate" : ISODate("2017-08-26T00:00:00.000Z"),
            "plannedDeliveryTime" : "",
            "actualDeliveryDate" : "",
            "actualDeliveryTime" : "",
            "deliveredBy" : "",
            "size1" : 60.0,
            "size2" : 1046.0,
            "size3" : 68.0,
            "jobPriority" : 1.0,
            "cancelReason" : "",
            "cancelDate" : "",
            "cancelBy" : "",
            "reasonCode" : "",
            "reasonText" : "",
            "status" : "",
            "lineItems" : [ 
                {
                    "ItemId" : "MMNB218",
                    "size1" : 50.0,
                    "size2" : 920.0,
                    "size3" : 60.0
                }, 
                {
                    "ItemId" : "MMNB219",
                    "size1" : 10.0,
                    "size2" : 126.0,
                    "size3" : 8.0
                }
            ],
            "accountId" : 1.0
        }
    ],
    "serviceTime" : {
        "_id" : ObjectId("59c3b07cb7799c90ebb32cdc"),
        "serviceTimeTypeId" : "1",
        "serviceTimeType" : "nohelper",
        "description" : "",
        "fixedTime" : 30.0,
        "variableTime" : 0.0,
        "accountId" : 1.0
    }
}
8
KARTHIKEYAN.A

Mongorestoreには、データベース内にあるものすべてに追加するというこの機能があるため、この動作は2つのコレクションを組み合わせるために使用できます。

  1. モンゴダンプコレクション1
  2. collection2.rename(コレクション1)
  3. モンゴルストア

まだ試していませんでしたが、map/reduceアプローチよりも速く実行される可能性があります。

2
shauli

コードスニペット。礼儀 - これを含むスタックオーバーフローに関する複数の投稿。

 db.cust.drop();
 db.Zip.drop();
 db.cust.insert({cust_id:1, Zip_id: 101});
 db.cust.insert({cust_id:2, Zip_id: 101});
 db.cust.insert({cust_id:3, Zip_id: 101});
 db.cust.insert({cust_id:4, Zip_id: 102});
 db.cust.insert({cust_id:5, Zip_id: 102});

 db.Zip.insert({Zip_id:101, Zip_cd:'AAA'});
 db.Zip.insert({Zip_id:102, Zip_cd:'BBB'});
 db.Zip.insert({Zip_id:103, Zip_cd:'CCC'});

mapCust = function() {
    var values = {
        cust_id: this.cust_id
    };
    emit(this.Zip_id, values);
};

mapZip = function() {
    var values = {
    Zip_cd: this.Zip_cd
    };
    emit(this.Zip_id, values);
};

reduceCustZip =  function(k, values) {
    var result = {};
    values.forEach(function(value) {
    var field;
        if ("cust_id" in value) {
            if (!("cust_ids" in result)) {
                result.cust_ids = [];
            }
            result.cust_ids.Push(value);
        } else {
    for (field in value) {
        if (value.hasOwnProperty(field) ) {
                result[field] = value[field];
        }
         };  
       }
      });
       return result;
};


db.cust_Zip.drop();
db.cust.mapReduce(mapCust, reduceCustZip, {"out": {"reduce": "cust_Zip"}});
db.Zip.mapReduce(mapZip, reduceCustZip, {"out": {"reduce": "cust_Zip"}});
db.cust_Zip.find();


mapCZ = function() {
    var that = this;
    if ("cust_ids" in this.value) {
        this.value.cust_ids.forEach(function(value) {
            emit(value.cust_id, {
                Zip_id: that._id,
                Zip_cd: that.value.Zip_cd
            });
        });
    }
};

reduceCZ = function(k, values) {
    var result = {};
    values.forEach(function(value) {
        var field;
        for (field in value) {
            if (value.hasOwnProperty(field)) {
                result[field] = value[field];
            }
        }
    });
    return result;
};
db.cust_Zip_joined.drop();
db.cust_Zip.mapReduce(mapCZ, reduceCZ, {"out": "cust_Zip_joined"}); 
db.cust_Zip_joined.find().pretty();


var flattenMRCollection=function(dbName,collectionName) {
    var collection=db.getSiblingDB(dbName)[collectionName];

    var i=0;
    var bulk=collection.initializeUnorderedBulkOp();
    collection.find({ value: { $exists: true } }).addOption(16).forEach(function(result) {
        print((++i));
        //collection.update({_id: result._id},result.value);

        bulk.find({_id: result._id}).replaceOne(result.value);

        if(i%1000==0)
        {
            print("Executing bulk...");
            bulk.execute();
            bulk=collection.initializeUnorderedBulkOp();
        }
    });
    bulk.execute();
};


flattenMRCollection("mydb","cust_Zip_joined");
db.cust_Zip_joined.find().pretty();
0
Vipul Mehta

MongoDBで 'SQL UNION'の方法で共用体を実行することは、単一のクエリで、ルックアップと共に集約を使用して可能です。これが私がMongoDB 4.0で動作することをテストした例です:

// Create employees data for testing the union.
db.getCollection('employees').insert({ name: "John", type: "employee", department: "sales" });
db.getCollection('employees').insert({ name: "Martha", type: "employee", department: "accounting" });
db.getCollection('employees').insert({ name: "Amy", type: "employee", department: "warehouse" });
db.getCollection('employees').insert({ name: "Mike", type: "employee", department: "warehouse"  });

// Create freelancers data for testing the union.
db.getCollection('freelancers').insert({ name: "Stephany", type: "freelancer", department: "accounting" });
db.getCollection('freelancers').insert({ name: "Martin", type: "freelancer", department: "sales" });
db.getCollection('freelancers').insert({ name: "Doug", type: "freelancer", department: "warehouse"  });
db.getCollection('freelancers').insert({ name: "Brenda", type: "freelancer", department: "sales"  });

// Here we do a union of the employees and freelancers using a single aggregation query.
db.getCollection('freelancers').aggregate( // 1. Use any collection containing at least one document.
  [
    { $limit: 1 }, // 2. Keep only one document of the collection.
    { $project: { _id: '$$REMOVE' } }, // 3. Remove everything from the document.

    // 4. Lookup collections to union together.
    { $lookup: { from: 'employees', pipeline: [{ $match: { department: 'sales' } }], as: 'employees' } },
    { $lookup: { from: 'freelancers', pipeline: [{ $match: { department: 'sales' } }], as: 'freelancers' } },

    // 5. Union the collections together with a projection.
    { $project: { union: { $concatArrays: ["$employees", "$freelancers"] } } },

    // 6. Unwind and replace root so you end up with a result set.
    { $unwind: '$union' },
    { $replaceRoot: { newRoot: '$union' } }
  ]);

これがどのように機能するかの説明は次のとおりです。

  1. 少なくとも1つのドキュメントを含むデータベースのanyコレクションからaggregateをインスタンス化します。データベースのコレクションが空にならないことを保証できない場合は、データベースに単一の空のドキュメントを含む「ダミー」コレクションを作成することでこの問題を回避することができます。

  2. パイプラインの最初のステージを{ $limit: 1 }にします。これは最初のものを除くコレクションのすべての文書を削除します。

  3. $projectステージを使用して、残りの文書のすべてのフィールドを削除します。

    { $project: { _id: '$$REMOVE' } }
    
  4. あなたの集合は今、単一の、空の文書を含みます。結合したいコレクションごとにルックアップを追加します。特定のフィルタリングを行うにはpipelineフィールドを使用するか、コレクション全体を一致させるためにlocalFieldおよびforeignFieldをnullのままにすることができます。

    { $lookup: { from: 'collectionToUnion1', pipeline: [...], as: 'Collection1' } },
    { $lookup: { from: 'collectionToUnion2', pipeline: [...], as: 'Collection2' } },
    { $lookup: { from: 'collectionToUnion3', pipeline: [...], as: 'Collection3' } }
    
  5. これで、次のような3つの配列を含む単一の文書を含む集合体ができました。

    {
        Collection1: [...],
        Collection2: [...],
        Collection3: [...]
    }
    

    その後、$project集計演算子とともに$concatArraysステージを使用して、それらを1つの配列にマージすることができます。

    {
      "$project" :
      {
        "Union" : { $concatArrays: ["$Collection1", "$Collection2", "$Collection3"] }
      }
    }
    
  6. これで単一のドキュメントを含む集合体ができました。その中に、コレクションの和集合を含む配列が配置されています。やるべきことは、$unwind$replaceRootステージを追加して、配列を別々の文書に分割することです。

    { $unwind: "$Union" },
    { $replaceRoot: { newRoot: "$Union" } }
    
  7. Voilà。これで、結合したいコレクションを含む結果セットができました。さらにステージを追加してさらに絞り込み、並べ替え、skip()およびlimit()を適用することができます。あなたが望むほとんど何でも。

0
sboisse

はい、できます:私が今日書いたこの効用関数を取ります。

function shangMergeCol() {
  tcol= db.getCollection(arguments[0]);
  for (var i=1; i<arguments.length; i++){
    scol= db.getCollection(arguments[i]);
    scol.find().forEach(
        function (d) {
            tcol.insert(d);
        }
    )
  }
}

この関数にはコレクションをいくつでも渡すことができます。最初のコレクションがターゲットコレクションになります。残りのコレクションはすべて、ターゲットコレクションに転送されるソースです。

0
Shangab