Firebase:如何为多个WHERE IN查询构造

时间:2017-07-31 14:59:46

标签: firebase web firebase-realtime-database

我在我的小型项目中使用Firebase将近一年,并且非常喜欢它。但由于单个orderByChild()限制,无法将其用于需要复杂查询的大型项目。

仍在考虑如何在多个where子句场景中使用Firebase。在我用PHP开发的一个主要项目中,我们有一个查询如下:

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)

以上查询。过滤在某些地区发生的事件,发生在特定时间段内,并在特定原因下进行覆盖。

  • 地方数量可以是40个
  • 原因将在20左右
  • 时间将是21

解决方案1:所有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节点路径中的过滤键和作为子项的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 个答案:

答案 0 :(得分: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规则中的.indexOn对其进行索引以提高查询效果也很重要。

希望这有帮助!