如何在Firebase中查询相关记录?

mit*_*sso 6 firebase

给定Firebase中的这个数据库结构:

{
    "users": {
        "user1": {
            "items": {
                "id1": true
            }
        },
        "user2": {
            "items": {
                "id2": true
            }
        }
    },

    "items": {
        "id1": {
            "name": "foo1",
            "user": "user1"
        },
        "id2": {
            "name": "foo2",
            "user": "user2"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

哪种查询属于特定用户的项目更有效?

Firebase文档似乎暗示了这一点:

var itemsRef = new Firebase("https://firebaseio.com/items");
var usersItemsRef = new Firebase("https://firebaseio/users/" + user.uid + "/items");
usersItemsRef.on("child_added", function(data){
    itemsRef.child(data.key()).once("value", function(itemData){
        //got the item
    });
});
Run Code Online (Sandbox Code Playgroud)

但使用.equalTo()查询也可以:

var ref = new Firebase("https://firebaseio.com/items");
ref.orderByChild("user").equalTo(user.uid).on("child_added", function(data){
    //got the item
});
Run Code Online (Sandbox Code Playgroud)

后一个代码看起来更简洁,并且不需要将项密钥非规范化为用户记录,但是我不清楚它是否是一种效率较低的方法(假设我在"用户"上创建索引).

谢谢.

Tom*_*ich 1

这是相当古老的问题,但是在开发 firebase 支持的应用程序时,我发现自己经常处理类似的问题。

.equalTo 更省时(特别是,如果一个用户拥有大量项目)。尽管 n+1 订阅不会导致到云的 n+1 网络往返,但拥有如此多的开放订阅会带来一些性能损失。

此外,.equalTo 方法不会导致数据非规范化。

然而,有一个问题:当您想要保护数据时,.equalTo 方法可能根本停止工作。

要允许用户调用 orderByChild("user").equalTo(user.uid),他们必须具有“items”集合的读取权限。此读取权限对根目录为 /items 的整个子文档有效。

摘要:如果要阻止 user1 查找 user2 的项目,则必须使用 BYOI(构建自己的索引)方法。这样您就可以验证该用户只读取放入其索引的项目。

最后,免责声明:) 我只使用 firebase 很短一段时间,我得到的只是一些基准测试和文档。如果我有任何错误,请纠正我。