2017-02-17 6 views
0

Вот массив, который я получил после долгой агрегации.MongoDB: как назначить имена индексов элементам массива в конвейере агрегации?

"stages": [ 
    [ 
     { 
      "id": "58a6678bc27c331884b60930", 
      "description": "Lorem ipsum dolor sit amet...", 
      "somevalue": 0, 
      "user": "589cf6511b94281f34617a13" 
     }, 
     { 
      "_id": "589cf6511b94281f34617a13", 
      "title": "Dr.", 
      "firstname": "Doe", 
      "lastname": "John" 
     } 
    ] 
    ] 

Как вы видите, теперь у меня есть куча массивов, вложенных друг в друга. Есть ли способ объединить два набора в массиве или дать им правильные имена индексов?

Возможное решение № 1 будет таким. Внутренний массив ушел, и наборы объединены.

"stages": [ 
     { 
      "id": "58a6678bc27c331884b60930", 
      "description": "Lorem ipsum dolor sit amet...", 
      "somevalue": 0, 
      "user": "589cf6511b94281f34617a13" 
      "_id": "589cf6511b94281f34617a13", 
      "title": "Dr.", 
      "firstname": "Doe", 
      "lastname": "John" 
     } 
    ] 

Возможное решение # 2: массив не пошел, но, по крайней мере, элементы теперь имеют имена индексов и не должны относиться к ним, как [0] и [1].

"stages": [ 
    [ 
     "stage": { 
      "id": "58a6678bc27c331884b60930", 
      "description": "Lorem ipsum dolor sit amet...", 
      "somevalue": 0, 
      "user": "589cf6511b94281f34617a13" 
     }, 

     "user": { 
      "_id": "589cf6511b94281f34617a13", 
      "title": "Dr.", 
      "firstname": "Doe", 
      "lastname": "John" 
     } 
    ] 
    ] 

Виртуальный печенье для тех, кто с раствором ...

Aggregation Код

db.collection('bugs').aggregate([{ 
       $match: new ObjectId() 
      }, { 
       $lookup: { 
        from: 'users', 
        localField: 'user', 
        foreignField: '_id', 
        as: 'userdata' 
       } 
      }, 

      { 
       $unwind: '$userdata' 
      }, 

      { 
       $sort: { 
        'stages.date': -1 
       } 
      }, 

      { 
       $unwind: '$stages' 
      }, { 
       $lookup: { 
        from: 'users', 
        localField: 'stages.user', 
        foreignField: '_id', 
        as: 'stages_users' 
       } 
      }, 

      { 
       $unwind: '$stages_users' 
      }, { 
       $unwind: '$stages' 
      }, 

      { 
       $group: { 
        '_id': '$_id', 
        'title': { 
         $first: '$title' 
        }, 
        'user': { 
         $first: '$user' 
        }, 
        'browser': { 
         $first: '$browser' 
        }, 
        'severity': { 
         $first: '$severity' 
        }, 
        'data': { 
         $first: '$data' 
        }, 
        'userdata': { 
         $first: '$userdata' 
        }, 
        'stages': { 
         $addToSet: { 
          $setUnion: [ 
           ['$stages_users'], 
           ['$stages'] 
          ] 
         } 
        } 
       } 
      }, 

      { 
       $project: { 

        '_id': 1, 
        'user': 1, 
        'title': 1, 
        'browser': 1, 
        'date': 1, 
        'severity': 1, 

        'userdata._id': 1, 
        'userdata.title': 1, 
        'userdata.firstname': 1, 
        'userdata.lastname': 1, 

        'stages._id': 1, 
        'stages.id': 1, 
        'stages.user': 1, 
        'stages.date': 1, 
        'stages.description': 1, 
        'stages.severity': 1, 
        'stages.previous_severity': 1, 
        'stages.files': 1, 

        'stages.title': 1, 
        'stages.firstname': 1, 
        'stages.lastname': 1 
       } 
      } 
     ], 
+0

Возможно ли разместить текст агрегирования? Может быть, проще добавить имена до окончательного вывода. – Veeram

+0

Да, но вы можете провести выходные, выяснив это ... http://pastebin.com/SNPuZWG0 Это простая система билета для модуля отчетности об ошибках. Отчет об ошибке содержит заголовок в коллекции с именем «ошибки», который содержит дату, заголовок и _id пользователя, который отправил его. Последующие действия называются этапами и хранятся в массиве с именем «этапы» для каждой записи «ошибок». На этапах также есть поля «пользователь», для человека, который разместил их, и агрегация должна искать этих пользователей и добавлять их в массив «этапов». –

ответ

1

Вы можете попробовать ниже агрегации.

Так что идея здесь заключается в объединении полей из stages и stage_users в stages_merge_users документ после $lookup в $project стадии.

Я добавил поле каждый из stages и stage_users для демонстрации.

Вы должны добавить все поля по одному из обоих документов, а заключительный этап - $group.

db.bugs.aggregate([{ 
    $lookup: { 
     from: 'users', 
     localField: 'user', 
     foreignField: '_id', 
     as: 'userdata' 
    } 
}, { 
    $unwind: '$stages' 
}, { 
    $lookup: { 
     from: 'users', 
     localField: 'stages.user', 
     foreignField: '_id', 
     as: 'stages_users' 
    } 
}, { 
    $unwind: '$stages_users' 
}, { 
    $project: { 
     '_id': 1, 
     'user': 1, 
     'title': 1, 
     'browser': 1, 
     'date': 1, 
     'severity': 1, 
     'userdata': 1, 
     "stages_merge_users.firstname": "$stages_users.firstname", 
     "stages_merge_users.user": "$stages.user" 
    } 
}, { 
    $group: { 
     '_id': '$_id', 
     'title': { 
      $first: '$title' 
     }, 
     'user': { 
      $first: '$user' 
     }, 
     'browser': { 
      $first: '$browser' 
     }, 
     'severity': { 
      $first: '$severity' 
     }, 
     'data': { 
      $first: '$data' 
     }, 
     'userdata': { 
      $first: '$userdata' 
     }, 
     'stages': { 
      $push: '$stages_merge_users' 

     } 
    } 
}]) 

Версия 3.4 Update

Вы можете заменить $project сцену $addFields. Эти этапы добавляют поля к существующим полям.

{$addFields: { "stages_merge_users.firstname":"$stages_users.firstname", "stages_merge_users.user_id":"$stages.user_id"}}, 
+0

О, так что я могу использовать $ project перед другими операциями! Это круто, я думал, что это конец. Однако все это выглядит намного сложнее, чем в SQL. Спасибо за решение. Я был бы признателен за решение 3.4. –

+0

Добро пожаловать. Добавлено обновление 3,4. Я имею в виду, что этап '$ lookup' и' $ group' по-прежнему остается таким же, как и sql. Остальное довольно стандартно. Вы можете использовать этапы агрегации в любом порядке. – Veeram