Firebase,IN子句查询和数据列表 [英] Firebase, IN clause query and lists of datas

查看:128
本文介绍了Firebase,IN子句查询和数据列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我看来,这是一个非常明显的问题,当有人需要处理一个数据库,所以我不知道为什么我不能找到任何有关它。

我试图设计我的项目的非关系数据库。我有一些信息(例如代码,图像和多语言描述)描述的产品列表,它们以不同的方式分类。这里是结构的一个快照:

 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
}
}
}

以下是产品的一些用法,真正的结构要复杂得多,但是可能足以解释我的问题:

family:{
products:{
-JiGh_31GA20JabpZBfa:true,
-Ji
产品:{
-JiGh_31GA20JabpZBfa:true
}

$ b $


$ b $ application $ {
application_1:{
products:{
-JiGh_31GA20JabpZBfa:true,
-JiGh_31GA20JabpZBfb:true
}
},
application_1:{
products:{
-JiGh_31GA20JabpZBfa:true,



code
$ b好​​的,现在让我们转到客户端!


我有几张表格,一张显示产品应用的族和一张。选择其中一个我想显示所有属于家庭的产品或在应用程序中使用的产品。



这就是我正在努力的:如果我想要在单元格中显示每个产品的描述和代码,是否必须对每个产品执行查询以检索其字段,或者是否可以使用某种IN查询?类似于从产品中选择*,其中键为IN {-JiGh_31GA20JabpZBfa,-JiGh_31GA20JabpZBfa} 。我知道这是一个SQL查询,但这只是为了更好地解释自己。

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

解决方案

正如@Frank van Puffelen的第一条评论所指出的,没有办法执行 IN 查询,或者,我想,类似于 JOIN

所以下面是我的代码片段

我创建了2 code> UITableViewController ,第一个显示了<第二个显示选择的产品 此代码检索家族列表

  let ref = FIRDatabase.database()。 ()
ref.child(families)。observeSingleEvent(of:.value,with:{snap in $ b $ if snap.value is NSNull {return}
let family = sn ap.value as! [String:AnyObject]
为family.keys中的familyKey {
让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 .value,其中:{snap in
如果snap.value是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(product.id).observeSingleEvent(of:.value,with:{snap in $ b $ if snap.val ue是NSNull {return}
product.populateProductDescription(product:snap.value as! [String:AnyObject])
self.tableView.reloadRows(at:[IndexPath.init(row:index,section:0)],with:.none)
})
}

如上所述,我利用了并行性,所以查询不是按顺序执行的,感兴趣的单元格将在每次更新时刷新。

 覆盖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
}

我希望这个答案会帮助那些正在尝试使用这个伟大的平台!


In my opinion this is pretty obvious question when someone has to deal with a DB, so I don't know why I can't find anything about it.
I'm trying to design the non-relational database for my project. I have a list of products described by some info (e.g. the code, an image and a multi language description) and they are categorized in different ways. Here is a snap of the structure:

"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"
      }
    }
  }

And below there are a couple of usages of the products, the real structure is much more complex, but probably it's enough to explain my problem:

"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,
        }
    }
}

Ok, now let's move to the client side!

I have a couple of tables, one that shows the families and one for the applications of the products. Selecting one of them I want to show all products that belong to the family or that are used in an application.

And here is what I'm struggling with: if I want to show the description and the code of each product in a cell, do I have to perform a query for every product to retrieve their fields or can I use some sort of "IN" query? Something like select * from products where key IN {"-JiGh_31GA20JabpZBfa", "-JiGh_31GA20JabpZBfa"}. I know that it's an SQL like query, but this was just to better explain myself.

Btw, I don't exclude that my way of designing the DB is wrong.

解决方案

As indicated in the first comment by @Frank van Puffelen, there is no way to perform a IN query or, I suppose, something similar to a JOIN.
So here are a few pieces of my code and a brief of the pipeline that I have implemented!

I created 2 UITableViewController, the first one to show the families and the second one to show the products of the selected one.

So, in the first controller I wrote this code to retrieve the list of families:

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()
})

After the selection of a family, in the second controller I'll perform two queries: one to retrieve the details of the product and the other one for the multi-language description.

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)
    })
}

As suggested, I've taken advantage of the parallelism, so the queries aren't performed sequentially and the interested cells will be refreshed at each update. I've taken care of the optional values to achieve that:

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
}

I hope this answer will help those who are trying to use this great platform!

这篇关于Firebase,IN子句查询和数据列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆