Customizing Seeker: Indexing and Searching Custom Objects

In previous posts, we’ve covered the basics of Seeker, along with searching custom attributes of an object (such as case.x_notes).

Continuing on, lets look at how to index and search custom objects.

In our environment, we keep track of the software license keys that we send to our customers, and we do this in our Dovetail system.

This is an entirely custom object, so this will make a great example.

The License Key Table

Using BOLT, we can quickly see what this table looks like:


We need to know the database table information so we can modify the documentSpecifications.xml file.


Modify the documentSpecifications.xml file

Seek.exe is the application that performs the actual indexing. The documentSpecifications.xml is the configuration file that seek.exe uses so that it knows what to index.

The documentSpecifications.xml file consists of many dovetailDocumentSpecifications. For example, there is a specification for case, one for subcase, one for solution, etc.

We’ll create a new dovetailDocumentSpecification for the license keys:

        <identification displayName="license" table="fc_license_key" idColumnName="objid"/>
        <documentSelectionCriteria><![CDATA[creation_date > ${lastIndexUpdate} ]]></documentSelectionCriteria>

            Site: <path>fc_license_key2site:name</path>, Product(s): <path>product</path>
        <customField title="site">
        <customField title="product">

What this tells Seeker is that we want to index the fc_license_key table.

When searching, the <contents> section defines that the following columns should be searched:

  • product
  • comments
  • license_key
  • site name (from the related site table)

When the search results are returned, the <title> and the <summary> data will be returned in the result set.

Notice that the <title> element uses a mix of data from the database (site name, product), as well as some static text ("Site:" and "Product:").

The <customFields> elements allow us to perform a search directly on those specific fields. We’ll show this in a bit.


Now that we’ve modified the documentSpecifications.xml file, we can run seek.exe, which will index the data.

The documentSelectionCriteria is used to tell seek.exe which objects to index. In our case:

creation_time > ${lastIndexUpdate}

This means that any license keys created since the last time seek.exe was run will be indexed.

Now, simply run seek.exe –index, and all of the license keys will be indexed.


We can now execute searches. In this scenario, we’ll be using  Dovetail Agent.

Search using a site name:


Search using a product name:


Search the comments:



Search Specific Fields

Because we set up <customFields> elements in the XML file, we can perform a search directly on those specific fields.

Search only the site data:


Search only the product data:



Displaying the License Key Page From the Client

Obviously, we want the user to be able to click on one of the results and open the appropriate page. In this case, we want to open the License key page.

In Dovetail Agent, when a search result is clicked, the OpenObjectById function is called. Typically, this function is called such as:

OpenObjectById(‘12345’, ‘case’);

which is used to open the case page for a case with an ID Number of 12345.

For license keys, we don’t have an Id number, we just have an objid. That makes it trivial. We’ll simply modify this OpenObjectById function to open the license window:

if (objectType == ‘license’){
    OpenLicenseWindow(0, id);

And up pops our license key window:



Hiding the Id in Search Results Page

In Dovetail Agent, the default search result page includes the Id number in each result listing, for example Case 1234, Solution 76, Subcase 54-2, etc.

Like this:


As is, the license keys would show the objids like this:


As mentioned earlier, license keys don’t have an Id, so the objid is used. But we really don’t want to show that to the end users.

A quick modification to the DisplaySearchResult function in search_utility.asp:

if (searchResult.Domain != "license"){   
    rw(PrettyObjectName(‘&nbsp’ + searchResult.Id));

This eliminates the Id number from the search results for license keys:


Kevin and I were discussing how we could enhance Seeker to better handle scenarios like this, without having to do custom code in the search result consumer code. We’re kicking around some ideas to make this easier.


And there you have it – searching custom objects.

Hope this helps.

Rock on.