2017-10-24 13 views
0

毎日百貨店(男性、女性など)に保管する人数に数十億の文書がある
id_department:departmentの位置、area_type:部門の支店名(靴、ファッション、など)mongodb集合体の性能を向上させる

(_id:59e86325dc03580bdbf2347f  
date:20170906 
id_department:2640 
goinside_type:2 
area_type:1) 
(_id:59e86325dc03580bdbf2347f  
date:20170906 
id_department:2642 
goinside_type:3 
area_type:2) 

私は、クエリを書きたい人の数は、時間の範囲でarea_typeを訪れる返すことができ、ここでの問題はarea_typeが1000を超えることができ、すべてのarea_typeの条件は(異なる可能性がありますこの場合はarea_typeでグループを使用できません)。私のパイプラインは長くなり、パフォーマンスが低下します。

$pipeline = Array 
(
    [0] => Array 
     (
      [$match] => Array 
       (
        [id_station] => Array 
         (
          [$in] => Array 
           (
            [0] => 2640 
            [1] => 2642 
            [2] => 2644 
           ) 

         ) 
        [date] => Array 
         (
          [$gte] => 20170802 
          [$lte] => 20170930 
         ) 

       ) 

     ) 

    [1] => Array 
     (
      [$group] => Array 
       (
        [_id] => Array 
         (
          [id_station] => $id_station        
         ) 

        [total_entries - area1] => Array 
         (
          [$sum] => Array 
           (
            [$cond] => Array 
             (
              [0] => Array 
               (
                [$and] => Array 
                 ( 
                  [0] => Array 
                   (
                    [$eq] => Array 
                     (
                      [0] => $area_type 
                      [1] => 1 
                     ) 

                   ) 

                  [2] => Array 
                   (
                    [$gte] => Array 
                     (
                      [0] => $date 
                      [1] => 20170901 
                     ) 

                   ) 

                  [3] => Array 
                   (
                    [$lte] => Array 
                     (
                      [0] => $date 
                      [1] => 20170930 
                     ) 

                   ) 

                 ) 

               ) 

              [1] => 1 
              [2] => 0 
             ) 

           ) 

         ) 

        [total_entries - area1previous] => Array 
         (
          [$sum] => Array 
           (
            [$cond] => Array 
             (
              [0] => Array 
               (
                [$and] => Array 
                 (
                  [0] => Array 
                   (
                    [$eq] => Array 
                     (
                      [0] => $area_type 
                      [1] => 1 
                     ) 

                   ) 

                  [2] => Array 
                   (
                    [$gte] => Array 
                     (
                      [0] => $date 
                      [1] => 20170802 
                     ) 

                   ) 

                  [3] => Array 
                   (
                    [$lte] => Array 
                     (
                      [0] => $date 
                      [1] => 20170831 
                     ) 

                   ) 

                 ) 

               ) 
              [1] => 1 
              [2] => 0 
             ) 

           ) 

         ) 
         [total_entries - area2] => Array 
         (
          [$sum] => Array 
           (
            [$cond] => Array 
             (
              [0] => Array 
               (
                [$and] => Array 
                 ( 
                  [0] => Array 
                   (
                    [$eq] => Array 
                     (
                      [0] => $area_type 
                      [1] => 2 
                     ) 

                   )              

                  [2] => Array 
                   (
                    [$gte] => Array 
                     (
                      [0] => $date 
                      [1] => 20170901 
                     ) 

                   ) 

                  [3] => Array 
                   (
                    [$lte] => Array 
                     (
                      [0] => $date 
                      [1] => 20170930 
                     ) 

                   ) 

                 ) 

               ) 

              [1] => 1 
              [2] => 0 
             ) 

           ) 

         ) 

        [total_entries - area2previous] => Array 
         (
          [$sum] => Array 
           (
            [$cond] => Array 
             (
              [0] => Array 
               (
                [$and] => Array 
                 (
                  [0] => Array 
                   (
                    [$eq] => Array 
                     (
                      [0] => $area_type 
                      [1] => 2 
                     ) 

                   )               
                  [2] => Array 
                   (
                    [$gte] => Array 
                     (
                      [0] => $date 
                      [1] => 20170802 
                     ) 

                   ) 

                  [3] => Array 
                   (
                    [$lte] => Array 
                     (
                      [0] => $date 
                      [1] => 20170831 
                     ) 

                   ) 

                 ) 

               ) 
              [1] => 1 
              [2] => 0 
             ) 

           ) 

         ) 

       ) 

     ) 
) 
$cursor = $collection->aggregate($pipeline, ['allowDiskUse' => true]); 

これを解決する方法はありますか?

+0

あなたの 'id_department'はおそらく' id_station'と呼ばれるべきでしょうか? – dnickless

答えて

0

ここで最も重要なことは、dateid_department/id_station(私は同じと思われる)フィールドにインデックスを作成することです。

collection.createIndex({ 
    "id_department" : 1, 
    "date" : 1 
}) 

これはほんの数文書は、次のパイプラインステージ(S)のために処理するために残されるべき後に$match段階をスピードアップします。その結果、パフォーマンスを測定し、(例えば右既に行う実際のグループ化の前に暫定$projectまたは$group段階にrepeteated日付フィルタを抽出して)あなたは、クエリの最適化を試みることができます十分ではないことが証明されていたら

+0

素晴らしいです、それは良い仕事です。 – sontd

+0

私の間違いは間違ったインデックスを作成しています: "id_department、date"の代わりに "date、id_department" – sontd

関連する問題