如何使用 firebase 在未指定的键中检索按键排序的数据
how to retrieve data ordered by key inside unspecified key with firebase
我在 firebase 中有一个快照供参考,如下所示:
"friendlist" : {
"user1" : {
"user3" : 1
},
"user2" : {
"user1" : 0
}
"user3" : {
"user1" : 1
}
}
参考解释:
每个用户都有一个唯一的 ID,我使用用户的 ID 作为他们朋友列表的唯一 ID。在上面的示例中,我有 3 个用户,每个用户都有自己的好友列表。在他们的好友列表中,有其他用户的 id 已经与他成为好友。如果值为1
,则该用户已经是好友。但是当值为0
时,用户请求加为好友。
我的问题是:
如何获取好友列表中所有 "user1"
值为 0 的用户好友列表的 ID?我可以在一次查询中完成吗?
我想我需要遍历所有好友列表和每个好友列表的 orderbykey 并寻找 "user1"
。或者有什么好的方法可以做到这一点?
任何答案将不胜感激,谢谢!
如果您下次多介绍一下您已经尝试过的内容,将会有所帮助。或者至少指定 language/environment 您的目标。
但在 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 客户端只会将所有数据下载到客户端并进行过滤 client-side。有了索引,就会进行查询server-side.
更好的数据模型
您可能想要搜索任何朋友,这会将索引变为:
".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 服务器发送一条命令,以将关系写入 friendList
和 friendsOf
节点。
我在 firebase 中有一个快照供参考,如下所示:
"friendlist" : {
"user1" : {
"user3" : 1
},
"user2" : {
"user1" : 0
}
"user3" : {
"user1" : 1
}
}
参考解释:
每个用户都有一个唯一的 ID,我使用用户的 ID 作为他们朋友列表的唯一 ID。在上面的示例中,我有 3 个用户,每个用户都有自己的好友列表。在他们的好友列表中,有其他用户的 id 已经与他成为好友。如果值为1
,则该用户已经是好友。但是当值为0
时,用户请求加为好友。
我的问题是:
如何获取好友列表中所有 "user1"
值为 0 的用户好友列表的 ID?我可以在一次查询中完成吗?
我想我需要遍历所有好友列表和每个好友列表的 orderbykey 并寻找 "user1"
。或者有什么好的方法可以做到这一点?
任何答案将不胜感激,谢谢!
如果您下次多介绍一下您已经尝试过的内容,将会有所帮助。或者至少指定 language/environment 您的目标。
但在 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 客户端只会将所有数据下载到客户端并进行过滤 client-side。有了索引,就会进行查询server-side.
更好的数据模型
您可能想要搜索任何朋友,这会将索引变为:
".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 服务器发送一条命令,以将关系写入 friendList
和 friendsOf
节点。