Dictionary 避免salesforce对soql查询的管理限制为每个组获取组成员?

Dictionary 避免salesforce对soql查询的管理限制为每个组获取组成员?,dictionary,salesforce,limit,apex,soql,Dictionary,Salesforce,Limit,Apex,Soql,我在apex salesforce平台上工作。我有一个循环来获取所有组名、ID和它们各自的组成员,将它们放在一个对象中以收集所有这些信息,然后将它们放在一个列表中以获得我需要的所有组和所有信息的列表: List<groupInfo> memberList = new List<groupInfo>(); for(Id key : groupMap.keySet()){ groupInfo newGroup = new groupInfo();

我在apex salesforce平台上工作。我有一个循环来获取所有组名、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);
            }
        }
    }
List memberList=newlist();
对于(Id键:groupMap.keySet()){
groupInfo newGroup=newgroupinfo();
g组=groupMap.get(键);
如果(g.Name!=null){
set memberSet=getGroupEventRelations(新集合{g.Id});
if(memberSet.size()!=0){
newGroup.groupId=g.Id;
newGroup.groupName=g.Name;
newGroup.groupMemberIds=memberSet;
成员列表。添加(新组);
}
}
}
我的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(设置GroupId){
set nesteds=new set();
set returnIds=new set();
列表成员=[从GroupMember中选择Id、GroupId、UserOrGroupId,其中GroupId位于:GroupId];
对于(组成员:成员){
if(Schema.Group.SObjectType==member.UserOrGroupId.getSObjectType()){
添加(member.UserOrGroupId);
}否则{
add(member.UserOrGroupId);
}
}
如果(nesteds.size()>0){
addAll(getGroupEventRelations(nestedId));
}
返回ID;
}
getGroupEventRelations包含一个soql查询,考虑到这是在组循环中调用的。。。如果有人有超过100个组成员,或者组内可能有一系列100个嵌套组。。。然后这将很快达到salesforce soql查询的管理限制

我想知道是否有人知道在getGroupEventRelations中消除soql查询的方法,从而消除循环中的查询。当我需要某个特定组的组成员时,我真的没有看到一种方法可以在循环中没有更多的循环,而在循环中我可能会遇到CPU超时限制:(


提前感谢您的帮助!

如果数字足够大,则没有解决方案,您将遇到一些管理器限制。但是您当然可以使代码使用比现在更大的数字。这里有一个小技巧,您可以将嵌套减少5倍。而不只是查看直接父级(单级子级)在一个查询中查找父母、祖父母、曾祖父母等。 [从GroupMember中选择Id、GroupId、UserOrGroupId,其中(GroupId在:GroupId中或Group.GroupId在:GroupId中或Group.Group.GroupId在:GroupId中或Group.Group.Group.GroupId在:GroupId中或Group.Group.Group.GroupId在:GroupId中)和Id不在:ReturnID]

在一个SOQL调用中,您只得到了5个(或者是6个?)级别的子级,因此您现在可以支持更多的嵌套级别。请注意,我添加了一个“NOT in”子句,以确保您不会重复已有的子级,因为您不知道哪些ID来自底层

你也可以第一次呼叫所有的通话组,而不是一次呼叫每个通话组。因此,如果有人有100个通话组,你只需拨打一次,而不是100次

List<Group> groups = groupMap.values();
List<GroupMember> allMembers = [SELECT Id, GroupId, UserOrGroupId FROM GroupMember WHERE GroupId IN :groups];
List groups=groupMap.values();
列出所有成员=[从GroupMember中选择Id、GroupId、UserOrGroupId,其中GroupId位于:groups];
最后,您可以在一个SOQL调用中查询所有GroupMembers,然后自己迭代。正如您所说,您可能会遇到10秒的限制,但是如果组的数量不是数百万,您可能会很好,特别是如果您执行一些O(n)分析并选择好的数据结构和算法。从好的方面来说,无论嵌套和树的复杂性如何,您都不必担心SOQL限制。这个答案应该非常有用,因为如果您在一次调用中调用所有成员,它们几乎正是您必须做的事情。

谢谢您的评论!我将像您的第一个soql示例中那样获得多个级别的子级。我们正在考虑对递归调用应用5ish层限制,因此使用该方法似乎可以一次性完成。但现在,我在加载时的最坏情况是O(n^3)仅由于这个组成员的原因,如果我可以减少这些,它应该是O(n^2),我认为在处理哪些组在哪些活动中,由于salesforce在组和活动之间没有桥梁,所以无论如何都不能使它低于O(n^2):(语法应该是Group.Group.GroupId吗?它不识别这种关系。似乎Group有GroupMember的子对象,但GroupMember似乎没有组的可见父对象……至少我在查看这些对象时可以从salesforce workbench网站上看到这一点。@TylerDahle我想我误解了,我在GroupId是对其他成员的引用(即对自身的递归引用,类似于帐户上的“父帐户”字段)。看起来GroupMember是一个连接对象,提供了多对多关系,但没有直接的父子链接。遗憾的是,SOQL不支持同一对象类型上的内部连接(无论出于何种原因),因此我看不到任何方法可以在一个查询中获得多个级别。抱歉,我错了:(没问题。是的,我不知道如何避开获取所有组和所有组成员,然后循环匹配Id和groupId,这可能会遇到10秒的限制,或者我的递归组成员函数,这将很容易遇到100个查询限制…也许10秒的限制不太可能发生?如果你查看文章他们讨论了一种O(N)算法,用父ID从节点的平面结构中构建树,这正是您所拥有的。O(N)复杂度10秒应该足以