web-dev-qa-db-fra.com

Si la recherche Mongo $ est une jointure externe gauche, alors pourquoi exclut-elle les documents non correspondants?

Le titre dit tout. Comment se fait-il qu'un document n'aboutisse à aucun document externe correspondant en fonction de son champ de correspondance, alors comment se fait-il qu'il ne soit pas inclus dans l'ensemble de résultats du pipeline?

Je teste les nouveaux agrégateurs dans Mongo 3.2 et je suis allé jusqu'à effectuer une recherche de tableaux imbriqués en déroulant d'abord, puis en regroupant les documents. Tout ce qu'il me reste à faire est que les résultats incluent tous les documents locaux qui ne répondent pas aux critères $lookup, Ce que je pensais être la définition standard de "jointure externe gauche".

Voici la requête:

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()

Donc, si j'ai un user qui a un tableau profile.universities Vide, alors j'ai besoin qu'il soit inclus dans le jeu de résultats indépendamment du fait que $lookup Renvoie des correspondances, mais il ne le fait pas ne pas. Comment puis-je faire cela et quelle est la raison pour laquelle Mongo a construit $lookup Pour fonctionner de cette façon?

13
Sun Lee

Ce comportement n'est pas lié à $lookup, c'est parce que le comportement par défaut de $unwind consiste à omettre les documents dans lesquels le champ référencé est manquant ou un tableau vide.

Pour conserver les documents déroulés même lorsque profile.universities est un tableau vide, vous pouvez définir son option preserveNullAndEmptyArrays sur 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