web-dev-qa-db-ja.com

Mongo $ lookupが左外部結合である場合、一致しないドキュメントが除外されるのはなぜですか?

タイトルはそれをすべて言います。ドキュメントが一致フィールドに従って一致する外部ドキュメントにならない場合、どうしてパイプラインの結果セットに含まれないのですか?

私はMongo 3.2で新しいアグリゲーターをテストしています。私は、最初に巻き戻し、次にドキュメントをグループ化して、ネストされた配列ルックアップを実行するところまで行きました。私が残したのは、$lookup基準を満たしていないすべてのローカルドキュメントを結果に含めることだけです。これは、「左外部結合」の標準的な定義であると私が考えたものです。

これがクエリです:

db.users.aggregate([
    {
        $unwind: "$profile",
        $unwind: "$profile.universities"
    },
    {
        $lookup: {
            from: "universities",
            localField: "profile.universities._id",
            foreignField: "_id",
            as: "profile.universities"
        }
    },
    {
        $group: {
            _id: "$_id",
            universities: {
                $addToSet: "$profile.universities"
            }
        }
    }
]).pretty()

したがって、空のprofile.universities配列を持つuserがある場合、一致を返す$lookupに関係なく、それを結果セットに含める必要がありますが、そうではありません。これをどのように行うことができますか、そしてMongoがこのように動作するように$lookupを構築した理由は何ですか?

13
Sun Lee

この動作は$lookupとは関係ありません。 $unwind のデフォルトの動作は、参照されたフィールドが欠落しているドキュメントや空の配列であるドキュメントを省略するためです。

profile.universitiesが空の配列であっても巻き戻されたドキュメントを保持するには、そのpreserveNullAndEmptyArraysオプションをtrueに設定します。

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",
            universities: {
                $addToSet: "$profile.universities"
            }
        }
    }
]).pretty()
30
JohnnyHK