查询中的Firebase多个WHERE子句

时间:2016-06-21 19:12:15

标签: java android firebase

我正在尝试检索仅在到达日期和机场匹配时返回航班数据的数据。我似乎无法找到最佳解决方案。我只能在机场或抵达日期相同的情况下提取数据,而不是两者(只能使用equalTo()一次)。这是我当前的Java代码:

                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" : "test2@test.com",
  "provider" : "password",
  "sex" : "M",
  "username" : "user2"
},
"c2c86e54-b4d0-4d83-934b-775a86f0a16c" : {
  "age" : "25",
  "createdTime" : "1466374588255",
  "email" : "test1@test.com",
  "provider" : "password",
  "sex" : "M",
  "username" : "user1"
}
}
}

当前的Java代码将返回拥有相同机场的所有子代。正如您所猜测的那样,当需要对客户端进行排序的数据量远大于上述测试数据时,这是不可行的。我怎样才能更好地过滤firebase上的数据呢?

2 个答案:

答案 0 :(得分:8)

实时数据库不支持多个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) {

   }
});

答案 1 :(得分:0)

考虑使用嵌套的侦听器: 首先,您可以等于其中一个,将结果保存在变量中,并在嵌套侦听器中调用equalTo,然后检查结果。

这样您就可以进行And查询。