sql >> Databáze >  >> NoSQL >> MongoDB

Najděte dokument založený na odkazu na rodiče v dítěti

Ve skutečnosti je „nejlepší“ způsob, jak toho dosáhnout, spíše pomocí .aggregate() a $lookup "spojit" data a "filtrovat" podmínky zápasu. To je velmi efektivní, protože MongoDB to všechno ve skutečnosti provádí na „serveru“ samotném, ve srovnání s vydáváním „více“ dotazů jako .populate() ano.

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

Pokud existuje "spousta" hodnocení, pak je nejlepší použít $unwind , který vytvoří dokument pro každou související položku "žebříčku":

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

Je zde také speciální zpracování toho, jak MongoDB řeší „spojování“ dokumentů, aby nedošlo k překročení limitu 16 MB BSON. Takže ve skutečnosti se tato zvláštní věc stane, když $unwind přímo navazuje na $lookup fáze potrubí:

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

Takže $unwind ve skutečnosti „zmizí“ a místo toho je „srolován“ do $lookup jako by to byla „jedna“ operace. Tímto způsobem nevytváříme "pole" přímo v nadřazeném dokumentu, což by u mnoha "souvisejících" položek v extrémních případech způsobilo překročení velikosti 16 MB.

Pokud nemáte MongoDB, který podporuje $lookup ( MongoDB 3.2 minunum ), pak byste mohli použít "virtuální" s .populate() místo toho (vyžaduje minimálně Mongoose 4.5.0 ). Ale všimněte si, že to ve skutečnosti provádí "dva" dotazy na server:

Nejprve přidejte „virtuální“ do schématu:

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

Poté zadejte dotaz pomocí .populate() :

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



  1. Mangoose Promise s bluebird a strojopisem

  2. Jak mohu zadat dotaz na pole slovníků v MongoDB?

  3. Potřebujete JPA při používání MongoDB?

  4. Správa uživatelů v node js s expresní, mongodb jako serverová databáze