Flowable Enterprise Documentation

Flowable Enterprise Documentation

  • How to
  • Modeler
  • Administrator
  • Developer
  • User

›Flowable How-To Guides

Flowable How-To Guides

  • Flowable How-To Guides
  • How-To: Initialize Variables Task
  • How-To: Generate Document Task
  • How-To: Building an Audit Stream
  • How-To: The Rich Text Component
  • How-To: Dynamic Document Gallery
  • How-To: Getting Started with Channels and Events
  • How-To: Receive Email
  • How-To: Custom Search Query
  • How To: Advanced search
  • How To: Add Task Listeners Automatically
  • How-To: Basic Performance Tuning

How-To: Custom Search Query

Target audience: Developers

Introduction

Sometimes, users will want to see slightly different data or data visualised in a different way than the default views. These default views, when you authenticate, show the instances (e.g. cases, processes and tasks) that you have permission on.

There is also an API with some default filters available to search work items (i.e. root case or process instances) or tasks with the filterId open, all, completed, and mine. However, sometimes there is no filter available which is giving you exactly what you would like to have.

In this case, Flowable offers you to create your own Elasticsearch query. In this howto, we'll show a basic example how such a custom query can be built.

There is also an advanced howto on indexing and search that covers advanced topics.

Creating an Own Query

Flowable has the capability to create your own queries, which is a powerful feature, and you should definitely check out the documentation on indexing to get a full overview of all additional possibilities with Flowable.

As an example, let's assume that we would like to search for all case instances with a given assignee.

Looking at our index (it's always a good idea to do this, this can be done by e.g. doing a call with Postman on http://localhost:9200/case-instances/_search when running Elasticsearch on your local machine), we see for example the following structure:

{
  "_index": "case-instances-20210213-2243-04-81784229",
  "_type": "_doc",
  "_id": "CAS-a3260edf-7453-11eb-9d47-1281fbfbc379",
  "_version": 1,
  "_seq_no": 0,
  "_primary_term": 2,
  "found": true,
  "_source": {
    "__flowableVersion": 8,
    "caseDefinitionKey": "testCaseModel",
    "caseDefinitionName": "Test Case Model",
    "startUserId": "admin",
    "startTime": "2021-02-21T14:46:53.322Z",
    "id": "CAS-a3260edf-7453-11eb-9d47-1281fbfbc379",
    "state": "active",
    "involvedUsers": [
      "admin"
    ],
    "variables": [
      {
        "id": "VAR-a326d231-7453-11eb-9d47-1281fbfbc379",
        "name": "initiator",
        "type": "string",
        "scopeId": "CAS-a3260edf-7453-11eb-9d47-1281fbfbc379",
        "scopeType": "cmmn",
        "scopeDefinitionId": "CAS-95dd54ea-7453-11eb-9d47-1281fbfbc379",
        "scopeDefinitionKey": "testCaseModel",
        "rawValue": "admin",
        "textValue": "admin",
        "textValueKeyword": "admin"
      }
    ],
    "caseDefinitionId": "CAS-95dd54ea-7453-11eb-9d47-1281fbfbc379",
    "caseDefinitionCategory": "http://flowable.org/cmmn",
    "identityLinks": [
      {
        "id": "IDL-a3276e72-7453-11eb-9d47-1281fbfbc379",
        "type": "assignee",
        "userId": "admin"
      },
      {
        "id": "IDL-a3359f47-7453-11eb-9d47-1281fbfbc379",
        "type": "participant",
        "userId": "admin"
      },
      {
        "id": "IDL-a3276e73-7453-11eb-9d47-1281fbfbc379",
        "type": "owner",
        "userId": "admin"
      },
      {
        "id": "IDL-a32635f0-7453-11eb-9d47-1281fbfbc379",
        "type": "starter",
        "userId": "admin"
      }
    ],
    "tenantId": "default"
  }
}

We can see that our indexed document will have a nested identityLinks object. We can use this part of the document to search for our cases. There must be an entry with the userId equal to our assignee we are searching for, and the type of the field assignee. This can be easily achieved with the following Elasticsearch query:

{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "identityLinks",
            "query": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "identityLinks.type": "assignee"
                    }
                  },
                  {
                    "term": {
                      "identityLinks.userId": "admin"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

Of course, this query would only find the cases with the assignee admin. We can replace admin with whatever we want to search for.

Using the Query in Flowable

Going against Elasticsearch gives you now a different document structure than what you might be used to from Flowable. Also, you are accessing Flowables Elasticsearch without going through Flowable.

This means that you are losing the out-of-the-box access control which is built into Flowable. To avoid that, Flowable provides the possibility to query with your custom queries.

To create your own query you need to put a document on your classpath in the directory com/flowable/indexing/mapping-extension/custom/ with the filename suffix .json.

In this document, you have the following structure:

{
  "key": "the-key-of-this-query",
  "type": "query",
  "sourceIndex": "case-instances",
  "version": 1,
  "parameters": {...},
  "customFilter": {...}
} 

The key needs to be a system-unique identiefier for your query. You can use the key to describe the query with a name which can be used later to perform the search.

This query will use the case-instances index, since we specified that as sourceIndex.

The field parameters allows us to specify custom parameters a user can pass in.

Inside customFilter, we can specify our query.

Now, using our Elasticsearch query and combining this with our template structure, we can create a file com/flowable/indexing/mapping-extension/custom/case-by-assignee.json on the classpath and put the following content inside:

{
  "key": "case-by-assignee",
  "type": "query",
  "sourceIndex": "case-instances",
  "version": 1,
  "parameters": {
    "assignee": "string"
  },
  "customFilter": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "identityLinks",
            "query": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "identityLinks.type": "assignee"
                    }
                  },
                  {
                    "term": {
                      "identityLinks.userId": "{assignee}"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

The userId is now {assignee}, which is exactly the same name as we have specified as a parameter.

To make it available you need to restart your Flowable application. Once this is done, we can execute a REST request to use our query: /platform-api/search/query-case-instances/query/case-by-assignee?assignee=admin.

As a result, we should see all case instances with the assignee admin.

Further reading

This article has only shown a small part of the Elasticsearch integration. In addition to executing queries, it's also possible to extract variables, write your own content into the index, and enhance the output result. As a further resource, it's recommended to look into the Work Indexing documentation and the Advanced search How-To.

← How-To: Receive EmailHow To: Advanced search →
  • Introduction
  • Creating an Own Query
  • Using the Query in Flowable
  • Further reading
Flowable Enterprise Documentation
Documentation
UsersModelersAdministratorsDevelopers
Community
Enterprise ForumEnterprise BlogOpen Source ForumOpen Source Blog
Follow @FlowableGroup
More
DisclaimerPoliciesGitHubStar
Copyright © 2021 Flowable AG