【问题标题】:Search by array values in Firebase在 Firebase 中按数组值搜索
【发布时间】:2017-03-10 04:16:52
【问题描述】:

我通过 REST API 使用 Firebase。我有以下数据库结构:

{
  "categories" : {
    "Cat1" : {},
    "Cat2" : {},
    "Cat3" : {},
    "Cat4" : {}
  },

  "items" : {
    "item1" : {
      "categories": ["Cat1", "Cat3"]
    },
    "item2" : {
      "categories": ["Cat1", "Cat3"]
    },
    "item3" : {
      "categories": ["Cat1", "Cat2", "Cat3"]
    },
    "item4" : {
      "categories": ["Cat4"]
    }
  }
}

如您所见,类别和项目之间存在“N N”类型的关系(一个类别可能有多个项目,一个项目可能属于多个类别)。

现在我想通过 Firebase REST API 获取 Cat1 的所有项目,但我做不到。

我们知道数组存储在 Firebase 中,类似于带有完整索引的地图:

"categories": {
  "0": "Cat1",
  "1": "Cat2",
  "2": "Cat3",
}

所以,我在实时数据库规则中添加了".indexOn": ["categories/*"] 并尝试调用它:
curl 'https://...firebaseio.com/...json?orderBy="categories/*"&equalTo="Cat1"'

但我只得到了这个:{ }

所以,我认为正则表达式在 Firebase 查询中不起作用,因为它在实时数据库规则中起作用:
".indexOn": ["categories/0"]
curl 'https://...firebaseio.com/...json?orderBy="categories/0"&equalTo="Cat1"'

当然,我可以将数据库模型更改为这样的:

{
  "categories" : {
    "Cat1" : {},
    "Cat2" : {},
    "Cat3" : {},
    "Cat4" : {}
  },

  "items" : {
    "item1" : {},
    "item2" : {},
    "item3" : {},
    "item4" : {}
  },

  "category-items": {
    "Cat1": ["item1", "item2", "item3"],
    "Cat2": ["item3"],
    "Cat3": ["item1", "item2", "item3"]
    "Cat4": ["item4"]
  }
}

并获取category-items 并遍历Cat1 数组,但是我必须调用REST API 读取方法太多次(该类别中的每个item 调用一个REST API)。所以,太贵了。

那么,谁能帮我获取原始数据库模型中某个类别中的所有项目?

更新
最终模型是:

{
  "categories" : {
    "Cat1" : {},
    "Cat2" : {},
    "Cat3" : {},
    "Cat4" : {}
  },

  "items" : {
    "item1" : {
      "Cat1": true,
      "Cat3": true,
    },
    "item2" : {
      "Cat1": true,
      "Cat3": true,
    },
    "item3" : {
      "Cat1": true,
      "Cat2": true,
      "Cat3": true,
    },
    "item4" : {
      "Cat4": true
    }
  }
}

我也加了

{
  rules": {
    ...
    "items": {
      ".indexOn": [ "Cat1", "Cat2", "Cat3", "Cat4" ]
    }
  }
}

实时数据库规则,REST API 调用是
curl 'https://...firebaseio.com/items.json?orderBy="Cat1"&equalTo=tr‌​ue'

感谢弗拉基米尔·加布里扬

【问题讨论】:

    标签: firebase firebase-realtime-database


    【解决方案1】:

    这是我建议的结构。

    {
      "categories" : {
        "Cat1" : {
            "items": {
                "item1":{/*Some item info*/},
                "item2":{/*Some item info*/}
            }
        },
        "Cat2" : {
            "items": {
                "item3":{/*Some item info*/}
            }
        },
      },
    
      "items" : {
        "item1" : {
          "categories": {
              "Cat1": true,
          }
        },
        "item3" : {
          "categories": {
              "Cat2": true, 
              "Cat3": true
          }
        }
      }
    }
    

    Cat1/Items/{itemId} 和items/{itemId} 中,您需要复制您的item 信息,但我认为没关系。

    另见这篇文章。 https://firebase.googleblog.com/2013/04/denormalizing-your-data-is-normal.html

    【讨论】:

      【解决方案2】:

      哇!非常感谢!您对替换的建议

      "item1" : {
        "categories": ["Cat1", "Cat3"]
      },
      

      "item1" : {
        "Cat1": true,
        "Cat3": true
      },
      

      可以解决问题,但是我将不得不在实时数据库规则中将每个Cat 添加到.indexOn,但这不像原始问题那么大。

      但我认为

      "categories" : {
        "Cat1" : {
          "items": {
              "item1":{/*Some item info*/},
              "item2":{/*Some item info*/}
          }
        },
        "Cat2" : {
          "items": {
              "item3":{/*Some item info*/}
          }
        },
      }
      

      在我的情况下不是一个好主意,因为每次我们获得有关Cat 的信息时都会获得许多备用数据(当我们不需要项目列表时,只需要Cat 的元数据)。所以,我建议以下模型:

      {
        "categories" : {
          "Cat1" : {},
          "Cat2" : {},
          "Cat3" : {},
          "Cat4" : {}
        },
      
        "items" : {
          "item1" : {
            "Cat1": true,
            "Cat3": true,
          },
          "item2" : {
            "Cat1": true,
            "Cat3": true,
          },
          "item3" : {
            "Cat1": true,
            "Cat2": true,
            "Cat3": true,
          },
          "item4" : {
            "Cat4": true
          }
        }
      }
      

      【讨论】:

      • 好的,如果您不需要在categories 中复制项目,我建议类别使用相同的模式。 "categories" : { "Cat1" : {"items": {"item1":true,"Item2": true}} } 在这种情况下,您可以通过一个请求获取cat1 的所有项目,并且无需在items/{itemId}/cat1 上存储索引以查询cat1 的所有项目
      • 在这种情况下,我必须在单独的 REST API 调用中获取有关每个 item 的完整信息。比较一个 REST API 调用来获取一个类别的所有项目,这太昂贵了。附言每个Cat 和每个item 都有一些额外的字段。显示的数据模型只是简化模型。
      • 好的,在这种情况下有两种选择。 1.复制所有项目数据或2.按照您在下面描述的方式进行,只是我想您需要添加类似这样的索引"items": { "$itemId": { "$category": {".indexOn": ".value"} } }
      • 是的,你是对的,就我而言,我在实时数据库规则中添加了"rules": { "items": { ".indexOn": [ "Cat1", "Cat2", "Cat3", "Cat4" ] } },因为我使用orderBy 而不是orderByValue。 REST API 调用是curl 'https://...firebaseio.com/...json?orderBy="Cat1"&equalTo=true'
      猜你喜欢
      • 2021-09-09
      • 2017-03-21
      • 1970-01-01
      • 2010-10-30
      • 2020-07-11
      • 2019-03-11
      • 2023-02-24
      • 2012-09-04
      相关资源
      最近更新 更多