sql >> データベース >  >> NoSQL >> MongoDB

MongoDbPipelineAggregationの並べ替えサブサブドキュメント

    集約パイプラインの最初から間違いを犯しています

    $project: {
                "tasks" : 1
            }
    

    これにより、すべてのデータが失われます。したがって、まず最初に、それを予約する必要があります:

    $project: {
                 tasks: 1,
                 doc: {
                         title: "$title", 
                         order: "$order", 
                         description: "$description", 
                         status: "$status"
                      }
              }
    

    その後、 $ unwindを実行します ■質問の場合と同じように:

    {$unwind: "$tasks"}, {$unwind: "$tasks.subTasks"}
    

    次に、並べ替えを行います。複合キーを使用して並べ替えを行う必要があります。そうでない場合は、 tasks.subTasks.orderで並べ替えます。 tasks.orderで並べ替えるとすぐには保持されません 。だから:

    {$sort: {"tasks.order": -1, "tasks.subTasks.order": 1}}
    

    そして、難しい部分があります。 $ groupする必要があります 結果を元に戻します。最初のステップは$pushです。 subTasksに戻る 、しかしまず第一に、タスク属性を保持する必要があります:

    $project: {
                 doc: 1, 
                 task_id: "$tasks._id", 
                 tasks_doc: {
                               title: "$tasks.title", 
                               description: "$tasks.description", 
                               order: "$tasks.order", 
                               status: "$tasks.status"
                            }, 
                 subTasks: "$tasks.subTasks"
              }
    

    ... subTasksを収集します :

    $group: {
               _id: {
                       _id: "$_id", 
                       task_id: "$task_id", 
                       doc: "$doc", 
                       task_doc: "$tasks_doc"
                    }, 
               subTasks: {
                            $push: "$subTasks"
                         }
            }
    

    タスクについても同じです 。 $ groupの間に注意してください task_docも投影する必要があります 属性:

    $group: {
               _id: {
                       _id: "$_id._id", 
                       doc: "$_id.doc"
                    }, 
               tasks: {
                         $push: {
                                   _id: "$_id.task_id", 
                                   title: "$_id.task_doc.title", 
                                   description: "$_id.task_doc.description",
                                   order: "$_id.task_doc.order", 
                                   status: "$_id.task_doc.status" 
                                   subTasks: "$subTasks"
                                }
                      }
            }
    

    次に、ルートの docを投影し直します 属性:

    $project: {
                 _id: "$_id._id", 
                 title: "$_id.doc.title", 
                 description: "$_id.doc.description", 
                 order: "$_id.doc.order", 
                 status: "$_id.doc.status", 
                 tasks: 1
              }
    

    基本的にはそれだけです。これが完全な生の集計パイプラインであるため、目的の結果が得られるかどうかをテストして確認できます。

    [
     {$match: {_id: ObjectId("554a13d4b692088a38f01f3b")}}, 
     {$project: {tasks: 1, doc: {title: "$title", order: "$order", description: "$description", status: "$status"}}}, 
     {$unwind: "$tasks"}, 
     {$unwind: "$tasks.subTasks"}, 
     {$sort: {"tasks.order": -1, "tasks.subTasks.order": 1}}, 
     {$project: {doc: 1, task_id: "$tasks._id", tasks_doc: {title: "$tasks.title", description: "$tasks.description", order: "$tasks.order", status: "$tasks.status"}, subTasks: "$tasks.subTasks"}}, 
     {$group: {_id: {_id: "$_id", task_id: "$task_id", doc: "$doc", task_doc: "$tasks_doc"}, subTasks: {$push: "$subTasks"}}}, 
     {$group: {_id: {_id: "$_id._id", doc: "$_id.doc"}, tasks: {$push: {_id: "$_id.task_id", title: "$_id.task_doc.title", description: "$_id.task_doc.description", order: "$_id.task_doc.order", status: "$_id.task_doc.status", subTasks: "$subTasks"}}}}, 
     {$project: {_id: "$_id._id", title: "$_id.doc.title", description: "$_id.doc.description", order: "$_id.doc.order", status: "$_id.doc.status", tasks: 1}}
    ]
    

    更新

    配列フィールドが空であるか存在しない場合( null $ unwind そのフィールドでの操作は、空の結果を返します 。この状況の解決策は、最初に nullを設定することです。 /emptyフィールドをzeroに 値、例: "" 。この$projectを実行する必要があることに注意してください $ unwindの前の各配列のイオン 。

    この回答 をご覧ください $ ifNullの使用方法について オペレーター。 $ sizeもチェックしてください 演算子こちら 。

    この部分を処理した後、 $ groupする必要があります 結果をバックアップします。これは、<を使用して実現できます。 code> $ cond オペレーター ""と照合します 値




    1. すべてのMongoデータベースを反復処理します

    2. 起動時にMongoDBコンテナ用のDBを作成するにはどうすればよいですか?

    3. Mongodbconcatintおよびstring

    4. バッチでmongoDBレコードを検索する(mongoid ruby​​アダプターを使用)