Pipelines d'agrégation MongoDB avec objet lié

Nov 21 2020

Je lie deux objets dans une requête et j'utilise la fonction d'agrégation pour cela. Certaines données sont localisées et j'utilise une solution d' ici pour obtenir des données pour les paramètres régionaux spécifiés.

J'ai du mal à faire de même avec les données de l'objet lié (salles). Plus précisément, répertoriez les données pour des paramètres régionaux donnés dans roomDetails.

Veuillez jeter un œil à l' aire de jeux Mongo

Réponses

2 turivishal Nov 21 2020 at 14:09

Il vous suffit d'ajouter un filtre dans votre deuxième $addFieldsétape que vous filtrez roomTypeset le reste des étapes serait le même, il suffit de mettre en évidence le nouveau code ci-dessous à partir du commentaire de début et du commentaire de fin,

Je suggère cette solution dans votre requête implémentée, je ne suis pas sûr que ce soit la bonne approche pour ce faire, cela pourrait entraîner la performance de la requête.

  • $reducepour itérer la boucle du roomDetails.descriptiontableau $ cond pour faire correspondre local et renvoyer le résultat de la correspondance à la valeur, même processus pour le roomDetails.titletableau, et fusionner ces 2 champs mis à jour avec l'objet actuel en utilisant$mergeObjects
  {
    $addFields: { roomTypes: { $map: {
          input: "$roomTypes", in: { $mergeObjects: [
              "$$this",
              {

Début:

                roomDetails: {
                  $mergeObjects: [
                    "$$this.roomDetails", { description: { $reduce: {
                          input: "$$this.roomDetails.description", initialValue: "", in: { $cond: [
                              { $eq: ["$$this.locale", "pl"] },
                              "$$this.value", "$$value"
                            ]
                          }
                        }
                      },
                      title: {
                        $reduce: { input: "$$this.roomDetails.title",
                          initialValue: "",
                          in: {
                            $cond: [ { $eq: ["$$this.locale", "pl"] }, "$$this.value",
                              "$$value"
                            ]
                          }
                        }
                      }
                    }
                  ]
                },

~ Fin ~

                available: {
                  $reduce: {
                    input: "$$this.capacity", initialValue: 0, in: { $cond: [
                        { $eq: ["$$this.cruiseID", "$cruiseID"] }, "$$this.available",
                        "$$value"
                      ]
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  }

Terrain de jeux


Dans l'option générique, j'ai répondu à votre question de référence, vous pouvez utiliser la même fonction comme,

function languageFilter(inputField, locale) {
  return {
    $reduce: {
      input: inputField,
      initialValue: "",
      in: {
        $cond: [{ $eq: ["$$this.locale", locale] }, "$$this.value", "$$value"]
      }
    }
  };
}

Votre dernière question serait:

let locale = "pl";
db.cs.aggregate([
  { $match: { cID: "00001" } },
  {
    $lookup: { from: "rooms", localField: "roomTypes.roomID", foreignField: "roomID", as: "roomTypes" } }, { $addFields: {
      title: languageFilter("$title", locale), description: languageFilter("$description", locale),
      roomTypes: {
        $map: { input: "$roomTypes",
          in: {
            $mergeObjects: [ "$$this",
              {
                roomDetails: {
                  $mergeObjects: [ "$$this.roomDetails",
                    {
                      description: languageFilter("$$this.roomDetails.description", locale), title: languageFilter("$$this.roomDetails.title", locale)
                    }
                  ]
                },
                available: {
                  $reduce: { input: "$$this.capacity",
                    initialValue: 0,
                    in: {
                      $cond: [ { $eq: ["$$this.cruiseID", "$cruiseID"] },
                        "$$this.available", "$$value"
                      ]
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  },
  {
    $project: {
      _id: 0,
      "roomTypes": { _id: 0 },
      "roomTypes.capacity": 0
    }
  }
]);