JNDI ldap search recursive



谁能帮我改进Java的ldap递归搜索?下面是我的代码。我正在传递的过滤器是filter=(&(IMSI=404201234500021)).目前,从 100000 条记录中搜索一条记录需要 19 秒以上。

public List<Map<String, String>> searchRecursive(List<String> sColumns, Map<String, String> searchFilters, int startIndex,
        int amount)
{
    String searchRDN = "";
    List<Map<String, String>> items = new ArrayList<Map<String, String>>();
    Attributes searchAttributes = new BasicAttributes();
    SearchControls ctls = new SearchControls();
    ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    NamingEnumeration<SearchResult> results = null;
    try
    {
             String filter = "";
             if (searchFilters != null)
             {
                 for (Map.Entry<String, String> entry : searchFilters.entrySet())
                 {
                     filter += "(" + entry.getKey() + "=" + entry.getValue() + ")";
                 }
             }    
            filter = "(&" + filter + ")";
            _log.debug("filter="+filter);
            byte[] cookie = null;
            ctx.setRequestControls(new Control[]
                {new PagedResultsControl(amount, cookie, Control.NONCRITICAL)});
           //results = ctx.search(searchRDN, searchAttributes, null);
            results= ctx.search("", filter, ctls);
        if (results != null)
        {
            while (results.hasMore())
            {
                Map<String, String> rowSet = new CaseInsensitiveMap();
                SearchResult searchResult = results.next();
                String rdn = searchResult.getNameInNamespace();
                rowSet.put("baseRDN", rdn);
                NamingEnumeration<? extends Attribute> all = searchResult.getAttributes().getAll();
                while (all.hasMoreElements())
                {
                    Attribute attr = all.nextElement();
                    // attr.getID()
                    NamingEnumeration<?> all2 = attr.getAll();
                    String value = "";
                    while (all2.hasMoreElements())
                    {
                        if (!value.equals(""))
                        {
                            value += ", " + all2.nextElement();
                        }
                        else
                        {
                            value = "" + all2.nextElement();
                        }
                    }
                    rowSet.put(attr.getID(), value);
                }
                items.add(rowSet);
            }
        }
    }
    catch (Throwable e)
    {
        _log.error(e.getMessage());
        _log.debug(e);
    }
    finally
    {
        if (results != null)
        {
            try
            {
                results.close();
            }
            catch (Exception e)
            {
            }
        }
    }
    return items;
}

根据LDAP树和数据结构,以下一个或多个提示可能会很有用:

  1. 从特定ou=而不是从根目录开始搜索,并减少搜索深度。

    ctx.search("", filter, ctls); 中的""替换为类似 ou=people,ou=company,ou=com 的 DN

  2. 限制搜索结果大小。

    通过ctls.setCountLimit(expected);添加搜索结果大小

  3. 限制收集的属性

    添加一组您感兴趣的属性。

    String[] attributeFilter = { "cn", "mail" }; ctls.setReturningAttributes(attributeFilter);

编辑以解释 1.

LDAP 结构就像一棵树:

root
 +- dc=com
  +- dc=company
   +- dc=people
    +- ou=developer
     +- dn=john_doe
    +- ou=manager
     +- dn=jane_foo

如果要搜索john_doe请在ou=developer,ou=people,ou=company,ou=com处开始递归搜索,而不是root(在代码中用""表示)。

基于注释编辑示例

root
 +- dc=com
  +- dc=example
   +- IMSI=1
    +- IMSI=1
     +- Context-Identifier=1001

这种数据结构对我来说看起来很奇怪。但是基于这些信息,搜索应该从 IMSI=1,dc=example,dc=com .