如何使用firebase检索由未指定密钥内的密钥排序的数据

时间:2015-12-31 02:45:49

标签: firebase firebase-realtime-database nosql

我在firebase中有一个快照供我参考:

"friendlist" : {
    "user1" : {
        "user3" : 1
    },
    "user2" : {
        "user1" : 0
    }
    "user3" : {
        "user1" : 1
    }
}

参考文献的解释:

每个用户都有一个唯一的ID,我使用用户的id作为他们的friendlist唯一ID。在上面的示例中,我有3个用户,每个用户都有自己的朋友列表。在他们的朋友列表中,还有其他用户的ID已经是他的朋友。如果值为1,则该用户已成为朋友。但是当值为0时,用户请求成为朋友。

我的问题是:

如何在朋友列表中获取所有用户的好友列表ID,其中"user1"的值为0?我可以只用一个查询吗?

我想我需要遍历每个好友列表的所有好友列表和orderbykey并寻找"user1"。或者有什么好方法可以做到这一点?

任何答案都将不胜感激,谢谢!

1 个答案:

答案 0 :(得分:1)

如果您下次再详细了解您已经尝试过的内容,那将会有所帮助。或者至少指定您要定位的语言/环境。

但是在JavaScript中,您可以通过以下方式获得这些用户:

var ref = new Firebase('https://yours.firebaseio.com/friendlist');
var query = ref.orderByChild('user1').equalTo(0);
query.once('value', function(usersSnapshot) {
    usersSnapshot.forEach(function(userSnapshot) {
        console.log(userSnapshot.key());
    });
});

使用您指定的样本数据,将打印:

user2

您应该添加(并将收到警告)有效执行此查询的索引:

{
  "rules": {
    "friendlist": {
      ".indexOn": ['user1']
    }
  }
}

如果没有此索引,Firebase客户端只会将所有数据下载到客户端并进行客户端过滤。使用索引,查询将在服务器端执行。

更好的数据模型

您可能希望搜索任何朋友,将索引转换为:

      ".indexOn": ['user1', 'user2', 'user3']

但是使用这种结构,您需要在添加用户时添加索引。 Firebase SDK没有用于添加索引的API,这通常表明您的数据结构不符合您的需求。

使用NoSQL数据库时,您的数据结构应满足您正在构建的应用程序的需求。由于您要查询user1的朋友,您应该以该格式存储数据:

"friendlist" : {
    "user1" : {
        "user3" : 1
    },
    "user2" : {
        "user1" : 0
    }
    "user3" : {
        "user1" : 1
    }
},
"friendsOf": {
    "user1": {
      "user2": 0,
      "user3": 1
    },
    "user3": {
      "user1": 1
    }
}

如您所见,我们现在存储两个列表: * friendList是您的原始列表 * friendsOf与原始列表相反

当您需要知道谁是用户1的朋友时,您现在可以通过以下方式阅读该数据:

ref.child('friendsOf').child('user1').on('value'...

请注意,我们不再需要对此进行查询,这使得操作在数据库端的可扩展性更高。

原子更新

使用这种新的数据模型,您需要在添加好友关系时在两个位置写入数据。您可以使用两个set() / update()操作执行此操作。但是在最近的Firebase SDK中,您还可以在单​​个更新中执行这两种写操作:

function setRelationship(user1, user2, value) {
    var updates = {};
    updates['friendList/'+user1+'/'+user2] = value;
    updates['friendsOf/'+user2+'/'+user1] = value;
    ref.update(updates);
}
setRelationship('user3', 'user4', 1);

以上操作会向Firebase服务器发送一个命令,以便将关系写入friendListfriendsOf个节点。