避免 salesforce 对 soql 查询的管理限制获取每个组的组成员?
Avoiding salesforce governing limits on soql queries getting group members for each group?
我在 salesforce 平台的 apex 工作。我有这个循环来获取所有组名、ID 及其各自的组成员,将它们放在一个对象中以收集所有这些信息,然后将其放入一个列表中以包含所有组的列表和我需要的所有信息:
List<groupInfo> memberList = new List<groupInfo>();
for(Id key : groupMap.keySet()){
groupInfo newGroup = new groupInfo();
Group g = groupMap.get(key);
if(g.Name != null){
set<Id> memberSet = getGroupEventRelations(new set<Id>{g.Id});
if(memberSet.size() != 0){
newGroup.groupId = g.Id;
newGroup.groupName = g.Name;
newGroup.groupMemberIds = memberSet;
memberList.add(newGroup);
}
}
}
我的 getGroupEventRelations 方法是这样的:
global static set<Id> getGroupEventRelations(set<Id> groupIds){
set<Id> nestedIds = new set<Id>();
set<Id> returnIds = new set<Id>();
List<GroupMember> members = [SELECT Id, GroupId, UserOrGroupId FROM GroupMember WHERE GroupId IN :groupIds];
for(GroupMember member : members){
if(Schema.Group.SObjectType == member.UserOrGroupId.getSObjectType()){
nestedIds.add(member.UserOrGroupId);
} else{
returnIds.add(member.UserOrGroupId);
}
}
if(nestedIds.size() > 0){
returnIds.addAll(getGroupEventRelations(nestedIds));
}
return returnIds;
}
getGroupEventRelations 包含一个 soql 查询,并且考虑到这是在组循环内调用的...如果某人有超过 100 个组和组成员,或者组内可能有一系列 100 个嵌套组...那么这就是很快达到 salesforce soql 查询的管理限制...
我想知道是否有人知道可能摆脱 getGroupEventRelations 中的 soql 查询以摆脱循环中的查询的方法。当我想要特定组的组成员时,我并没有真正看到一种方法来解决这个问题,而没有更多的循环内部循环,我可能会冒 运行 进入 CPU 超时销售人员管理限制的风险:(
提前感谢您的帮助!
数量足够大时没有解决方案,您将 运行 进入某些调控器限制。但是您当然可以让您的代码处理比现在更大的数字。 这里有一个快速的小技巧,可以将嵌套减少 5 倍。而不是只看直接的 parent(children 的单层)寻找 parent、grandparent、曾祖 parent 等,全部在一个查询.
[SELECT Id, GroupId, UserOrGroupId FROM GroupMember WHERE (GroupId IN :groupIds OR Group.GroupId IN :groupIds OR Group.Group.GroupId IN :groupIds OR Group.Group.Group.GroupId IN :groupIds OR Group.Group.Group.Group.GroupId IN :groupIds OR Group.Group.Group.Group.Group.GroupId IN :groupIds) 并且 Id NOT IN :returnIds];
您刚刚在一个 SOQL 调用中获得了 5 个(或者是 6 个?)级别的 children,因此您现在可以支持多倍的嵌套级别。请注意,我添加了一个 'NOT IN' 子句以确保您不会重复已经拥有的 children,因为您不知道哪些 ID 来自底层。
您也可以第一次呼叫所有群组,而不是一次呼叫每个群组。因此,如果某人有 100 个群组,您将只拨打一个电话,而不是 100 个。
List<Group> groups = groupMap.values();
List<GroupMember> allMembers = [SELECT Id, GroupId, UserOrGroupId FROM GroupMember WHERE GroupId IN :groups];
最后,您可以在单个 SOQL 调用中查询所有 GroupMembers,然后自己进行迭代。就像你说的,你冒着 运行 进入 10 秒限制的风险,但如果组的数量不是数百万,你可能会很好,特别是如果你做一些 O(n) 分析和选择好的数据结构和算法。从好的方面来说,无论嵌套和树的复杂性如何,您都不必担心 SOQL 限制。这个答案应该非常有帮助,如果您在一个电话中召集所有成员,他们所做的几乎与您必须做的完全一样。
How to efficiently build a tree from a flat structure?
我在 salesforce 平台的 apex 工作。我有这个循环来获取所有组名、ID 及其各自的组成员,将它们放在一个对象中以收集所有这些信息,然后将其放入一个列表中以包含所有组的列表和我需要的所有信息:
List<groupInfo> memberList = new List<groupInfo>();
for(Id key : groupMap.keySet()){
groupInfo newGroup = new groupInfo();
Group g = groupMap.get(key);
if(g.Name != null){
set<Id> memberSet = getGroupEventRelations(new set<Id>{g.Id});
if(memberSet.size() != 0){
newGroup.groupId = g.Id;
newGroup.groupName = g.Name;
newGroup.groupMemberIds = memberSet;
memberList.add(newGroup);
}
}
}
我的 getGroupEventRelations 方法是这样的:
global static set<Id> getGroupEventRelations(set<Id> groupIds){
set<Id> nestedIds = new set<Id>();
set<Id> returnIds = new set<Id>();
List<GroupMember> members = [SELECT Id, GroupId, UserOrGroupId FROM GroupMember WHERE GroupId IN :groupIds];
for(GroupMember member : members){
if(Schema.Group.SObjectType == member.UserOrGroupId.getSObjectType()){
nestedIds.add(member.UserOrGroupId);
} else{
returnIds.add(member.UserOrGroupId);
}
}
if(nestedIds.size() > 0){
returnIds.addAll(getGroupEventRelations(nestedIds));
}
return returnIds;
}
getGroupEventRelations 包含一个 soql 查询,并且考虑到这是在组循环内调用的...如果某人有超过 100 个组和组成员,或者组内可能有一系列 100 个嵌套组...那么这就是很快达到 salesforce soql 查询的管理限制...
我想知道是否有人知道可能摆脱 getGroupEventRelations 中的 soql 查询以摆脱循环中的查询的方法。当我想要特定组的组成员时,我并没有真正看到一种方法来解决这个问题,而没有更多的循环内部循环,我可能会冒 运行 进入 CPU 超时销售人员管理限制的风险:(
提前感谢您的帮助!
数量足够大时没有解决方案,您将 运行 进入某些调控器限制。但是您当然可以让您的代码处理比现在更大的数字。 这里有一个快速的小技巧,可以将嵌套减少 5 倍。而不是只看直接的 parent(children 的单层)寻找 parent、grandparent、曾祖 parent 等,全部在一个查询.
[SELECT Id, GroupId, UserOrGroupId FROM GroupMember WHERE (GroupId IN :groupIds OR Group.GroupId IN :groupIds OR Group.Group.GroupId IN :groupIds OR Group.Group.Group.GroupId IN :groupIds OR Group.Group.Group.Group.GroupId IN :groupIds OR Group.Group.Group.Group.Group.GroupId IN :groupIds) 并且 Id NOT IN :returnIds];
您刚刚在一个 SOQL 调用中获得了 5 个(或者是 6 个?)级别的 children,因此您现在可以支持多倍的嵌套级别。请注意,我添加了一个 'NOT IN' 子句以确保您不会重复已经拥有的 children,因为您不知道哪些 ID 来自底层。
您也可以第一次呼叫所有群组,而不是一次呼叫每个群组。因此,如果某人有 100 个群组,您将只拨打一个电话,而不是 100 个。
List<Group> groups = groupMap.values();
List<GroupMember> allMembers = [SELECT Id, GroupId, UserOrGroupId FROM GroupMember WHERE GroupId IN :groups];
最后,您可以在单个 SOQL 调用中查询所有 GroupMembers,然后自己进行迭代。就像你说的,你冒着 运行 进入 10 秒限制的风险,但如果组的数量不是数百万,你可能会很好,特别是如果你做一些 O(n) 分析和选择好的数据结构和算法。从好的方面来说,无论嵌套和树的复杂性如何,您都不必担心 SOQL 限制。这个答案应该非常有帮助,如果您在一个电话中召集所有成员,他们所做的几乎与您必须做的完全一样。 How to efficiently build a tree from a flat structure?