【问题标题】:Firebase Query by Inner Array ValuesFirebase 按内部数组值查询
【发布时间】:2018-08-19 18:18:07
【问题描述】:

通过从我的应用程序的下拉列表中选择一个值,我需要在其内部节点“foodtype”中获取包含所选值的每个对象的列表。

我的 Firebase 数据库中有以下结构:

restaurants
  - key: "12345"
    - name: "Salad house"
    - address: "Etc etc etc"
    - foodtypes
        - 0: "Salad"
        - 1: "Fastfood"
        - 2: "Seafood"
...

例如:如果我选择“沙拉”、“快餐”或“海鲜”,我应该在我的餐馆列表中获得上面的对象。但是,如果我选择“日本料理”,我应该什么也得不到(或任何其他包含该内容的记录)。

有没有办法在 Firebase 中执行此操作而无需创建大量连接的字段/值?我真的很感激任何建议!

【问题讨论】:

  • 如果您选择Salad,您想要获取食物类型?
  • 如果我选择“沙拉”,我想获取整个餐厅对象,因为它在其 'foodtypes' 内部节点中包含该值。
  • 我不确定这是否可能,但如果您删除 foodtypes 并添加 - 0: "Salad" - 1: "Fastfood" - 2: "Seafood" 则可能
  • 我可以像你说的那样删除foodtypes节点并创建3个名为foodtype1foodtype2foodtype3的字段,但这样做我会设置一个固定数量的food types每个restaurant 允许。

标签: javascript typescript firebase ionic-framework firebase-realtime-database


【解决方案1】:

这可以通过 Cloud Firestore 查询实现,而不是 Firebase RTDB(实时数据库)查询。

如果您想使用 Firebase RTDB 进行处理,您的数据库应如下所示。

restaurants
  - key: "12345"
    - name: "Salad house"
    - address: "Etc etc etc"
    - foodtype: 0 (or 1 or 2 ...)
...

您也可以使用诸如“Salad”、“Fastfood”、“Seafood”之类的字符串,但由于将来可能会更改名称,因此我将使用整数作为常量变量,并在您的 javascript 代码中将其定义为const FOODTYPE_SALAD = 0const FOODTYPE_FASTFOOD = 1

最后你可以得到如下代码列表。

return restaurantsRef.orderByChild('foodtype').equalTo(FOODTYPE_SALAD).once('value').then(snap => {
    // TODO: ...
});

但是这种方式有一些缺点。

例如,您无法根据需要对列表进行排序。如果要将餐厅列表排序为注册日期怎么办?

因此,在这种情况下,Firebase RTDB 的最佳选择是非规范化您的数据库并扁平化数据库。

你需要Server side Fan-out on Cloud Functions for Firebase

这是您的数据库表的最终外观。

restaurants
  - key: "12345"
    - name: "Salad house"
    - address: "Etc etc etc"
    - foodtype: 0
  - key: "22222"
    - name: "Fastfood house"
    - address: "Etc etc etc"
    - foodtype: 1
  - key: "33333"
    - name: "Seafood house"
    - address: "Etc etc etc"
    - foodtype: 2

restaurants-salad
  - key: "12345"
    - name: "Salad house"
    - address: "Etc etc etc"
    - foodtype: 0

restaurants-fastfood
  - key: "22222"
    - name: "Fastfood house"
    - address: "Etc etc etc"
    - foodtype: 1

restaurants-seafood
  - key: "33333"
    - name: "Seafood house"
    - address: "Etc etc etc"
    - foodtype: 2
...

记住restaurants 应该有所有原始restaurant 对象数据。

【讨论】:

  • 我真的很难接受这种程度的非规范化(我一直在使用关系数据库多年),但我认为我必须这样做。
  • @Marcelo 请记住,非规范化在 NoSQL 数据库中是正常的,它比 rdb 具有更好的性能。
  • 如果对你有帮助一定要采纳我的回答:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-08-19
  • 1970-01-01
  • 2015-04-07
  • 1970-01-01
  • 1970-01-01
  • 2020-09-28
  • 2022-12-05
相关资源
最近更新 更多