2017-07-31 4 views
0

私は、私の小規模なサイドプロジェクトでFirebaseを使用していて、ほぼ1年間愛用しています。しかし、単一orderByChild()の制限のために、複雑なクエリを必要とする大規模なプロジェクトには使用できませんでした。Firebase:複数のWHERE INクエリの構造化方法

マルチ句のシナリオでFirebaseを使用する方法を考えています。問い合わせの上

SELECT * 
FROM `masterEvents` 
WHERE causeId IN (1, 2, 3, 4, 5, 6, 7, 8) 
AND timeId IN (1, 2, 3, 4) 
AND localityID IN (1, 2, 3, 4, 5) 

:私たちはPHPで開発された1つの私のメインのプロジェクトでは、我々は以下のようにクエリを持っています。特定の地域で発生し、特定の時間ブロックで発生し、特定の原因でカバーされるイベントをフィルタリングします。

  • 市町村は約20
  • 時間は21

ソリューション1になります

  • 原因がなる数で40になります子供として全3フィルタキー

    { 
        "eventIndex": { 
         "ev1": { 
          "name": "Event 1", 
          "location": 2, 
          "cause": 3, 
          "time": 5, 
         }, 
         "ev2": { 
          "name": "Event 2", 
          "location": 5, 
          "cause": 2, 
          "time": 1, 
         }, 
         "ev3": { 
          "name": "Event 3", 
          "location": 26, 
          "cause": 12, 
          "time": 18, 
         } 
        } 
    } 
    
    forEach(location in selectedLocationArray) { 
        firebase.database().ref("eventIndex").orderByChild("location").equalTo(location).on("value", snap => { 
         // loop through all events and filter them based on selectedCauseArray and selectedTimeArray 
        }); 
    } 
    

    解決策2: 1フィルタk子供としてノード・パスのEYと2フィルタキー

    { 
        "eventIndex": { 
         "location1": { 
          "ev1": { 
           "name": "Event 1", 
           "cause": 2, 
           "time": 1, 
          }, 
          "ev2": { 
           "name": "Event 2", 
           "cause": 12, 
           "time": 18, 
          } 
         }, 
         "location2": { 
          "ev4": { 
           "name": "Event 4", 
           "cause": 2, 
           "time": 1, 
          } 
         }, 
         "location3": { 
          "ev8": { 
           "name": "Event 9", 
           "cause": 2, 
           "time": 1, 
          }, 
          "ev9": { 
           "name": "Event 9", 
           "cause": 12, 
           "time": 18, 
          } 
         } 
        } 
    } 
    
    forEach(location in selectedLocationArray) { 
        forEach(cause in selectedCauseArray) { 
         firebase.database().ref("eventIndex/location" + location).orderByChild("cause").equalTo(cause).on("value", snap => { 
          // loop through all events and filter them based on selectedTimeArray 
         }); 
        } 
    } 
    

    解決策3:ノード・パスで 2フィルタキーとその私ができる良い効率的なソリューションとなります上記の子供

    として1つのフィルタキー取る?ありがとう:-)

    PS:コードは、実際のコードではなくロジックのアイデアを与えるために疑似コードとして扱うことができます。

  • 答えて

    1

    データをフィルタリングするのに最も効果的な方法の1つは、複数のキーをグループ化または結合することです。

    たとえば、あなたの質問に記載されている上記の構造では、 "_idx_location_cause_time"という別のフィールドを追加します。これは、注文場所、原因、時刻の値の組み合わせです。

    ... 
    "ev1": { 
        "name": "Event 1", 
        "location": 2, 
        "cause": 3, 
        "time": 5, 
        "_idx_location_cause_time" : "2_3_5" 
    }, 
    ... 
    

    ここでorderByChildクエリを使用して結果をフィルタリングできます。これはこれは、あなたのデータを構造化し、それに応じてそれらをフィルタリングするためにこれを使用する方法の一般的な考えで、

    dbRef.orderByChild(_idx_location_cause_time).equalTo("2_3_5").once("value", ...);

    です。また、このテクニックをあなたの質問で言及したテクニックと組み合わせて、フィルタリングプロセスをさらに単純化することもできます。

    Firebase Rulesで.indexOnを使用してインデックスを作成し、クエリのパフォーマンスを向上させることも重要です。

    このヘルプが必要です。

    関連する問題