DS 7.1.8

Query

Examples in this documentation depend on features activated in the ds-evaluation setup profile.

To search, perform an HTTP GET with a _queryFilter=expression parameter. For details about the query filter expression, see Query.

The _queryId, and _totalPagedResultsPolicy parameters, described in Query are not used in DS software at present.

The following table shows LDAP search filters and corresponding query filter expressions:

LDAP Filter REST Filter

(&)

_queryFilter=true

(uid=*)

_queryFilter=_id+pr

(uid=bjensen)

_queryFilter=_id+eq+'bjensen'

(uid=*jensen*)

_queryFilter=_id+co+'jensen'

(uid=jensen*)

_queryFilter=_id+sw+'jensen'

(&(uid=*jensen*)(cn=babs*))

_queryFilter=(_id+co+'jensen'and+displayName+sw'babs')

(|(uid=*jensen*)(cn=sam*))

_queryFilter=(_id+co+'jensen'or+displayName+sw'sam')

(!(uid=*jensen*))

_queryFilter=!(_id+co+'jensen')

(uid<=jensen)

_queryFilter=_id+le+'jensen'

(uid>=jensen)

_queryFilter=_id+ge+'jensen'

For query operations, the filter expression is constructed from the following building blocks. Make sure you URL-encode the filter expressions, which are shown here without URL-encoding to make them easier to read.

In filter expressions, the simplest json-pointer is a field of the JSON resource, such as userName or id. A json-pointer can also point to nested elements, as described in the JSON Pointer Internet-Draft:

Comparison expressions

Build filters using the following comparison expressions:

json-pointer eq json-value

Matches when the pointer equals the value, as in the following example:

$ curl \
 --user kvaughan:bribery \
 --cacert ca-cert.pem \
 --silent \
 "https://localhost:8443/api/users?_queryFilter=userName+eq+'babs@example.com'&_prettyPrint=true"

{
  "result" : [ {
    "_id" : "bjensen",
    "_rev" : "<revision>",
    "_schema" : "frapi:opendj:rest2ldap:posixUser:1.0",
    "_meta" : {
      "lastModified" : "<datestamp>"
    },
    "userName" : "babs@example.com",
    "displayName" : [ "Barbara Jensen", "Babs Jensen" ],
    "name" : {
      "givenName" : "Barbara",
      "familyName" : "Jensen"
    },
    "description" : "Original description",
    "manager" : {
      "_id" : "trigden",
      "_rev" : "<revision>"
    },
    "contactInformation" : {
      "telephoneNumber" : "+1 408 555 9999",
      "emailAddress" : "babs@example.com"
    },
    "uidNumber" : 1076,
    "gidNumber" : 1000,
    "homeDirectory" : "/home/bjensen",
    "groups" : [ {
      "_id" : "Carpoolers"
    } ]
  } ],
  "resultCount" : 1,
  "pagedResultsCookie" : null,
  "totalPagedResultsPolicy" : "NONE",
  "totalPagedResults" : -1,
  "remainingPagedResults" : -1
}
json-pointer co json-value

Matches when the pointer contains the value, as in the following example:

$ curl \
 --user kvaughan:bribery \
 --cacert ca-cert.pem \
 --silent \
 "https://localhost:8443/api/users?_queryFilter=userName+co+'jensen'&_fields=userName&_prettyPrint=true"

{
  "result" : [ {
    "_id" : "ajensen",
    "_rev" : "<revision>",
    "userName" : "ajensen@example.com"
  }, {
    "_id" : "gjensen",
    "_rev" : "<revision>",
    "userName" : "gjensen@example.com"
  }, {
    "_id" : "jjensen",
    "_rev" : "<revision>",
    "userName" : "jjensen@example.com"
  }, {
    "_id" : "kjensen",
    "_rev" : "<revision>",
    "userName" : "kjensen@example.com"
  }, {
    "_id" : "rjensen",
    "_rev" : "<revision>",
    "userName" : "rjensen@example.com"
  }, {
    "_id" : "tjensen",
    "_rev" : "<revision>",
    "userName" : "tjensen@example.com"
  } ],
  "resultCount" : 6,
  "pagedResultsCookie" : null,
  "totalPagedResultsPolicy" : "NONE",
  "totalPagedResults" : -1,
  "remainingPagedResults" : -1
}
json-pointer sw json-value

Matches when the pointer starts with the value, as in the following example:

$ curl \
 --user kvaughan:bribery \
 --cacert ca-cert.pem \
 --silent \
 "https://localhost:8443/api/users?_queryFilter=userName+sw+'ab'&_fields=userName&_prettyPrint=true"

{
  "result" : [ {
    "_id" : "abarnes",
    "_rev" : "<revision>",
    "userName" : "abarnes@example.com"
  }, {
    "_id" : "abergin",
    "_rev" : "<revision>",
    "userName" : "abergin@example.com"
  } ],
  "resultCount" : 2,
  "pagedResultsCookie" : null,
  "totalPagedResultsPolicy" : "NONE",
  "totalPagedResults" : -1,
  "remainingPagedResults" : -1
}
json-pointer lt json-value

Matches when the pointer is less than the value, as in the following example:

$ curl \
 --user admin:password \
 --cacert ca-cert.pem \
 --silent \
 "https://localhost:8443/api/users?_queryFilter=userName+lt+'ac'&_fields=userName&_prettyPrint=true"

{
  "result" : [ {
    "_id" : "abarnes",
    "_rev" : "<revision>",
    "userName" : "abarnes@example.com"
  }, {
    "_id" : "abergin",
    "_rev" : "<revision>",
    "userName" : "abergin@example.com"
  } ],
  "resultCount" : 2,
  "pagedResultsCookie" : null,
  "totalPagedResultsPolicy" : "NONE",
  "totalPagedResults" : -1,
  "remainingPagedResults" : -1
}
json-pointer le json-value

Matches when the pointer is less than or equal to the value, as in the following example:

$ curl \
 --user admin:password \
 --cacert ca-cert.pem \
 --silent \
 "https://localhost:8443/api/users?_queryFilter=userName+le+'ad'&_fields=userName&_prettyPrint=true"

{
  "result" : [ {
    "_id" : "abarnes",
    "_rev" : "<revision>",
    "userName" : "abarnes@example.com"
  }, {
    "_id" : "abergin",
    "_rev" : "<revision>",
    "userName" : "abergin@example.com"
  }, {
    "_id" : "achassin",
    "_rev" : "<revision>",
    "userName" : "achassin@example.com"
  } ],
  "resultCount" : 3,
  "pagedResultsCookie" : null,
  "totalPagedResultsPolicy" : "NONE",
  "totalPagedResults" : -1,
  "remainingPagedResults" : -1
}
json-pointer gt json-value

Matches when the pointer is greater than the value, as in the following example:

$ curl \
 --user admin:password \
 --cacert ca-cert.pem \
 --silent \
 "https://localhost:8443/api/users?_queryFilter=userName+gt+'wa'&_fields=userName&_prettyPrint=true"

{
  "result" : [ {
    "_id" : "wlutz",
    "_rev" : "<revision>",
    "userName" : "wlutz@example.com"
  } ],
  "resultCount" : 1,
  "pagedResultsCookie" : null,
  "totalPagedResultsPolicy" : "NONE",
  "totalPagedResults" : -1,
  "remainingPagedResults" : -1
}
json-pointer ge json-value

Matches when the pointer is greater than or equal to the value, as in the following example:

$ curl \
 --user admin:password \
 --cacert ca-cert.pem \
 --silent \
 "https://localhost:8443/api/users?_queryFilter=userName+ge+'va'&_fields=userName&_prettyPrint=true"

{
  "result" : [ {
    "_id" : "wlutz",
    "_rev" : "<revision>",
    "userName" : "wlutz@example.com"
  } ],
  "resultCount" : 1,
  "pagedResultsCookie" : null,
  "totalPagedResultsPolicy" : "NONE",
  "totalPagedResults" : -1,
  "remainingPagedResults" : -1
}
Presence expression

json-pointer pr matches any resource on which the json-pointer is present:

$ curl \
 --user kvaughan:bribery \
 --cacert ca-cert.pem \
 --silent \
 "https://localhost:8443/api/groups?_queryFilter=displayName+pr&_fields=displayName&_prettyPrint=true"

{
  "result" : [ {
    "_id" : "Accounting Managers",
    "_rev" : "<revision>",
    "displayName" : "Accounting Managers"
  }, {
    "_id" : "Directory Administrators",
    "_rev" : "<revision>",
    "displayName" : "Directory Administrators"
  }, {
    "_id" : "HR Managers",
    "_rev" : "<revision>",
    "displayName" : "HR Managers"
  }, {
    "_id" : "PD Managers",
    "_rev" : "<revision>",
    "displayName" : "PD Managers"
  }, {
    "_id" : "QA Managers",
    "_rev" : "<revision>",
    "displayName" : "QA Managers"
  } ],
  "resultCount" : 5,
  "pagedResultsCookie" : null,
  "totalPagedResultsPolicy" : "NONE",
  "totalPagedResults" : -1,
  "remainingPagedResults" : -1
}
Literal expressions

true matches any resource in the collection.

false matches no resource in the collection.

In other words, you can list all resources in a collection as in the following example:

$ curl \
 --user kvaughan:bribery \
 --cacert ca-cert.pem \
 --silent \
 "https://localhost:8443/api/groups?_queryFilter=true&_fields=_id&_prettyPrint=true"

{
  "result" : [ {
    "_id" : "Accounting Managers",
    "_rev" : "<revision>"
  }, {
    "_id" : "Directory Administrators",
    "_rev" : "<revision>"
  }, {
    "_id" : "HR Managers",
    "_rev" : "<revision>"
  }, {
    "_id" : "PD Managers",
    "_rev" : "<revision>"
  }, {
    "_id" : "QA Managers",
    "_rev" : "<revision>"
  } ],
  "resultCount" : 5,
  "pagedResultsCookie" : null,
  "totalPagedResultsPolicy" : "NONE",
  "totalPagedResults" : -1,
  "remainingPagedResults" : -1
}
Complex expressions

Combine expressions using boolean operators and, or, and ! (not), and by using parentheses (expression) with group expressions. The following example queries resources with last name Jensen and manager name starting with Sam:

$ curl \
 --user kvaughan:bribery \
 --cacert ca-cert.pem \
 --silent \
 "https://localhost:8443/api/users?_queryFilter=\
(name/familyName+co+'jensen'+and+manager/displayName+sw+'Sam')&_fields=name/familyName,manager/displayName&_prettyPrint=true"

{
  "result" : [ {
    "_id" : "bjense2",
    "_rev" : "<revision>",
    "name" : {
      "familyName" : "Jensen"
    },
    "manager" : {
      "displayName" : [ "Sam Carter", "Samantha Carter" ],
      "_id" : "scarter",
      "_rev" : "<revision>"
    }
  }, {
    "_id" : "jjensen",
    "_rev" : "<revision>",
    "name" : {
      "familyName" : "Jensen"
    },
    "manager" : {
      "displayName" : [ "Sam Carter", "Samantha Carter" ],
      "_id" : "scarter",
      "_rev" : "<revision>"
    }
  }, {
    "_id" : "tjensen",
    "_rev" : "<revision>",
    "name" : {
      "familyName" : "Jensen"
    },
    "manager" : {
      "displayName" : [ "Sam Carter", "Samantha Carter" ],
      "_id" : "scarter",
      "_rev" : "<revision>"
    }
  } ],
  "resultCount" : 3,
  "pagedResultsCookie" : null,
  "totalPagedResultsPolicy" : "NONE",
  "totalPagedResults" : -1,
  "remainingPagedResults" : -1
}

Notice the filters use the JSON pointers name/familyName and manager/displayName to identify the fields nested inside the name and manager objects.

Graph-Like Queries

The default REST to LDAP sample mapping defines references with resourcePath fields. When the REST to LDAP mapping defines references to other resources in this way, the mapping supports recursion. Client applications can use query filters that traverse a "graph" of resources.

The following example gets users whose manager belongs to the Directory Administrators group. The search is not indexed by default, so the directory superuser makes the request:

$ curl \
 --user admin:password \
 --cacert ca-cert.pem \
 --silent \
 "https://localhost:8443/api/users/?_queryFilter=/manager/groups/_id+eq+'Directory%20Administrators'&_fields=_id&_prettyPrint=true"

{
  "result" : [ {
    "_id" : "ashelton",
    "_rev" : "<revision>"
  }, {
    "_id" : "btalbot",
    "_rev" : "<revision>"
  }, {
    "_id" : "dakers",
    "_rev" : "<revision>"
  }, {
    "_id" : "dsmith",
    "_rev" : "<revision>"
  }, {
    "_id" : "eward",
    "_rev" : "<revision>"
  }, {
    "_id" : "gjensen",
    "_rev" : "<revision>"
  }, {
    "_id" : "hmiller",
    "_rev" : "<revision>"
  }, {
    "_id" : "jburrell",
    "_rev" : "<revision>"
  }, {
    "_id" : "jcampai2",
    "_rev" : "<revision>"
  }, {
    "_id" : "jfalena",
    "_rev" : "<revision>"
  }, {
    "_id" : "jvaughan",
    "_rev" : "<revision>"
  }, {
    "_id" : "kcarter",
    "_rev" : "<revision>"
  }, {
    "_id" : "mreuter",
    "_rev" : "<revision>"
  }, {
    "_id" : "newuser",
    "_rev" : "<revision>"
  }, {
    "_id" : "pworrell",
    "_rev" : "<revision>"
  }, {
    "_id" : "rbannist",
    "_rev" : "<revision>"
  }, {
    "_id" : "rdaugherty",
    "_rev" : "<revision>"
  }, {
    "_id" : "rschneid",
    "_rev" : "<revision>"
  }, {
    "_id" : "striplet",
    "_rev" : "<revision>"
  }, {
    "_id" : "tclow",
    "_rev" : "<revision>"
  }, {
    "_id" : "tmason",
    "_rev" : "<revision>"
  }, {
    "_id" : "tschmith",
    "_rev" : "<revision>"
  }, {
    "_id" : "tward",
    "_rev" : "<revision>"
  } ],
  "resultCount" : 23,
  "pagedResultsCookie" : null,
  "totalPagedResultsPolicy" : "NONE",
  "totalPagedResults" : -1,
  "remainingPagedResults" : -1
}

REST to LDAP translates such graph-like HTTP queries into a series of corresponding LDAP requests. Complex graph-like queries can have a significant server-side performance impact.

Paged Results

You can page through search results using the following query string parameters that are further described in Query:

  • _pagedResultsCookie=string

  • _pagedResultsOffset=integer

  • _pageSize=integer

The following example demonstrates how paged results are used:

# Request five results per page, and retrieve the first page:
$ curl \
 --user admin:password \
 --cacert ca-cert.pem \
 --silent \
 "https://localhost:8443/api/users?_queryFilter=true&_fields=userName&_pageSize=5&_prettyPrint=true"

{
  "result" : [ {
    "_id" : "abarnes",
    "_rev" : "<revision>",
    "userName" : "abarnes@example.com"
  }, {
    "_id" : "abergin",
    "_rev" : "<revision>",
    "userName" : "abergin@example.com"
  }, {
    "_id" : "achassin",
    "_rev" : "<revision>",
    "userName" : "achassin@example.com"
  }, {
    "_id" : "ahall",
    "_rev" : "<revision>",
    "userName" : "ahall@example.com"
  }, {
    "_id" : "ahel",
    "_rev" : "<revision>",
    "userName" : "ahel@example.com"
  } ],
  "resultCount" : 5,
  "pagedResultsCookie" : "<cookie>",
  "totalPagedResultsPolicy" : "NONE",
  "totalPagedResults" : -1,
  "remainingPagedResults" : -1
}

$ export COOKIE=$(cut -d \" -f 4 <(grep pagedResultsCookie \
 <(curl --cacert ca-cert.pem \
 --user admin:password \
 --silent \
 "https://localhost:8443/api/users?_queryFilter=true&_fields=userName&_pageSize=5&_prettyPrint=true")))

# Provide the cookie to request the next five results:
$ curl \
 --user admin:password \
 --cacert ca-cert.pem \
 --silent \
 "https://localhost:8443/api/users?_queryFilter=true&_fields=userName&_pageSize=5\
&_pagedResultsCookie=$COOKIE&_prettyPrint=true"

{
  "result" : [ {
    "_id" : "ahunter",
    "_rev" : "<revision>",
    "userName" : "ahunter@example.com"
  }, {
    "_id" : "ajensen",
    "_rev" : "<revision>",
    "userName" : "ajensen@example.com"
  }, {
    "_id" : "aknutson",
    "_rev" : "<revision>",
    "userName" : "aknutson@example.com"
  }, {
    "_id" : "alangdon",
    "_rev" : "<revision>",
    "userName" : "alangdon@example.com"
  }, {
    "_id" : "alutz",
    "_rev" : "<revision>",
    "userName" : "alutz@example.com"
  } ],
  "resultCount" : 5,
  "pagedResultsCookie" : "<new-cookie>",
  "totalPagedResultsPolicy" : "NONE",
  "totalPagedResults" : -1,
  "remainingPagedResults" : -1
}

# Request the tenth page of five results:
$ curl \
 --user admin:password \
 --cacert ca-cert.pem \
 --silent \
 "https://localhost:8443/api/users?_queryFilter=true&_fields=userName\
&_pageSize=5&_pagedResultsOffset=10&_prettyPrint=true"

{
  "result" : [ {
    "_id" : "ashelton",
    "_rev" : "<revision>",
    "userName" : "ashelton@example.com"
  }, {
    "_id" : "awalker",
    "_rev" : "<revision>",
    "userName" : "awalker@example.com"
  }, {
    "_id" : "awhite",
    "_rev" : "<revision>",
    "userName" : "awhite@example.com"
  }, {
    "_id" : "aworrell",
    "_rev" : "<revision>",
    "userName" : "aworrell@example.com"
  }, {
    "_id" : "bfrancis",
    "_rev" : "<revision>",
    "userName" : "bfrancis@example.com"
  } ],
  "resultCount" : 5,
  "pagedResultsCookie" : "<cookie>",
  "totalPagedResultsPolicy" : "NONE",
  "totalPagedResults" : -1,
  "remainingPagedResults" : -1
}

Notice the following features of the responses:

  • "remainingPagedResults" : -1 means that the number of remaining results is unknown.

  • "totalPagedResults" : -1 means that the total number of paged results is unknown.

  • "totalPagedResultsPolicy" : "NONE" means that result counting is disabled.

Server-Side Sort

You can use the _sortKeys parameter, described in Query, to request that the server sort the results it returns.

The following example sorts results by given name:

$ curl \
 --user admin:password \
 --cacert ca-cert.pem \
 --silent \
 "https://localhost:8443/api/users?_queryFilter=name/familyName+eq+'jensen'\
&_sortKeys=name/givenName&_fields=name&_prettyPrint=true"

{
  "result" : [ {
    "_id" : "ajensen",
    "_rev" : "<revision>",
    "name" : {
      "givenName" : "Allison",
      "familyName" : "Jensen"
    }
  }, {
    "_id" : "bjensen",
    "_rev" : "<revision>",
    "name" : {
      "givenName" : "Barbara",
      "familyName" : "Jensen"
    }
  }, {
    "_id" : "bjense2",
    "_rev" : "<revision>",
    "name" : {
      "givenName" : "Bjorn",
      "familyName" : "Jensen"
    }
  }, {
    "_id" : "gjensen",
    "_rev" : "<revision>",
    "name" : {
      "givenName" : "Gern",
      "familyName" : "Jensen"
    }
  }, {
    "_id" : "jjensen",
    "_rev" : "<revision>",
    "name" : {
      "givenName" : "Jody",
      "familyName" : "Jensen"
    }
  }, {
    "_id" : "kjensen",
    "_rev" : "<revision>",
    "name" : {
      "givenName" : "Kurt",
      "familyName" : "Jensen"
    }
  }, {
    "_id" : "user.5814",
    "_rev" : "<revision>",
    "name" : {
      "givenName" : "Mollie",
      "familyName" : "Jensen"
    }
  }, {
    "_id" : "user.19233",
    "_rev" : "<revision>",
    "name" : {
      "givenName" : "Molly",
      "familyName" : "Jensen"
    }
  }, {
    "_id" : "user.32652",
    "_rev" : "<revision>",
    "name" : {
      "givenName" : "Mommy",
      "familyName" : "Jensen"
    }
  }, {
    "_id" : "user.46071",
    "_rev" : "<revision>",
    "name" : {
      "givenName" : "Mona",
      "familyName" : "Jensen"
    }
  }, {
    "_id" : "user.59490",
    "_rev" : "<revision>",
    "name" : {
      "givenName" : "Monah",
      "familyName" : "Jensen"
    }
  }, {
    "_id" : "user.72909",
    "_rev" : "<revision>",
    "name" : {
      "givenName" : "Monica",
      "familyName" : "Jensen"
    }
  }, {
    "_id" : "user.86328",
    "_rev" : "<revision>",
    "name" : {
      "givenName" : "Moniek",
      "familyName" : "Jensen"
    }
  }, {
    "_id" : "user.99747",
    "_rev" : "<revision>",
    "name" : {
      "givenName" : "Monika",
      "familyName" : "Jensen"
    }
  }, {
    "_id" : "rjense2",
    "_rev" : "<revision>",
    "name" : {
      "givenName" : "Randy",
      "familyName" : "Jensen"
    }
  }, {
    "_id" : "rjensen",
    "_rev" : "<revision>",
    "name" : {
      "givenName" : "Richard",
      "familyName" : "Jensen"
    }
  }, {
    "_id" : "tjensen",
    "_rev" : "<revision>",
    "name" : {
      "givenName" : "Ted",
      "familyName" : "Jensen"
    }
  } ],
  "resultCount" : 17,
  "pagedResultsCookie" : null,
  "totalPagedResultsPolicy" : "NONE",
  "totalPagedResults" : -1,
  "remainingPagedResults" : -1
}

To sort in reverse order, use _sortKeys=-field.

To specify multiple sort keys, use a comma-separated list of fields.

The sort key fields that you specify must exist in the result entries.

The server must store and then sort the result set for your search. If you expect a large result set for your search, use paged results, described in Paged Results, to limit the impact on the server and get your results more quickly.

Copyright © 2010-2024 ForgeRock, all rights reserved.