2016-06-21 165 views
4

我正在嘗試檢索僅在到達日期和機場匹配時才返回航班數據的數據。我似乎無法找出最佳解決方案。我只能提取機場或到達日期相同的數據,而不是兩者(只能使用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結尾的數據?

回答

7

實時數據庫不支持多個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) { 

    } 
}); 
+0

你是說這是https://github.com/davideast/Querybase不可能在android中?只想確認! –

+3

我希望firebase很快就會採用內置的方式來編寫多個where子句,而不是像這樣的工作。 –

0

考慮使用嵌套監聽器: 首先,您可以等於其中一個,將結果保存在變量中,並在嵌套偵聽器中調用equalTo秒,並檢查您的結果。

這樣你可以做And查詢。

+3

這是一個反模式爲了嵌套數據或者用實時數據庫創建嵌套的監聽器,我建議重新考慮數據結構以保持一次讀取的平坦結構。 –

+2

是的你是對的,謝謝。 –