避免 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?