您如何获得与用户相关的所有用户(直接和间接)
How can you get all users related to a user ( directly & indirectly )
我有一个问题,我必须让所有用户与使用自定义 LDAP 属性 的用户相关,现在我只能通过使用递归函数和一个将不断增长的查询来实现这一点每次调用,我知道这不会扩展,有没有更好的方法来实现这个。
这是我使用的代码。
/*
* at start accumlatedUsers === usersToBeSearched accumlatedUsers will be
* updated
*/
public void GetSubordinatesRecurisve(ArrayList<String> usersToBeSearched, ArrayList<String> accumlatedUsers)
throws NamingException {
String searchFilter = "(&(ObjectCategory=User)(|";
for (String user : usersToBeSearched) {
searchFilter += "(supeirorName=" + user + ")";
}
searchFilter += "))";
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration<SearchResult> results = ldapContext.search(ldapSearchBase, searchFilter, searchControls);
ArrayList<String> usersFounded = new ArrayList<String>();
SearchResult searchResult = null;
while (results.hasMoreElements()) {
searchResult = (SearchResult) results.nextElement();
usersFounded.add((String) searchResult.getAttributes().get("sAMAccountName").get());
}
accumlatedUsers.addAll(usersFounded);
if (usersFounded.size() != 0) {
this.GetSubordinatesRecurisve(usersFounded, accumlatedUsers);
}
return;
}
谢谢。
是的,问题是您查询中的用户数量 ldapContext.search
将呈指数增长,因此根本无法扩展。例如,第一个查询针对 1 个用户,第二个查询针对 3 个用户,第三个查询针对 9 个用户等等。
与单个用户相关的用户可以看作一棵树(如果没有循环)。遍历树的最常见方法是深度优先搜索 (DFS) 或面包优先搜索 (BFS) 算法。如果您的目标是查找 ALL 与某个用户相关的用户,那么任一选项都可以。
DFS(或 BFS)比您的解决方案更具可扩展性,因为它总是每次查询 1 个用户的 LDAP。
我无法测试你的方法,但我正在向你展示如何实现 DFS:
// ...
accumlatedUsers.addAll(usersFounded);
for(String userFounded : usersFounded){
if(!visited.contains(userFounded)){
visited.add(userFounded);
List<String> singleUserList = new ArrayList<>();
singleUserList.add(userFounded);
this.GetSubordinatesRecurisve(singleUserList, accumlatedUsers);
}
}
return;
注意访问过的列表,它是为了防止用户图中出现循环。
我有一个问题,我必须让所有用户与使用自定义 LDAP 属性 的用户相关,现在我只能通过使用递归函数和一个将不断增长的查询来实现这一点每次调用,我知道这不会扩展,有没有更好的方法来实现这个。
这是我使用的代码。
/*
* at start accumlatedUsers === usersToBeSearched accumlatedUsers will be
* updated
*/
public void GetSubordinatesRecurisve(ArrayList<String> usersToBeSearched, ArrayList<String> accumlatedUsers)
throws NamingException {
String searchFilter = "(&(ObjectCategory=User)(|";
for (String user : usersToBeSearched) {
searchFilter += "(supeirorName=" + user + ")";
}
searchFilter += "))";
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration<SearchResult> results = ldapContext.search(ldapSearchBase, searchFilter, searchControls);
ArrayList<String> usersFounded = new ArrayList<String>();
SearchResult searchResult = null;
while (results.hasMoreElements()) {
searchResult = (SearchResult) results.nextElement();
usersFounded.add((String) searchResult.getAttributes().get("sAMAccountName").get());
}
accumlatedUsers.addAll(usersFounded);
if (usersFounded.size() != 0) {
this.GetSubordinatesRecurisve(usersFounded, accumlatedUsers);
}
return;
}
谢谢。
是的,问题是您查询中的用户数量 ldapContext.search
将呈指数增长,因此根本无法扩展。例如,第一个查询针对 1 个用户,第二个查询针对 3 个用户,第三个查询针对 9 个用户等等。
与单个用户相关的用户可以看作一棵树(如果没有循环)。遍历树的最常见方法是深度优先搜索 (DFS) 或面包优先搜索 (BFS) 算法。如果您的目标是查找 ALL 与某个用户相关的用户,那么任一选项都可以。
DFS(或 BFS)比您的解决方案更具可扩展性,因为它总是每次查询 1 个用户的 LDAP。
我无法测试你的方法,但我正在向你展示如何实现 DFS:
// ...
accumlatedUsers.addAll(usersFounded);
for(String userFounded : usersFounded){
if(!visited.contains(userFounded)){
visited.add(userFounded);
List<String> singleUserList = new ArrayList<>();
singleUserList.add(userFounded);
this.GetSubordinatesRecurisve(singleUserList, accumlatedUsers);
}
}
return;
注意访问过的列表,它是为了防止用户图中出现循环。