Firebase,IN子句查询和数据列表

时间:2016-11-24 10:01:32

标签: swift firebase firebase-realtime-database non-relational-database

在我看来,当有人要处理数据库时,这是非常明显的问题,所以我不知道为什么我找不到任何关于它的信息。
我正在尝试为我的项目设计非关系型数据库。我有一些信息描述的产品列表(例如代码,图像和多语言描述),并且它们以不同的方式分类。这是结构的一个快照:

"products" : {
    "-JiGh_31GA20JabpZBfa" : {
      "code" : "IR3300000000",
      "schema" : "http://lorempixel.com/400/200/",
    },
    "-JiGh_31GA20JabpZBfb" : {
      "code" : "PJ0000000000",
      "schema" : "http://lorempixel.com/400/200/",
    }
  }

"it" : {
    "products" : {
      "-JiGh_31GA20JabpZBfa" : {
        "description" : "desc product IR330000000"
      },
      "-JiGh_31GA20JabpZBfb" : {
        "description" : "description product PJ00000 lorem ipsum"
      }
    }
  }

下面有几个产品用途,真正的结构要复杂得多,但可能足以解释我的问题:

"families" : {
    "family1" : {
        "products" : {
            "-JiGh_31GA20JabpZBfa" : true,
            "-JiGh_31GA20JabpZBfb" : true
        }
    },
    "family2" : {
        "products" : {
            "-JiGh_31GA20JabpZBfa" : true
        }
    }
}

"applications" : {
    "application_1" : {
        "products" : {
            "-JiGh_31GA20JabpZBfa" : true,
            "-JiGh_31GA20JabpZBfb" : true
        }
    },
    "application_1" : {
        "products" : {
            "-JiGh_31GA20JabpZBfa" : true,
        }
    }
}

好的,现在让我们转移到客户端!

我有几张表,一张显示系列,另一张显示产品的应用。选择其中一个我想要显示属于该系列的所有产品或在应用程序中使用的产品。

这就是我正在努力的方面:如果我想在单元格中显示每个产品的描述和代码,我是否必须对每个产品执行查询以检索其字段,或者我可以使用某种排序“IN”查询?像select * from products where key IN {"-JiGh_31GA20JabpZBfa", "-JiGh_31GA20JabpZBfa"}这样的东西。我知道这是一个类似SQL的查询,但这只是为了更好地解释自己。

顺便说一句,我不排除我设计数据库的方式是错误的。

1 个答案:

答案 0 :(得分:1)

正如@Frank van Puffelen在第一条评论中指出的那样,无法执行IN查询,或者我认为,类似于JOIN。 以下是我的一些代码和我已实现的管道简介!

我创建了2 UITableViewController,第一个显示系列,第二个显示所选产品的产品

所以,在第一个控制器中,我编写了这段代码来检索系列列表

let ref = FIRDatabase.database().reference()
ref.child("families").observeSingleEvent(of: .value, with: { snap in
    if snap.value is NSNull { return }        
    let families = snap.value as! [String:AnyObject]
    for familyKey in families.keys {
        let familyDetails = familyes[familyKey] as! [String:AnyObject]
        self.families.append(FamilyL1.init(familyName: familyKey, familyDetails: familyDetails))
    }
    self.tableView.reloadData()
})

选择一个家庭后,在第二个控制器中,我会执行两个查询:一个用于检索产品的详细信息,另一个用于检索多语言描述

for (index, product) in (family?.products ?? []).enumerated() {
    self.ref.child("products").child(product.id).observeSingleEvent(of: .value, with: { snap in
        if snap.value is NSNull { return }
        product.populateProduct(product: snap.value as!  [String:AnyObject])
        self.tableView.reloadRows(at: [IndexPath.init(row: index, section: 0)], with: .none)
    })   
    self.ref.child("it").child("products").child(product.id).observeSingleEvent(of: .value, with: { snap in
        if snap.value is NSNull { return }
        product.populateProductDescription(product: snap.value as! [String:AnyObject])
        self.tableView.reloadRows(at: [IndexPath.init(row: index, section: 0)], with: .none)
    })
}

根据建议,我已经利用了并行性,因此查询不会按顺序执行,并且每次更新时都会刷新感兴趣的单元格。我已经处理了可选值来实现这一目标:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    let product = self.family?.products[indexPath.row]
    cell.textLabel?.text = product?.code ?? "..."
    cell.detailTextLabel?.text = product?.pDescription ?? "..."
    return cell
}

我希望这个答案可以帮助那些尝试使用这个伟大平台的人!