MongoDB aggregiert Pipelines mit verknüpftem Objekt

Nov 21 2020

Ich verknüpfe zwei Objekte in einer Abfrage und verwende dafür die Aggregatfunktion. Einige Daten sind lokalisiert und ich verwende eine Lösung von hier , um Daten für das angegebene Gebietsschema abzurufen.

Ich habe Probleme, dasselbe mit Daten aus dem verknüpften Objekt (Räumen) zu tun. Listen Sie insbesondere die Daten für das angegebene Gebietsschema in den roomDetails auf.

Bitte schauen Sie sich den Mongo-Spielplatz an

Antworten

2 turivishal Nov 21 2020 at 14:09

Sie müssen nur in Ihrer zweiten $addFieldsStufe, die Sie filtern , einen Filter hinzufügen, roomTypesund der Rest der Stufen wäre derselbe. Markieren Sie einfach den neuen Code unten aus dem Startkommentar und dem Endkommentar.

Ich schlage diese Lösung in Ihrer implementierten Abfrage vor. Ich bin nicht sicher, ob dies der richtige Ansatz ist. Möglicherweise führt mehr dazu, dass die Abfrage ausgeführt wird.

  • $reduceUm die Schleife des roomDetails.descriptionArrays $ cond zu iterieren , um das lokale Ergebnis mit dem Wert roomDetails.titleabzugleichen, und den gleichen Prozess für das Array zurückzugeben, und diese 2 aktualisierten Felder mit dem aktuellen Objekt zusammenzuführen$mergeObjects
  {
    $addFields: { roomTypes: { $map: {
          input: "$roomTypes", in: { $mergeObjects: [
              "$$this",
              {

Start:

                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"
                            ]
                          }
                        }
                      }
                    }
                  ]
                },

~ Ende ~

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

Spielplatz


In der allgemeinen Option, die ich in Ihrer Referenzfrage beantwortet habe, können Sie die gleiche Funktion verwenden wie:

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

Ihre letzte Frage wäre:

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
    }
  }
]);