Skip to main content
Skip table of contents

4. Document Search

Document Search

This scenario demonstrates how to search for documents in Circularo using various criteria and filters. The search functionality is powerful and flexible, allowing you to find documents based on metadata, workflow state, creation date, and many other attributes.

Key features:

  • Search for documents using multiple criteria

  • Filter documents based on metadata, workflow state, and user information

  • Sort search results by different fields

  • Paginate through search results with from/size parameters

Search Query Structure

Circularo's document search is built on ElasticSearch, providing a powerful query language for finding documents. Search queries can include:

  • Basic filters: Simple field-value matching

  • Nested queries: For searching within nested objects like workflow states or user information

  • Range queries: For date ranges, numeric values, and other range-based searches

  • Sorting: Control the order of returned results

  • Pagination: Limit the number of results and implement paging

The examples in this scenario demonstrate common search patterns. You can combine these patterns to create more complex queries tailored to your specific needs.

Step 1 - Basic search with pagination

This endpoint demonstrates the simplest form of document search, retrieving all documents the user has access to with basic pagination parameters.

  • The from parameter specifies the starting index for pagination (0-based)

  • The size parameter limits the number of results returned

  • Without additional filters, this search returns all accessible documents

Pagination is important for performance when dealing with large document collections. Always use appropriate from/size values to limit result sets.

Endpoint

CODE
POST /search

Request

JSON
POST /search?token=4dcef4DRwwMgss2tAbPqaIbjgqZks3rmQSGFGWSaLaSE1YeDtKPScKYMf4UkQi60

Content-Type: application/json

{
  "from": 0,
  "size": 100
}

Response

JSON
{
  "total": 1252,
  "results": [
    {
      "document": {
        "documentTitle": "Project Proposal",
        "documentId": "ceccdc09-2caf-4316-9de6-8b23825d02bf",
        ...
      }
    },
    ...
  ]
}

The response includes all documents the user has access to, limited by the pagination parameters.

  • The total field indicates the total number of matching documents

  • The results array contains the document data for the current page

  • Each result includes the document's metadata and content information

Step 2 - Search documents created by a specific user

This endpoint demonstrates how to search for documents created by a specific user using nested queries.

  • The esFilters array contains ElasticSearch filter objects

  • The nested query type is used to search within nested objects like user information

  • The term query matches exact values in the specified field

Nested queries are necessary when searching fields within nested objects in the document structure. The path parameter specifies which nested object to search within.

Endpoint

CODE
POST /search

Request

JSON
POST /search?token=4dcef4DRwwMgss2tAbPqaIbjgqZks3rmQSGFGWSaLaSE1YeDtKPScKYMf4UkQi60

Content-Type: application/json

{
  "esFilters": [
    {
      "nested": {
        "path": "createName",
        "query": {
          "term": {
            "createName.name": "derek.trotter@circularo.com"
          }
        }
      }
    }
  ],
  "size": 100
}

Response

JSON
{
  "total": 154,
  "results": [
    {
      "document": {
        "documentTitle": "Contract Agreement",
        "documentId": "5bc1e6c3-da29-4e65-a230-0f656a0bddb3",
        "user": {  //Note the \"createName\" property is returned as \"user\" in the response
          "name": "derek.trotter@circularo.com",
          ...
        },
        ...
      }
    }
  ]
}

The response includes only documents created by the specified user.

  • Each document in the results has a user field matching the search criteria

  • This type of search is useful for finding all documents created by a team member or colleague

You can combine this filter with other criteria to narrow down results further, such as finding documents created by a specific user within a date range.

Step 3 - Search documents awaiting action from a specific user

This endpoint demonstrates how to search for documents that are waiting for action from a specific user, such as approval or review.

  • Multiple nested queries are used to navigate the document structure

  • The bool query combines multiple conditions with logical operators

  • The filter clause requires all conditions to match

This type of search is particularly useful for building task lists or dashboards showing documents requiring attention from specific users.

Endpoint

CODE
POST /search

Request

JSON
POST /search?token=4dcef4DRwwMgss2tAbPqaIbjgqZks3rmQSGFGWSaLaSE1YeDtKPScKYMf4UkQi60

Content-Type: application/json

{
  "esFilters": [
    {
      "nested": {
        "path": "workflow",
        "query": {
          "nested": {
            "path": "workflow.waitingFor",
            "query": {
              "bool": {
                "filter": [
                  {
                    "term": {
                      "workflow.waitingFor.hasTurn": true
                    }
                  },
                  {
                    "nested": {
                      "path": "workflow.waitingFor.user",
                      "query": {
                        "term": {
                          "workflow.waitingFor.user.name": "mary.griffin@circularo.com"
                        }
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      }
    }
  ],
  "size": 100
}

Response

JSON
{
  "total": 17,
  "results": [
    {
      "document": {
        "documentTitle": "Quarterly Report",
        "documentId": "33686713-515c-40b1-bba1-f45e7c72fb56",
        "workflow": {
          "waitingFor": [
            {
              "hasTurn": true,
              "user": {
                "name": "mary.griffin@circularo.com",
                ...
              },
              ...
            }
          ],
          ...
        },
        ...
      }
    }
  ]
}

The response includes documents that are waiting for action from the specified user.

  • Each document in the results has a workflow state with the specified user in the waitingFor list

  • The hasTurn: true property indicates that it's this user's turn to take action

This query can be used to build a personalized task list showing documents requiring the user's attention.

Step 4 - Search documents by date range and type

This endpoint demonstrates how to search for documents of a specific type created before a certain date using range queries.

  • The type parameter filters documents by their metadata definition type

  • The range query type allows searching for values within a specified range

  • The lte (less than or equal) operator defines the upper bound of the range

  • ElasticSearch date math expressions like now-1M/M provide flexible date range options

Date math expressions are a powerful feature of ElasticSearch. For example, "now-1M/M" means "one month ago, rounded to the start of the month".

Endpoint

CODE
POST /search

Request

JSON
POST /search?token=4dcef4DRwwMgss2tAbPqaIbjgqZks3rmQSGFGWSaLaSE1YeDtKPScKYMf4UkQi60

Content-Type: application/json

{
  "type": "d_default",
  "fields": [
    {
      "type": "range",
      "field": "createDate",
      "value": {
        "lte": "now-1M/M"
      }
    }
  ],
  "size": 100
}

Response

JSON
{
  "total": 284,
  "results": [
    {
      "document": {
        "documentTitle": "Historical Report",
        "documentId": "24d2e519-f332-4ba8-b45a-8382b45ef6cd",
        "documentType": "d_default",
        "date": "2025-06-28T06:54:29.562Z",
        ...
      }
    }
  ]
}

The response includes documents of the specified type created before the given date.

  • Each document in the results matches both the type and date range criteria

  • This type of search is useful for finding historical documents or implementing archiving policies

Date math expressions in ElasticSearch are very flexible. You can use expressions like "now-1y" (one year ago), "now-1d" (yesterday), or "now/d" (start of today).

Step 5 - Search documents by workflow state and category with sorting

This endpoint demonstrates how to search for documents in specific workflow states and categories, with results sorted by creation date.

  • Multiple filter conditions are combined to narrow down results

  • The terms query matches documents where the field value is any of the specified values

  • The sort parameter controls the order of results

  • The order property specifies ascending (asc) or descending (desc) sort order

Sorting is important for presenting results in a meaningful order. You can sort by multiple fields to handle ties in the primary sort field.

Endpoint

CODE
POST /search

Request

JSON
POST /search?token=4dcef4DRwwMgss2tAbPqaIbjgqZks3rmQSGFGWSaLaSE1YeDtKPScKYMf4UkQi60

Content-Type: application/json

{
  "esFilters": [
    {
      "nested": {
        "path": "workflow",
        "query": {
          "terms": {
            "workflow.shareStateName": [
              "completed",
              "rejected",
              "expired",
              "cancelled"
            ]
          }
        }
      }
    },
    {
      "term": {
        "documentCategory": "NDA"
      }
    }
  ],
  "sort": [
    {
      "createDate": {
        "order": "desc"
      }
    }
  ],
  "size": 100
}

Response

JSON
{
  "total": 762,
  "results": [
    {
      "document": {
        "documentTitle": "Non-Disclosure Agreement",
        "documentId": "95ab440e-1529-4abf-8ea3-4153d9349e11",
        "documentCategory": "NDA",
        "workflow": {
          "shareStateName": "completed",
          ...
        },
        ...
      }
    },
    {
      "document": {
        "documentTitle": "Confidentiality Agreement",
        "documentId": "e3e12203-2777-4e51-9805-7333ccfc482c",
        "documentCategory": "NDA",
        "workflow": {
          "shareStateName": "completed",
          ...
        },
        ...
      }
    }
  ]
}

The response includes documents matching the workflow state and category criteria, sorted by creation date in descending order.

  • Each document in the results matches both the workflow state and category criteria

  • Results are ordered with the most recently created documents first

  • This type of search is useful for finding completed documents of a specific category

You can sort by multiple fields by adding more objects to the sort array. The secondary sort field will be used when the primary sort field values are equal.


Document Search Summary

The search functionality in Circularo provides powerful capabilities for finding documents based on various criteria. This scenario demonstrated several common search patterns that you can adapt and combine for your specific needs.

Key Concepts

  • ElasticSearch Queries: Circularo's search is built on ElasticSearch, providing a flexible and powerful query language

  • Nested Queries: Used for searching within nested objects like workflow states or user information

  • Range Queries: Allow searching for values within specified ranges, particularly useful for dates

  • Sorting and Pagination: Control the order and number of results returned

Common Search Patterns

  • Basic Search: Retrieve all accessible documents with pagination

  • Creator Search: Find documents created by a specific user

  • Workflow Search: Find documents in specific workflow states or awaiting action

  • Date Range Search: Find documents created within a specific time period

  • Category Search: Find documents of specific categories or types

Example Implementation

See our OpenAPI documentation to learn about the full set of API endpoints and parameters.

Please use proper exception handling and function decomposition in your own code. The code is provided for illustrative purposes only and is not intended for production use.

JAVASCRIPT
// Document search examples
const URL = "https://sandbox.circularo.com";
const API_PATH = "/api/v1";
const TOKEN = "YOUR_AUTH_TOKEN"; // Obtained from login or API key

try {
    // Example 1: Basic search with pagination
    const basicSearchResponse = await fetch(`${URL}${API_PATH}/search?token=${TOKEN}`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            from: 0,
            size: 20
        })
    });
    const basicSearchResults = await basicSearchResponse.json();
    console.log(`Found ${basicSearchResults.total} documents in total`);

    // Example 2: Search documents created by a specific user
    const creatorSearchResponse = await fetch(`${URL}${API_PATH}/search?token=${TOKEN}`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            esFilters: [{
                nested: {
                    path: "createName",
                    query: {
                        term: {
                            'createName.name': "john.doe@example.com"
                        }
                    }
                }
            }],
            size: 100
        })
    });
    const creatorSearchResults = await creatorSearchResponse.json();

    // Example 3: Search documents awaiting my action
    const myEmail = "my.email@example.com";
    const taskSearchResponse = await fetch(`${URL}${API_PATH}/search?token=${TOKEN}`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            esFilters: [{
                nested: {
                    path: "workflow",
                    query: {
                        nested: {
                            path: "workflow.waitingFor",
                            query: {
                                bool: {
                                    filter: [{
                                        term: {
                                            'workflow.waitingFor.hasTurn': true
                                        }
                                    }, {
                                        nested: {
                                            path: "workflow.waitingFor.user",
                                            query: {
                                                term: {
                                                    'workflow.waitingFor.user.name': myEmail
                                                }
                                            }
                                        }
                                    }]
                                }
                            }
                        }
                    }
                }
            }],
            size: 100
        })
    });
    const taskSearchResults = await taskSearchResponse.json();

    // Example 4: Search documents created in the last 30 days
    const recentDocumentsResponse = await fetch(`${URL}${API_PATH}/search?token=${TOKEN}`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            fields: [{
                type: "range",
                field: "createDate",
                value: {
                    gte: "now-30d/d"
                }
            }],
            sort: [{
                createDate: {
                    order: "desc"
                }
            }],
            size: 100
        })
    });
    const recentDocuments = await recentDocumentsResponse.json();

} catch (error) {
    console.error('Error searching documents:', error.message);
}

The search API is powerful but can be complex. Start with simple queries and gradually add complexity as needed.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.