sql >> Database >  >> NoSQL >> MongoDB

Zoek een document op basis van een verwijzing naar de ouder in het kind

Eigenlijk is de "beste" manier om dit te doen eerder het gebruik van .aggregate() en $lookup om de gegevens "aan te sluiten" en te "filteren" op de wedstrijdvoorwaarden. Dit is zeer effectief omdat MongoDB dit allemaal op de "server" zelf uitvoert, in vergelijking met het uitgeven van "meerdere" queries als .populate() doet.

MovieModel.aggregate([
  { "$match": { "m_title": m_title } },
  { "$lookup": {
    "from": RankMovieModel.collection.name,
    "localField": "_id",
    "foreignField": "movie",
    "as": "rankings"
  }}
])

Als er "veel" ranglijsten zijn, kunt u het beste $unwind , die een document aanmaakt voor elk gerelateerd "ranglijst"-item:

MovieModel.aggregate([
  { "$match": { "m_title": m_title } },
  { "$lookup": {
    "from": RankMovieModel.collection.name,
    "localField": "_id",
    "foreignField": "movie",
    "as": "rankings"
  }},
  { "$unwind": "$rankings" }
])

Er is hier ook een speciale behandeling van hoe MongoDB omgaat met "samengevoegde" documenten om te voorkomen dat de BSON-limiet van 16 MB wordt overschreden. Dus in feite gebeurt dit speciale wanneer $unwind volgt direct een $lookup pijplijnfase:

    {
        "$lookup" : {
            "from" : "rankmovies",
            "as" : "rankings",
            "localField" : "_id",
            "foreignField" : "movie",
            "unwinding" : {
                "preserveNullAndEmptyArrays" : false
            }
        }
    }

Dus de $unwind eigenlijk "verdwijnt" en wordt in plaats daarvan "opgerold" in de $opzoeken zichzelf alsof dit "één" operatie was. Op die manier creëren we geen "array" rechtstreeks in het bovenliggende document, waardoor de grootte in extreme gevallen met veel "gerelateerde" items groter zou zijn dan 16 MB.

Als u geen MongoDB heeft die $lookup ( MongoDB 3.2 minimum ) dan zou je een "virtuele" kunnen gebruiken met .populate() in plaats daarvan (vereist Mongoose 4.5.0 minimum ). Maar merk op dat dit feitelijk "twee" uitvoert vragen naar de server:

Voeg eerst de "virtuele" toe aan het schema:

movieSchema.virtual("rankings",{
  "ref": "Movie",
  "localField": "_id",
  "foreignField": "movie"
});

Geef vervolgens de query op met .populate() :

MovieModel.find({ "m_title": m_title })
  .populate('rankings')
  .exec()



  1. Redis niet in staat om verbinding te maken in drukke belasting

  2. Zijn er voordelen aan het gebruik van een aangepaste _id voor documenten in MongoDB?

  3. Hoe u veel grote JSON-bestanden efficiënt rechtstreeks van S3 in MongoDB kunt importeren

  4. Publiceer abonneren met nodejs en redis(node_redis)