JNDI ldap搜索递归

时间:2015-06-17 05:37:06

标签: java ldap jndi openldap

有人可以帮我改进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;
}

1 个答案:

答案 0 :(得分:0)

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

  1. 在特定的ou=处开始搜索,而不是根,并缩小搜索深度。

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

  2. 等DN
  3. 限制搜索结果大小。

    通过ctls.setCountLimit(expected);

  4. 添加搜索结果大小
  5. 限制收集的属性

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

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

  6. 编辑解释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开始。