2017-02-17 5 views
0

ここで私は長い集計の後に得た配列です。MongoDB:集約パイプラインの配列の要素にインデックス名を割り当てる方法は?

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

ここでわかるように、私はお互いにネストされた配列のヒープを持っています。配列内の2つのセットを統一するか、適切なインデックス名を与える方法はありますか?

可能な解決策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" 
     } 
    ] 
    ] 

溶液で誰にも仮想クッキー...

集約コード

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を含むヘッダーが "bugs"という名前で付けられています。フォローアップはステージと呼ばれ、「バグ」のすべてのレコードについて「ステージ」という配列に格納されます。ステージには、それらを掲示した人のための「ユーザー」フィールドもあり、集計はこれらのユーザーを検索し、それらを「ステージ」配列に追加することになっています。 –

答えて

1

あなたは集計の下に試すことができます。

ので、ここでの考え方は$project段階で$lookupstages_merge_users文書にstagesstage_usersからフィールドをマージすることです。

デモ用にフィールドをそれぞれstagesstage_usersから追加しました。

文書の両方からすべてのフィールドを1つずつ追加する必要があります。最後のステージは$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アップデート

あなたは$addFields$projectステージに置き換えることができます。この段階では、既存のフィールドにフィールドを追加します。

{$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

関連する問題