Can anyone help me to improve the ldap recursive search from java? Below is my code. The filter I am passing is filter=(&(IMSI=404201234500021))
. Currently it's taking more than 19 sec to search one record from 100000 total records.
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;
}
Depending on the LDAP tree and data structure may one or more of the following tips will be useful:
Start the search at a specific
ou=
instead at root and reduce the search depth.Replace
""
inctx.search("", filter, ctls);
with a DN likeou=people,ou=company,ou=com
Limit the search result size.
Add a search result size via
ctls.setCountLimit(expected);
Limit the collected attributes
Add a set of attributes you are interested in.
String[] attributeFilter = { "cn", "mail" }; ctls.setReturningAttributes(attributeFilter);
EDIT to explain 1.
The LDAP structure is like a tree:
If you are searching for
john_doe
start recursive search atou=developer,ou=people,ou=company,ou=com
instead ofroot
(representing by""
in your code).EDIT example based on comment
This data structure looks strange to me. But based on these information the search should start at
IMSI=1,dc=example,dc=com
.