MongoDBの集計は、分単位で指数関数的に複雑になります。
ネストされた配列を$unwind
して、巻き戻されたネストされた配列からの各オブジェクトの$lookup
によって_id
を実行します。私の最後の試みは$group
で巻き戻しを元に戻すことです。ただし、元の埋め込み配列を、元のプロパティ名とともに、各ドキュメントの残りの元の直接プロパティとともに再構築することはできません。
これまでの私の試みは次のとおりです。
db.users.aggregate([
{
$unwind: "$profile",
$unwind: {
path: "$profile.universities",
preserveNullAndEmptyArrays: true
}
},
{
$lookup: {
from: "universities",
localField: "profile.universities._id",
foreignField: "_id",
as: "profile.universities"
}
},
{
$group: {
_id: "$_id",
emails: { "$first": "$emails" },
profile: { "$first": "$profile" },
universities: { "$Push": "$profile.universities" }
}
}
]).pretty()
私が得るものはこのようなものです:
{
"_id" : "A_USER_ID",
"emails" : [
{
"address" : "AN_EMAIL_ADDRESS",
"verified" : false
}
],
"profile" : {
"name" : "NAME",
"company" : "A COMPANY",
"title" : "A TITLE",
"phone" : "123-123-1234",
"disabled" : false,
"universities" : [
{
"_id" : "ID_1",
"name" : "UNIVERSITY_NAME_1",
"code" : "CODE_1",
"styles" : {AN_OBJECT}
}
]
},
"universities" : [
[
{
"_id" : "ID_1",
"name" : "UNIVERSITY_NAME_1",
"code" : "CODE_1",
"styles" : {AN_OBJECT}
}
],
[
{
"_id" : "ID_2",
"name" : "UNIVERSITY_NAME_2",
"code" : "CODE_2",
"styles" : {AN_OBJECT}
}
]
]
}
この結果には2つの問題があります。
universities
は、$lookup
が元の$profile.universities
ネスト配列の単一要素配列を返したため、それぞれ1つのオブジェクトの配列の配列です。それはオブジェクトの配列でなければなりません。universities
は、profiles
の下にネストされた元の場所になります。 profile.universities
演算子を使用しているので、元の$first
がそのままの理由を知っています。これの背後にある私の意図は、元のネストされたprofile
配列を保持しながら、universities
の元のプロパティをすべて保持することです。最終的に、私が必要なのは次のようなものです:
{
"_id" : "A_USER_ID",
"emails" : [
{
"address" : "AN_EMAIL_ADDRESS",
"verified" : false
}
],
"profile" : {
"name" : "NAME",
"company" : "A COMPANY",
"title" : "A TITLE",
"phone" : "123-123-1234",
"disabled" : false,
"universities" : [
{
"_id" : "ID_1",
"name" : "UNIVERSITY_NAME_1",
"code" : "CODE_1",
"styles" : {AN_OBJECT}
},
{
"_id" : "ID_2",
"name" : "UNIVERSITY_NAME_2",
"code" : "CODE_2",
"styles" : {AN_OBJECT}
}
]
}
}
これを達成するために$group
の代わりに使用できる別の演算子はありますか?または、$group
の目的を誤って理解していますか?
編集:これはコンテキストの元の投稿です: Mongo $ lookupが左外部結合である場合、どのようにして非一致するドキュメント?
$lookup
演算子は配列フィールドを生成するため、を実行する必要があります $unwind
$group
パイプラインの前の新しいフィールド望ましい結果を得るには:
db.users.aggregate([
{ "$unwind": "$profile" },
{ "$unwind": {
"path": "$profile.universities",
"preserveNullAndEmptyArrays": true
} },
{ "$lookup": {
"from": "universities",
"localField": "profile.universities._id",
"foreignField": "_id",
"as": "universities"
} },
{ "$unwind": "$universities" },
{ "$group": {
"_id": "$_id",
"emails": { "$first": "$emails" },
"profile": { "$first": "$profile" },
"universities": { "$Push": "$universities" }
} },
{ "$project": {
"emails": 1,
"profile.name" : 1,
"profile.company": 1,
"profile.title" : 1,
"profile.phone" : 1,
"profile.disabled": 1,
"profile.universities": "$universities"
} }
]).pretty()