查询中的Firebase多个WHERE子句
我正在尝试检索仅在到达日期和机场匹配时才返回航班数据的数据。我似乎无法找出最佳解决方案。我只能提取机场或到达日期相同的数据,而不是两者(只能使用equalTo()一次)。这里是我当前的Java代码如下所示:查询中的Firebase多个WHERE子句
Firebase ref = mFirebaseRef.child(FirebaseReference.CHILD_FLIGHTS);
Query queryRef = ref.orderByChild("airport").equalTo(getAirport());
queryRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println(TAG + " datasnapshot is equal to " + dataSnapshot);
}
这里的数据本身:
{
"flight" : {
"1ddf3c02-1f2e-4eb7-93d8-3d8d4f9e3da2" : {
"airport" : "Gothenburg, Sweden - Landvetter (GOT)",
"arrivalDate" : "2016-06-21",
"arrivalTime" : "20:58",
"code" : "GOT",
"departureDate" : "2016-06-23",
"departureTime" : "20:58"
},
"c2c86e54-b4d0-4d83-934b-775a86f0a16c" : {
"airport" : "Gothenburg, Sweden - Landvetter (GOT)",
"arrivalDate" : "2016-06-21",
"arrivalTime" : "20:50",
"code" : "GOT",
"departureDate" : "2016-06-23",
"departureTime" : "20:50"
}
},
"users" : {
"1ddf3c02-1f2e-4eb7-93d8-3d8d4f9e3da2" : {
"age" : "25",
"createdTime" : "1466533088358",
"email" : "[email protected]",
"provider" : "password",
"sex" : "M",
"username" : "user2"
},
"c2c86e54-b4d0-4d83-934b-775a86f0a16c" : {
"age" : "25",
"createdTime" : "1466374588255",
"email" : "[email protected]",
"provider" : "password",
"sex" : "M",
"username" : "user1"
}
}
}
当前的Java代码将返回其仅具有相同的机场所有儿童。正如你所猜测的那样,当需要对客户端进行排序的数据量远大于上述测试数据时,这是不可行的。如何更好地过滤Firebase结尾的数据?
实时数据库不支持多个where子句,但您可以创建一个额外的密钥使其成为可能。
您的"flight"
列表中的“航班”可以有一个组合键"arrivalDate"
和"code"
。
"1ddf3c02-1f2e-4eb7-93d8-3d8d4f9e3da2" : {
"airport" : "Gothenburg, Sweden - Landvetter (GOT)",
"arrivalDate" : "2016-06-21",
"arrivalTime" : "20:58",
"arrivalDate_code": "2016-06-21_GOT", // combined key
"code" : "GOT",
"departureDate" : "2016-06-23",
"departureTime" : "20:58"
}
然后您可以查询该密钥。
Firebase ref = mFirebaseRef.child(FirebaseReference.CHILD_FLIGHTS);
Query queryRef = ref.orderByChild("arrivalDate_code").equalTo("2016-06-21_GOT");
queryRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
}
});
另一种选择是在数据结构中掀起了字段的键:
/ flights
/$code
/$flight_id
这意味着你的数据是这样的:
"flight" : {
"GOT": {
"1ddf3c02-1f2e-4eb7-93d8-3d8d4f9e3da2" : {
"airport" : "Gothenburg, Sweden - Landvetter (GOT)",
"arrivalDate" : "2016-06-21",
"arrivalTime" : "20:58",
"code" : "GOT",
"departureDate" : "2016-06-23",
"departureTime" : "20:58"
}
}
}
然后你可以制定一个像这样的查询:
Firebase ref = mFirebaseRef.child(FirebaseReference.CHILD_FLIGHTS);
Query queryRef = ref.child("GOT").orderByChild("arrivalTime").equalTo("2016-06-21_GOT");
queryRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
}
});
考虑使用嵌套监听器: 首先,您可以等于其中一个,将结果保存在变量中,并在嵌套侦听器中调用equalTo秒,并检查您的结果。
这样你可以做And
查询。
这是一个反模式为了嵌套数据或者用实时数据库创建嵌套的监听器,我建议重新考虑数据结构以保持一次读取的平坦结构。 –
是的你是对的,谢谢。 –
你是说这是https://github.com/davideast/Querybase不可能在android中?只想确认! –
我希望firebase很快就会采用内置的方式来编写多个where子句,而不是像这样的工作。 –