在 Firebase 中按数组值搜索

Ild*_*dar 5 firebase firebase-realtime-database

我通过 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"]
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我们在类别和项目之间有“N <-> N”类型的关系(一个类别可以有多个项目,一个项目可以在多个类别中)。

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

正如我们所知,数组存储在 Firebase 中,就像具有完整索引的地图一样:

"categories": {
  "0": "Cat1",
  "1": "Cat2",
  "2": "Cat3",
}
Run Code Online (Sandbox Code Playgroud)

所以,我添加".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"]
  }
}
Run Code Online (Sandbox Code Playgroud)

并获取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
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我还加了

{
  rules": {
    ...
    "items": {
      ".indexOn": [ "Cat1", "Cat2", "Cat3", "Cat4" ]
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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

感谢 Vladimir Gabrielyan

Vla*_*yan 3

这是我建议采用的结构。

{
  "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
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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