检查列表中是否存在具有密钥的节点 [英] Check if a node with a key exists in a list
问题描述
问题
我需要在现有的firebase数据结构中进行特殊检查,并想知道是否有可能(或任何解决方法)。 >
所以现在的结构是:
$ p $ {
groups:{
group1:{name:Group one}
group2:{name:Group two}
},
成员:{
group1:{
some @ email,com:true,
another @ email,com:true
},
group2:{some @ email,com:true}
}
}
我需要并且可以轻松做到:
- 获取特定组中的所有用户
- 将用户添加到任何特定组从任何特定的组中删除用户
但是我不知道如何进行检查:有些电子邮件是任何组的成员。
组和成员的数量可以相当大,所以我不想加载所有我我不是最佳解决方案
我能找到的唯一方法是添加一个更多的对象用户
并在那里保留可用的组。像这样:
{
users:{
some @ email,com:{
groups:{
group1:true,
group2:true
}
}
}
}
在这种情况下,我可以在没有任何问题的情况下执行检查,但会添加一个请求来添加/删除操作(向成员添加电子邮件并添加groupID用户;删除成员的电子邮件,并从用户删除组ID)。
感谢您的帮助。
例如,给定这个结构
<$ p $
会员
Group_0
ben @ thing,com:value
jerry @ thing,com:@value
frank @ thing,com :@value
Group_1
elmo @ thing,com:value
linda @ thing,com:value
$我们构造一个查询如下(ObjC) FQuery * q1 = [ref queryOrderedByCh ILD:@ 毛毛@事情,COM];
FQuery * q2 = [q1 queryEqualToValue:@value];
[q2 observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot * snapshot){
NSLog(@%@,snapshot.value);
}];
和查询返回
Group_1
$ p $上面的缺点是你正在查找的关键是动态的(电子邮件),而不是一个电子邮件,而且在这个键上不会有索引的规则 - 所以Firebase会抱怨说:
elmo @ thing,com:value
linda @ thing,com:value
使用未指定的索引。考虑添加.indexOn:.... etc
下面是一个可能的解决方案:使用节点结构像这样
emails_node
random_node_name_0
email:jerry@thing.com
group :group_0
random_node_name_1
email:linda@thing.com
组:group_1
random_node_name_2
电子邮件:elmo@thing.com
group:group_1
和一组规则
rules:{
.read:true,
.write:true,
emails_node :{
.indexOn:email
}
}
random_node_name_x是由childByAutoId(ObjC)创建的一个Firebase引用。
然后查询变为
FQuery * q1 = [ref queryOrderedByChild:@email];
FQuery * q2 = [q1 queryEqualToValue:@elmo@thing.com];
结果是
email =elmo@thing.com;
group = group1;
这里的优点有两个:
1)查询返回的电子邮件和组,所以你不仅可以检查重复,但也告诉我们它在哪里(如果需要的话)
2)实际可以使用电子邮件的值,而不是解析/更改电子邮件。 (点)到,
The problem
I need to have a special check in existed firebase data structure and want to know if it is possible (or any work around).
So current structure is:
{ groups: { group1: { name: "Group one" } group2: { name: "Group two" } }, members: { group1: { "some@email,com": true, "another@email,com": true }, group2: { "some@email,com": true } } }
What I need and can do easily:
- Get all users in a specific group
- Add a user to any specific group
- Remove a user from any specific group
But I have no idea how to make a check: if a user with some email is a member of any group.
Number of groups and members can be quite big so i do not want to load all members objects and check manually.
My not optimal solution
The only way I could find is to add one more object
users
and keep available groups there. Like so:{ users: { "some@email,com": { groups: { group1: true, group2: true } } } }
In this case I can do the check without any problems, but will add one more request to add/remove actions (add email to members and add groupID to user; remove email from members and remove groupID from user).
Thanks for any help.
解决方案It can be done
For example, given this structure
Members Group_0 ben@thing,com: "value" jerry@thing,com: @"value" frank@thing,com: @"value" Group_1 elmo@thing,com: "value" linda@thing,com: "value"
We construct a query as follows (ObjC)
FQuery *q1 = [ref queryOrderedByChild:@"elmo@thing,com"]; FQuery *q2 = [q1 queryEqualToValue:@"value"]; [q2 observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) { NSLog(@"%@", snapshot.value); }];
and the query returns
Group_1 elmo@thing,com: "value" linda@thing,com: "value"
(updated info)
The downside of the above is the key you are looking up is dynamic (the email) and there won't be a rule in place for indexing on that key - so Firebase will complain that
Using an unspecified index. Consider adding ".indexOn":....etc
Here's a possible solution: Use a node structure like this
emails_node random_node_name_0 email: "jerry@thing.com" group: "group_0" random_node_name_1 email: "linda@thing.com" group: "group_1" random_node_name_2 email: "elmo@thing.com" group: "group_1"
and a set of rules
"rules": { ".read": true, ".write": true, "emails_node": { ".indexOn": "email" } }
the random_node_name_x is a Firebase reference created by childByAutoId (ObjC)
the query then becomes
FQuery *q1 = [ref queryOrderedByChild:@"email"]; FQuery *q2 = [q1 queryEqualToValue:@"elmo@thing.com"];
the result is
email = "elmo@thing.com"; group = group1;
The advantages here are two fold:
1) The query returns both the email and group so you can not only check for duplicates but also tells us which group it's in (if needed)
2) The actual email value can be used instead of parsing/changing the email from . (dot) to ,
这篇关于检查列表中是否存在具有密钥的节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!