我学会了如何使用 pagination来 self 之前的一个问题,我已经在我的海事术语字典应用程序中实现了它。数据库中有很多术语。
数据库是这样的:
maritime_terms
|- id
|- term: "broad reach"
|- details: "Sailing with the wind abaft the beam."
|- etc
在我使用的文档中:
db.collection("maritime_terms")
.startAt(searchText)
.endAt(searchText+ "\uf8ff")
.limit(20);
例如,当我开始搜索“broad reach”并输入第一个字母 b
时,我得到了 20 个结果。当我输入第二个字母时,我得到了其他 20 个结果。等等。问题是,对于我键入的每个字母,我都会得到 20 次阅读,因此对于简单的搜索,我会从最少 100 次阅读到 150 次甚至更多。
到目前为止,我的应用程序运行良好,但我认为它对于一个简单的字典应用程序来说太贵了。如何减少如此庞大的读取次数?
最佳答案
虽然 Fogmeister 的回答可以帮助您显着减少读取次数,但我会尝试为您提供另一种方法,但这将意味着您的数据库结构发生了变化。所以这就是我要做的。
首先,我将停止搜索 maritime_terms
以您的方式收集。取而代之的是,我将创建一个文档来保存您在数据库中拥有的所有术语。每个术语都将添加到术语数组中。根据条款的长度,可以将所有条款放在一个文档中。我这么说是因为文件有限制。因此,对于可以放入文档的数据量存在一些限制。根据有关 usage and limits 的官方文档:
Maximum size for a document: 1 MiB (1,048,576 bytes)
如您所见,单个文档中的数据总量不得超过 1 MiB。当我们谈论存储文本时,您可以存储很多内容。
如果所有术语无法放在一个文档中,那么您可以简单地为字母表中的每个字母创建一个文档。由于您知道搜索的内容,因此很容易知道要阅读的文档。因此,请查看以下架构:
Firestore-root
|
--- alphabetTerms (collection)
|
--- a (document)
| |
| --- aTerms: ["A-Term", "A-Term", "A-Term"]
|
--- b (document)
|
--- bTerms: ["B-Term", "B-Term", "B-Term"]
获取a
文档,只需获取引用并制作 get()
调用:
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
DocumentReference aRef = rootRef.collection("alphabetTerms").document("a");
aRef.get().addOnCompleteListener(/* ... */);
即使 aTerms
是一个数组,当你制作一个 get()
打电话,你会得到一个 List<String>
并且不是作为一个数组。然后您可以使用以下命令简单地搜索该字符串列表:
termFromTheList.contains(searchedTerm);
需要注意的是,所有术语都必须是唯一的才能使用此解决方案。
此解决方案比您现在使用的解决方案好得多,因为它允许您搜索子字符串。例如,如果您想在 broad reach
中搜索对于 reach
,这是不可能的,除非您使用第三方服务,如 Algolia .
找到匹配项后,获取它并创建一个新查询:
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference maritimeTermsRef = rootRef.collection("maritime_terms");
Query searchQuery = maritimeTermsRef.whereEqualTo("term", searchedTerm);
searchQuery.get().addOnCompleteListener(/* ... */);
使用上面的解决方案,您将最终只读取一个文档来查找文档中的术语,并读取一个文档来显示术语的详细信息。
So you'll reduce the number of reads from
150to only 2.
关于java - 如何减少 Firestore 集合中的读取次数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57888824/