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

Aggregate $lookup не връща оригиналния ред на масива

Това е "по дизайн" на $lookup изпълнение. Какво всъщност се случва "под капака" е MongoDB вътрешен преобразува аргументите в $lookup към новия изразителен форматирайте с помощта на $expr и $in . Дори във версиите преди това изразително Формата е внедрена, вътрешната механика за "масив от стойности" беше наистина почти същото.

Решението тук е да поддържате копие на оригиналния масив като препратка за пренареждане на „joined“ елементи:

collection.aggregate([
  {"$match": {"_id": ObjectId("5c781752176c512f180048e3") }},
  {"$lookup": {
    "from": "collection2",
    "let": { "classIds": "$Classes.ID" },
    "pipeline": [
      { "$match": {
        "$expr": { "$in": [ "$_id", "$$classIds" ] }
      }},
      { "$addFields": {
        "sort": {
          "$indexOfArray": [ "$$classIds", "$_id" ]
        }
      }},
      { "$sort": { "sort": 1 } },
      { "$addFields": { "sort": "$$REMOVE" }}
    ],
    "as": "results"
  }}
])

Или от наследения $lookup употреба:

collection.aggregate([
  {"$match": {"_id": ObjectId("5c781752176c512f180048e3") }},
  {"$lookup": {
    "from": "collection2",
    "localField": "Classes.ID",
    "foreignField": "_id",
    "as": "results"
  }},
  { "$unwind": "$results" },
  { "$addFields": {
    "sort": {
      "$indexOfArray": [ "$Classes.ID", "$results._id" ]
    }
  }},
  { "$sort": { "_id": 1, "sort": 1 } },
  { "$group": {
    "_id": "$_id",
    "Name": { "$first": "$Name" },
    "Classes": { "$first": "$Classes" },
    "results": { "$push": "$results" }
  }}
])

И двата варианта произвеждат еднакъв изход:

{
        "_id" : ObjectId("5c781752176c512f180048e3"),
        "Name" : "Pedro",
        "Classes" : [
                {
                        "ID" : ObjectId("5c7af2b2f6f6e47c9060d7ce")
                },
                {
                        "ID" : ObjectId("5c7af2bcf6f6e47c9060d7cf")
                },
                {
                        "ID" : ObjectId("5c7af2aaf6f6e47c9060d7cd")
                }
        ],
        "results" : [
                {
                        "_id" : ObjectId("5c7af2b2f6f6e47c9060d7ce"),
                        "variable1" : "B"
                },
                {
                        "_id" : ObjectId("5c7af2bcf6f6e47c9060d7cf"),
                        "variable1" : "C"
                },
                {
                        "_id" : ObjectId("5c7af2aaf6f6e47c9060d7cd"),
                        "variable1" : "A"
                }
        ]
}

Общата концепция е да се използва $indexOfArray в сравнение с _id стойност от "joined" съдържание, за да откриете, че е „индекс“ позиция в оригиналния изходен масив от "$Classes.ID" . Различният $lookup вариантите на синтаксис имат различни подходи към начина, по който осъществявате достъп до това копие и как основно реконструирате.

$sort разбира се задава реда на действителните документи, като в рамките на обработката на конвейера за изразителната форма или чрез откритите документи на $unwind . Където сте използвали $unwind тогава ще $group обратно към оригиналния формуляр на документа.

ЗАБЕЛЕЖКА :Примерите за използване тук зависят от MongoDB 3.4 за $indexOfArray поне и $$REMOVE подравнява се с MongoDB 3.6, както и изразителният $lookup .

Има и други подходи за пренареждане на масива за предишни издания, но те са демонстрирани по-подробно в поръчката за гаранция $in на клаузата на MongoDB. Реално минимумът, който в момента трябва да използвате като производствена версия на MongoDB, е версията 3.4.

Вижте Правила за поддръжка под MongoDB сървър за пълните подробности за поддържаните издания и крайни дати.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Намерете дали някой е имал рожден ден през следващите 30 дни с mongo

  2. MongoDB поле за преименуване на база данни в масива

  3. Вземете само определено поле в MongoDB с C#

  4. MongoDB актуализиране Много()

  5. Най-лесният начин да копирате/клонирате екземпляр на документ от мангуста?