有没有更好的方法来优化此Firestore查询?

时间:2019-06-10 22:24:58

标签: swift firebase google-cloud-firestore

现在,我根据另一个字符串数组查询Firestore数组。效果很好,但我想知道这是否正确,以及是否有一种对其进行优化以使其更快的方法。

这是我的代码。

var exampleArray = [test]()

func loadData(textArray : [String]){
        let db = Firestore.firestore()

        for i in 0..<textArray.count{
            db.collection("testCollection").whereField("testField", arrayContains: textArray[i]).getDocuments{ (querySnapshot, err) in
                if let err = err {
                    print("\(err.localizedDescription)")
                    print("Test Error")
                } else {
                    if (querySnapshot!.isEmpty == false){
                        let res = querySnapshot!.documents.compactMap({test(dictionary: $0.data())})
                        self.exampleArray.append(contentsOf: res)
                        self.summaryTableView.reloadData()
                        SVProgressHUD.dismiss()
                        print(self.textArray[i])

                    }
                }
            }
        }
    }

谢谢。

更新:

一些信息:

  • 目前,VisionCloudRecognition流程和查询大约需要10到11秒。识别7秒,查询3-4。
  • 该数据库有7700个文档,每个文档有7个字段。

基本上我的应用程序执行以下操作:

  • 用户拍张照片
  • 使用OCR,图像变成文本,然后将文本附加在字符串数组中。我们不知道会有多少个字符串。也许是0或50。
  • 然后我根据字符串数组查询Firestore数组。

1 个答案:

答案 0 :(得分:3)

正如评论中指出的那样,您正在循环中运行一堆异步请求(这总是很糟糕),并且在每个数据解析时都会重新加载数据,导致tableView继续使用新的重新绘制数据。

您要做的是将所有这些数据库请求添加到DispatchGroup中。当它们解析时,将数据添加到您的阵列中。完成所有操作后,执行一个tableView.reloadData(),然后关闭您的SVProgressHud

这不仅可以加快速度,因为可以并行发生多个调用,而且当添加新数据并且tableView在快速启动中重新加载X次时,用户的表行将不会跳动。 / p>

编辑:您要求一个示例-这是非常快速的示例,写在SO上,因此请寻找XCode来通知您任何错别字或错误。

class MyVC: UIViewController {

  var exampleArray = [test]()
  let db = Firestore.firestore()
  let dispatchGroup = DispatchGroup()

  override func viewDidLoad(animated: bool) {
    super.viewDidLoad(animated)

    myTableView.delegate = self
    myTableView.dataSource = self

    for i in 0..<textArray.count {
      getTestFieldRecords(i)
    }

    dispatchGroup.notify(queue: .main) {
      self.myTableView.reloadData()
    }
  }

  private func getTestFieldRecords(_ record: Int) {
    dispatchGroup.enter()
    db.collection("testCollection").whereField("testField", arrayContains: textArray[i]).getDocuments{ (querySnapshot, err) in
      if let err = err {
        print("\(err.localizedDescription)")
        print("Test Error")
      } else {
        // rest of your code because I'm too lazy to format it
      }
      self.dispatchGroup.leave()
    }
  }

}

确保每次都致电leave()-是否出错。在所有DispatchGroup命令都用enter()命令完成之前,leave()不会完成。希望这可以帮助您指出正确的方向!