MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Намерете документ въз основа на препратка към родителя в детето

Всъщност „най-добрият“ начин да направите това е по-скоро да използвате .aggregate() и $lookup за „обединяване“ на данните и „филтриране“ по условията на съвпадение. Това е много ефективно, тъй като MongoDB всъщност изпълнява всичко това на самия "сървър", в сравнение с издаването на "множество" заявки като .populate() прави.

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

Ако има „много“ класации, най-добре е да използвате $unwind , което ще създаде документ за всеки свързан елемент с „класиране“:

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

Тук също има специална обработка на начина, по който MongoDB се справя с „съединяването“ на документи, за да се избегне нарушаване на ограничението от 16MB BSON. Така че всъщност това специално нещо се случва, когато $unwind директно следва $lookup етап на тръбопровод:

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

Така че $unwind всъщност „изчезва“ и вместо това е „навит“ в $lookup като че ли това е "една" операция. По този начин ние не създаваме "масив" директно в родителския документ, което би довело до надвишаване на размера от 16 MB в крайни случаи с много "свързани" елементи.

Ако нямате MongoDB, която поддържа $lookup ( MongoDB 3.2 мин. ), тогава можете да използвате „виртуален“ с .populate() вместо това (изисква минимум Mongoose 4.5.0 ). Но имайте предвид, че това всъщност изпълнява "две" заявки към сървъра:

Първо добавете „виртуалния“ към схемата:

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

След това подайте заявката с .populate() :

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



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. mongodb заявка срещу mysql

  2. MongoDB - Експортиране на данни

  3. Mongo Дава „грешка с дублиран ключ“ в неуникални полета

  4. Как мога да получа всички идентификатори на документи в MongoDB?

  5. Mongoose findbyid() връща нула