【问题标题】:whereArrayContains limit to 10whereArrayContains 限制为 10
【发布时间】:2020-04-26 17:51:17
【问题描述】:

我想根据 tagIDs 过滤 questionCollection 。一切正常,但 whereArraycontains 最多可用于 10 个 id。

我如何改进我的结构,使其能够为超过 10 个tagIDs 工作,同时确保调用尽可能少地访问服务器以减少开支

Firestore-root
   |
   --- questions (collection)
   |     |
   |     --- qid (documents)
   |          |
   |          --- title: "Question Title"
   |          |
   |          --- qid: "autogeneratedID"
   |          |
   |          --- tagIDs =[tagID_1,tagID_2...tag_IDs_5] // array
   |
   --- tags (collection)
   |     |
   |     --- tagID (documents)
   |          |
   |          --- tagName: "Mathematics"
   |          |
   |          --- tagID: "autogeneratedID"
   |

获取包含特定 tagID 的问题(如果 tagID 大于 10 则失败

private fun fetchQuestion(tagMap: HashMap<String, String>) {

        val tagIDList:MutableList<String> = ArrayList();
        for ((key) in tagMap) { 
            tagIDList.add(key);
        }
        var query: Query = db.collection(Constants.QUESTION_COLLECTION)
                .orderBy(Constants.KEY_QUESTION_ID, Query.Direction.DESCENDING).limit(50)
        if(!tagIDList.isNullOrEmpty())
            query = query.whereArrayContainsAny("tagIDs", tagIDList);//if list greater than 10 it's not working

        query.get().addOnSuccessListener { queryDocumentSnapshots ->
                if(!queryDocumentSnapshots.isEmpty){
                    for (documentSnapshot in queryDocumentSnapshots) {
                        val question = documentSnapshot.toObject(QuestionBO::class.java)
                    }
                }
            }.addOnFailureListener { e ->
                toast("No record found.")
                e.printStackTrace()
            }
    }

【问题讨论】:

  • 也许您应该重新考虑构建数据的方式。也许您应该有一个单独的集合,而不是拥有一个 tagID 数组,而该集合对于给定的 ID 返回一个 tagID 文档并从那里继续。
  • 您找到解决问题的方法了吗?我有同样的问题。

标签: android firebase kotlin google-cloud-firestore


【解决方案1】:

documentation for whereArrayContains 查询非常具体。它只能处理 10 个数组项:

使用 array-contains-any 运算符将同一字段上的最多 10 个 array-contains 子句与逻辑 OR 组合起来

您应该知道 whereArrayContains 不会减少计费文档的读取次数。如果您的数组包含 10 个项目,则仍将花费 10 次文档读取。如果您执行 10 个 whereArrayContains 查询,每个查询有 10 个数组项,它仍将花费 100 次读取。

如果你需要 N 个文档,没有捷径可以让这 N 个文档的读取成本低于 N 个文档读取的成本。

【讨论】:

  • Doug Stevenson,你能推荐一个更好的结构来获取超过 10 个 tagID。
  • 不,我不能。您将不得不多次查询。
  • @DougStevenson 如果我有 100 个图像 URL 作为 ArrayList 并且如果我想 get() 这 100 个 URL,它只算作一个文档读取对吗?
  • @DougStevenson 假设我现在在一个文档中有一个包含 5 个项目的数组,如果我使用 whereArrayContainsAny 查询该文档,它会计算 5 个读取计数吗?
  • @Arup 是的,您可以为 .where 的集合保存字符串数组,当:没有代词,在集合中重复,我想将其保存为 Array.length 的对象或子文档> 10
猜你喜欢
  • 1970-01-01
  • 2021-04-05
  • 2023-03-18
  • 2014-03-27
  • 2019-04-26
  • 2017-05-07
  • 2012-08-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多