【问题标题】:Firebase multiple WHERE clause in query [duplicate]查询中的Firebase多个WHERE子句[重复]
【发布时间】:2016-10-23 11:50:18
【问题描述】:

我正在尝试检索仅在到达日期和机场匹配时才返回航班数据的数据。我似乎无法找出最好的解决方案。我只能提取机场或到达日期相同的数据,而不是两者(只能使用一次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 端的数据?

【问题讨论】:

    标签: java android firebase


    【解决方案1】:

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

    这样就可以进行And查询。

    【讨论】:

    • 嵌套数据或使用实时数据库创建嵌套侦听器是一种反模式,我建议重新考虑数据结构以保持单次读取的扁平结构。
    • 是的,你是对的,谢谢。
    【解决方案2】:

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

    【讨论】:

    • 你的意思是github.com/davideast/Querybase在android中是不可能的?只是想确认!
    • 我希望 firebase 很快就会采用一种内置方式来编写多个 where 子句,而不是像这样的解决方法。
    • 'addChildEventListener()' 怎么样?
    猜你喜欢
    • 2021-08-06
    相关资源
    最近更新 更多