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

Търсене с масив от обекти

По принцип трябва да $unwind първо масива. MongoDB все още не може да работи с "вътрешното" свойство на обект в масив като източник за $lookup .

Освен това за ефективност наистина трябва да използваме $concatArrays първо да се „присъедините“ към източника на масива и след това да направите само едно $lookup операция:

Project.aggregate([
  { "$match": { "project_id": projectId} },
  { "$project": {
    "project_id": 1,
    "updated_at": 1,
    "created_at": 1,
    "owner": 1,
    "name": 1,
    "combined": {
      "$concatArrays": [
        { "$map": {
          "input": {
            "$filter": {
              "input": "$uploaded_files",
              "as": "uf",
              "cond": { "$eq": ["$$uf.upload_id", uploadId ] }
            }
          },
          "as": "uf",
          "in": {
            "$arrayToObject": {
              "$concatArrays": [
                { "$objectToArray": "$$uf" },
                [{ "k": "type", "v": "uploaded_files" }]
              ]
            }
          }
        }},
        { "$map": {
          "input": {
            "$filter": {
              "input": "$file_history",
              "as": "fh",
              "cond": { "$eq": ["$$fh.upload_id", uploadId ] }
            }
          },
          "as": "fh",
          "in": {
            "$arrayToObject": {
              "$concatArrays": [
                { "$objectToArray": "$$fh" },
                [{ "k": "type", "v": "file_history" }]
              ]
            }
          }
        }}
      ]
    }
  }},
  { "$unwind": "$combined" },
  { "$lookup": {
    "from": "files",
    "localField": "combined.file",
    "foreignField": "_id",
    "as": "combined.file"
  }},
  { "$unwind": "$combined.file" },
  { "$lookup": {
    "from": "users",
    "localField": "owner",
    "foreignField": "_id",
    "as": "owner"
  }},
  { "$unwind": "$owner" },
  { "$group": {
    "_id": "$_id",
    "project_id": { "$first": "$project_id" },
    "updated_at": { "$first": "$updated_at" },
    "created_at": { "$first": "$created_at" },
    "owner": { "$first": "$owner" },
    "name": { "$first": "$name" },
    "combined": { "$push": "$combined" }
  }},
  { "$project": {
    "project_id": 1,
    "updated_at": 1,
    "created_at": 1,
    "owner": 1,
    "name": 1,
    "uploaded_files": {
      "$filter": {
        "input": "$combined",
        "as": "cf",
        "cond": { "$eq": [ "$$cf.type", "uploaded_files" ] }
      }    
    },
    "file_history": {
      "$filter": {
        "input": "$combined",
        "as": "cf",
        "cond": { "$eq": [ "$$cf.type", "file_history" ] }
      }    
    }
  }}
])

С две думи

  1. Съберете двата масива в източника и ги маркирайте, след което $unwind първо

  2. Направете $lookup върху комбинирания детайл и $unwind това

  3. Направете $lookup на другия чужд източник и $unwind това

  4. $group документа обратно заедно с единичен масив.

  5. $filter чрез полето „имена на тагове“ или „тип“, които добавихме, за да „разделим“ масивите.

Можете да следвате същия процес, просто като използвате $unwind на всеки масив, след което извършване на „съединяване“ и групиране обратно заедно. Но наистина това изисква много повече стъпки, отколкото просто „комбиниране“ на първо място.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB намира документи, където всички елементи на масива имат някаква стойност

  2. PyMongo - избиране на поддокументи от колекция чрез регулярен израз

  3. Как да преброим продуктовата група с име на поле в Monogodb?

  4. Django-Nonrel със списък на Mongodb

  5. Уникално ограничение с две полета в MongoDB