問題描述
我的 Firestore 數據庫中有一系列任務,如下所示:
I have a collection of tasks on my Firestore database like this:
"tasks": {
v8NC4GovVOPe21fhwtp0 : {
id: "v8NC4GovVOPe21fhwtp0"
status: 0
dateFrom: 30 april 2019 at 00:00:00 UTC-3
dateTo: 05 may 2019 at 00:00:00 UTC-3
....
},
v7NC4GaxVOPe48ftstp1 : {
id:"v7NC4GaxVOPe48ftstp1"
status: 0
dateFrom: 29 april 2019 at 00:00:00 UTC-3
dateTo: 02 may 2019 at 00:00:00 UTC-3
....
}
}
文檔有一個 dateFrom
字段,表示用戶可以開始處理該任務的第一個日期和一個 dateTo
字段,表示用戶擁有的最后一天完成該任務.
The document has a dateFrom
field, which indicates the first date the user can start working on that task and an dateTo
field, which indicates the last day the user have to finish that task.
我試圖從 2019 年 4 月開始獲取所有任務,這意味著 dateFrom
或 dateTo
屬于本月/年的任務(在本例中,如果月份是 2019 年 4 月,它必須同時獲取這兩個任務).
I was trying to get all tasks from April 2019, which means the ones that either dateFrom
or dateTo
belongs to this month/year (in this example, if the month is April-2019, it must fetch both tasks).
在 Android 上,我得到了所選月份的第一個日期 (startDate
) 和所選月份的最后一個日期 (endDate
),我正在嘗試做某事喜歡:
On Android, I get the first date of the chosen month (startDate
) and te last date from the chosen month (endDate
) and I was trying to do something like:
val missionsCollection = FirebaseFirestore.getInstance()
.collection("/users").document(uid).collection("tasks")
.whereGreaterThanOrEqualTo("dateFrom", startDate).whereLessThanOrEqualTo("dateTo", endDate)
但我收到一條錯誤消息,提示 除 whereEqualTo() 之外的所有 where 過濾器都必須位于同一字段上.但是您在dateFrom"和dateTo"上有過濾器
.
But I get an error saying that All where filters other than whereEqualTo() must be on the same field. But you have filters on 'dateFrom' and 'dateTo'
.
我想了一些解決方法,但它們看起來都很糟糕,即使我找不到一個好的解決方案,我相信一定有一個.
I thought about some workarounds, but they all look bad and even though I could not find a nice solution, I'm sure there's gotta be one.
推薦答案
Firestore 允許鏈接多個where()"方法來創建更具體的查詢,但僅限于同一字段.正如您可能在官方文檔中看到的那樣 查詢限制:
Firestore allows to chain multiple "where()" methods to create more specific queries but only on the same field. As you can probably see in the official documentation regardin Query limitations:
Cloud Firestore 不支持以下類型的查詢:
Cloud Firestore does not support the following types of queries:
- 在不同字段上使用范圍過濾器進行查詢,如上一節所述.
因此禁止對不同字段進行范圍過濾.
So range filters on different fields are forbidden.
為了達到你想要的,你需要查詢你的數據庫兩次,一次是使用調用來過濾數據:
To achieve what you want, you need to query your database twice, once to fiter data using a call to:
.whereGreaterThanOrEqualTo("dateFrom", startDate)
第二次使用調用:
.whereLessThanOrEqualTo("dateTo", endDate)
但很遺憾,您不能在同一個查詢中使用它們.
But unfortunately you cannot use them in the same query.
當我們設計數據庫架構時,基本上我們會為查詢構建它.因此,除了上述解決方案(您可以過濾查詢中的一個字段以及客戶端代碼中的另一個字段)之外,還有另一種方法可以將兩個范圍的值組合到一個字段中某種方式可以讓您的用例使用單個字段.
When we are designing a database schema, basically we structure it for our queries. So beside the above solution in which you can filter on one field in the query, and on the other field in your client-side code, there is also another approach in which you can combine the values of the two range into a single field in some way that will allow your use-case with a single field.
到目前為止,我見過的最成功的例子之一是 Geohashes
中用于過濾緯度和經度的組合,正如 Frank van Puffelen 在以下視頻中所解釋的那樣:
One of the most successful examples I've seen so far is the combination used in Geohashes
to filter on latitude and longitude as explained by Frank van Puffelen in the following video:
- https://www.youtube.com/watch?v=mx1mMdHBi5Q
知道這兩種解決方案在工作量上的區別,我建議使用第一種.
Knowing the difference in effort between these two solutions, I'd recommend using the first one.
還有第三種解決方案,您應該將 3 月至 4 月的所有任務添加到一個集合中.然后您可以使用以下命令查詢這個新集合:
There is also a third solution, in which you should to add all tasks from Mar-Apr into a single collection. Then you could query this new collection with:
db.collection("tasks-aps-mar")
.whereGreaterThanOrEqualTo("day", 1)
.whereLessThanOrEqualTo("day", 30);
更通用的解決方案是將每個月的任務存儲在一個集合中,然后執行查詢以獲取與所需月份對應的所有任務.在您的用例中,您應該查詢數據庫以獲取每個集合 tasks-mar-2019
、tasks-apr-2019
、tasks- 之一中的文檔2019 年 5 月
等等.
Even a more general solution would be to store the tasks in a collection for each month, and then perform a query to get all the tasks that correspond with the desired month. In your use case, you should query your database to get the documents within one of each collection tasks-mar-2019
, tasks-apr-2019
, tasks-may-2019
and so on.
關于您的評論,使用數組對您毫無幫助,因為您不能使用范圍間隔.
Regarding your comment, using arrays won't help you at all since you cannot use range intervals.
這篇關于Firebase 日期范圍查詢以獲取具有 starDate 和 endDate 的文檔的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!