---
title: Search or query script
description: Connectors continue to be released outside the IDM release. For the latest documentation, refer to the OpenICF documentation.
component: pingidm
version: 7.2
page_id: pingidm:connector-dev-guide:scripts/script-search
canonical_url: https://docs.pingidentity.com/pingidm/7.2/connector-dev-guide/scripts/script-search.html
section_ids:
  returning_search_results: Returning search results
---

# Search or query script

|   |                                                                                                                                                                                   |
| - | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | Connectors continue to be released outside the IDM release. For the latest documentation, refer to the [OpenICF documentation](https://docs.pingidentity.com/openicf/index.html). |

A search script searches for one or more objects on the external resource. Connectors that do not support searches should throw an `UnsupportedOperationException`.

A sample search script for an SQL database is provided in `openidm/samples/scripted-sql-with-mysql/tools/SearchScript.groovy`.

* Input variables

  The following variables are available to the search script:

  * configuration

    A handler to the connector's configuration object.

  * options

    A handler to the Operation Options.

  * operation

    An OperationType that corresponds to the action (`SEARCH`).

  * objectClass

    The object class to search, such as `__ACCOUNT__` or `__GROUP__`.

  * filter

    The OpenICF native Query filter for this operation.

  * query

    A Map representation of the native Query filter that is easy to process.

    Provides a convenient way to access the query filter parameter. For example:

    ```none
    query = [ operation: "CONTAINS", left: attribute, right: "value", not: true/false ]
     query = [ operation: "ENDSWITH", left: attribute, right: "value", not: true/false ]
     query = [ operation: "STARTSWITH", left: attribute, right: "value", not: true/false ]
     query = [ operation: "EQUALS", left: attribute, right: "value", not: true/false ]
     query = [ operation: "GREATERTHAN", left: attribute, right: "value", not: true/false ]
     query = [ operation: "GREATERTHANOREQUAL", left: attribute, right: "value", not: true/false ]
     query = [ operation: "LESSTHAN", left: attribute, right: "value", not: true/false ]
     query = [ operation: "LESSTHANOREQUAL", left: attribute, right: "value", not: true/false ]
     query = null : then we assume we fetch everything

     // AND and OR filter - embed these left/right queries:
     query = [ operation: "AND", left: query1, right: query2 ]
     query = [ operation: "OR", left: query1, right: query2 ]
    ```

    For example, the equality query filter `"sn == Smith"` would be represented by the following query Map:

    ```none
    [ operation: "EQUALS", left: "sn", right: "Smith", not: false ]
    ```

  * handler

    A Closure handler for processing the search results.

  * log

    A logger instance for the connector.

* Returns

  Optionally, the script can return a search result. The result can be be returned as a `SearchResult` object or as a `String` that represents the `pagedResultsCookie` to be used for the next paged results.

## Returning search results

In a search operation, a result handler (callback) is passed to the script to return the results one by one. The handler must be called for every query result. The handler variable that is passed to the script is a `Groovy Closure`. You can call the handler in the following ways:

* Using an OpenICF `ConnectorObject` object.

  You can use the `ConnectorObjectBuilder` to build this object. For example:

  ```groovy
  def builder = new ConnectorObjectBuilder()
   builder.setUid(uidValue)
   builder.setName(nameValue)
   builder.setObjectClass(ObjectClass.ACCOUNT)
   builder.addAttribute("sn", snValue)

   // Call the handler with the ConnectorObject object
   handler builder.build()
  ```

* Using a Groovy Closure.

  In this case the Closure delegates calls to a specific Object that implements these calls. For example:

  ```groovy
  handler {           // The handler parameter here is a Closure
       uid uidValue    // (mandatory), the method resolution for 'uid' is delegated to the Object
                       // handling the Closure. This is the OpenICF __UID__
       id nameValue    // (mandatory), the method resolution for 'id' is delegated to the Object
                       // handling the Closure. This is the OpenICF __NAME__
       attribute "sn", snValue // (optional), the method resolution for 'id' is delegated to the
                              //  Object handling the Closure
       // attribute <attribute2Name>, <attribute2Value>
       // etc...
   }
  ```

  In the following example, the handler is called within a loop to return all the results of a query:

  ```groovy
   for (user in userList) {
       handler {
                   uid user.userName
                   id user.userName
                   user.attributes.each(){ key,value -> attribute key, value }
               }
   }
  ```
