Search

Using the API

@workertown/search provides a text search engine via a REST API - think of it as a self-hosted Algolia or ElasticSearch... just without the front-end.

The following assumes you are using the default routing configuration. If you are using a custom routing configuration, you will need to adjust the URL paths accordingly.


Documents

Indexing a document

You can index a document via a PUT request to the /v1/docs/:id endpoint, where :id is the unique ID of the document you are indexing.

curl -X PUT \
  -H "Content-Type: application/json" \
  -d '{"tenant": "test-tenant", "index": "test-index", "data": {"title": "Hello world", "content": "This is a test document"}}' \
  https://search.example.com/v1/docs/1

You must provide a tenant and index property in the request body - if you do not intend to search/suggest across multiple tenants/indexes, you can use a "default" value for both and use it in all requests.

data can be any JSON object you want - it has no predefined structure. Any string fields on the object will be accessible via searches and suggestions, although you can (and should) narrow that down when performing a search/suggestion.

You can optionally tag a document by providing a tags property on the request body, which is an array of string values.

curl -X PUT \
  -H "Content-Type: application/json" \
  -d '{"tenant": "test-tenant", "index": "test-index", "data": {"title": "Hello world", "content": "This is a test document"}, "tags": ["test", "other"]}' \
  https://search.example.com/v1/docs/1

You will receive a 200 OK response if the document was successfully indexed.

{
  "status": 200,
  "success": true,
  "data": {
    "id": "1",
    "tenant": "test-tenant",
    "index": "test-index",
    "data": {
      "title": "Hello world",
      "content": "This is a test document"
    },
    "tags": ["test", "other"],
    "createdAt": "2023-08-06T18:35:22.471Z",
    "updatedAt": "2023-08-06T18:51:32.428Z"
  }
}

Getting a document

You can get a document via a GET request to the /v1/docs/:id endpoint, where :id is the unique ID of the document you are getting.

curl -X GET \
  https://search.example.com/v1/docs/1

You will receive a 200 OK response if the document was successfully retrieved.

{
  "status": 200,
  "success": true,
  "data": {
    "id": "1",
    "tenant": "test-tenant",
    "index": "test-index",
    "data": {
      "title": "Hello world",
      "content": "This is a test document"
    },
    "tags": ["test", "other"],
    "createdAt": "2023-08-06T18:35:22.471Z",
    "updatedAt": "2023-08-06T18:51:32.428Z"
  }
}

Updating a document

Indexing a document is performed as an "upsert", so therefore you can update a document via the indexing endpoint.

Deleting a document

You can delete a document via a DELETE request to the /v1/docs/:id endpoint, where :id is the unique ID of the document you are deleting.

curl -X DELETE \
  https://search.example.com/v1/docs/1

You will receive a 200 OK response if the document was successfully deleted.

{
  "status": 200,
  "success": true,
  "data": {
    "id": "1",
  }
}

Searching

You can search for documents via a GET request to the /v1/search/:tenant/:index endpoint, where :tenant is the name of the tenant you are searching within, and :index is the name of the index you are searching within.

curl -X GET \
  -H "Content-Type: application/json" \
  https://search.example.com/v1/search/test-tenant/test-index?term=test&field=content

index is optional, and if omitted the search will be performed over all of the tenants indexes. You must provide a term query parameter in the request URL, which is the search term you are searching for.

You will receive a 200 OK response if the search was successful.

{
  "status": 200,
  "success": true,
  "data": [
    {
      "id": "1",
      "document": {
        "id": "1",
        "tenant": "test-tenant",
        "index": "test-index",
        "data": {
          "title": "Hello world",
          "content": "This is a test document"
        },
        "tags": [
          "test"
        ],
        "createdAt": "2023-08-06T18:35:22.471Z",
        "updatedAt": "2023-08-06T18:51:32.428Z"
      },
      "score": 0.4315231086776713,
      "terms": [
        "test"
      ],
      "match": {
        "test": [
          "content"
        ]
      }
    }
  ],
  "pagination": {
    "hasNextPage": false,
    "endCursor": "MQ=="
  }
}

score is the relevancy score of the document, and terms is an array of the terms that matched the document. match is an object of the terms that matched the document, and the fields that matched the term.

You can optionally set fuzzy matching on the search by providing a fuzzy query parameter in the request URL, which is a float value, e.g. 0.5. If the fuzzy parameter is not provided, fuzzy matching is disabled by default.

curl -X GET \
  -H "Content-Type: application/json" \
  https://search.example.com/v1/search/test-tenant/test-index?term=test&field=content&fuzzy=0.5

You can optionally set prefix matching on the search by providing a prefix query parameter in the request URL, which is a boolean value indicated by 1 or true for on, or 0 or false for off. If the prefix parameter is not provided, prefix matching is disabled by default.

Prefix matching will ensure that the search term is matched at the start of the field value(s).

curl -X GET \
  -H "Content-Type: application/json" \
  https://search.example.com/v1/search/test-tenant/test-index?term=test&field=content&prefix=1

You can optionally set exact matching on the search by providing an exact query parameter in the request URL, which is a boolean value indicated by 1 or true for on, or 0 or false for off. If the exact parameter is not provided, exact matching is disabled by default.

Exact matching will ensure that the search term is matched exactly to the field value(s).

curl -X GET \
  -H "Content-Type: application/json" \
  https://search.example.com/v1/search/test-tenant/test-index?term=test&field=content&exact=1

Pagination

You can optionally set a limit to the number of results to be returned by a search with the limit query parameter. The default limit is 100.

curl -X POST \
  -H "Content-Type: application/json" \
  https://search.example.com/v1/search/test-tenant/test-index?term=test&field=content&limit=10

A successful response will contain a pagination object, which contains hasNextPage and endCursor properties. hasNextPage is a boolean value indicating if there are more results to be returned, and endCursor is a unique cursoe to use in subsequent search requests using the after query parameter.

curl -X POST \
  -H "Content-Type: application/json" \
  https://search.example.com/v1/search/test-tenant/test-index?term=test&field=content&limit=10&after=MQ==

Suggestions

You can get suggestions for a search term via a GET request to the /v1/suggest/:tenant/:index endpoint, where :tenant is the name of the tenant you are searching within, and :index is the name of the index you are searching within.

curl -X GET \
  -H "Content-Type: application/json" \
  https://search.example.com/v1/suggest/test-tenant/test-index?term=test&field=content

index is optional, and if omitted the suggestions will be performed over all of the tenant's indexes. You must provide a term query parameter in the request URL, which is the search term you are searching for.

You will receive a 200 OK response if the suggestions were successful.

{
  "status": 200,
  "success": true,
  "data": [
    {
      "suggestion": "test",
      "terms": [
        "test"
      ],
      "score": 0.4315231086776713
    }
  ]
}

suggestion is the suggested term, terms is an array of the terms that matched the suggestion, and score is the relevancy score of the suggestion.

Fuzzy suggestions

Suggestions can be fuzzy matched in the same way as search.

Prefix suggestions

Suggestions can be prefix matched in the same way as search.

Exact suggestions

Suggestions can be exact matched in the same way as search.


Tags

Get tags

You can see a list of tags registered to your documents via a GET request to the /v1/tags endpoint.

curl -X GET \
  -H "Content-Type: application/json" \
  https://search.example.com/v1/tags

You will receive a 200 OK response if the tags were successfully retrieved.

{
  "status": 200,
  "success": true,
  "data": [
    "test"
  ]
}

This endppoint will return tags across all tenants/indexes, so is only intended for overall tag "management". If you would like to power tag suggestion interfaces, you can place a _tags field on your document as a space-delimited string of the tags for the document, and then perform a suggestion request against the _tags field.


Admin

Info

You can send a GET request to the /v1/admin/info endpoint to get the currently active configuration for your service. This is useful for debugging in live-like environments.

curl -X GET \
  -H "Content-Type: application/json" \
  https://search.example.com/v1/admin/info

You will receive a 200 OK response if the config was successfully retrieved.

{
  "status": 200,
  "success": true,
  "data": {
    "auth": {
      "apiKey": {
        "env": {
          "apiKey": "SEARCH_API_KEY"
        }
      },
      "basic": {
        "env": {
          "username": "SEARCH_USERNAME",
          "password": "SEARCH_PASSWORD"
        }
      },
      "jwt": {
        "env": {
          "jwksUrl": "SEARCH_JWKS_URL",
          "secret": "SEARCH_JWT_SECRET",
          "audience": "SEARCH_JWT_AUDIENCE",
          "issuer": "SEARCH_JWT_ISSUER"
        }
      }
    },
    "endpoints": {
      "v1": {
        "admin": "/v1/admin",
        "documents": "/v1/docs",
        "search": "/v1/search",
        "suggest": "/v1/suggest",
        "tags": "/v1/tags"
      },
      "public": "/"
    },
    "env": {
      "cache": "SEARCH_CACHE",
      "db": "SEARCH_DB"
    },
    "search": {
      "scanRange": 1000,
      "stopWords": [
          //...
      ]
    }
  }
}

Migrate

You can send a POST request to the /v1/admin/migrate endpoint to run the migrations required for your storage adapter to keep your database up to date.

curl -X POST \
  -H "Content-Type: application/json" \
  https://search.example.com/v1/admin/migrate

You will receive a 200 OK response if the migrations were successfully run.

{
  "status": 200,
  "success": true,
  "data": [
    {
      "migrationName": "1688823193041_add_initial_tables_and_indexes",
      "direction": "Up",
      "status": "Success"
    }
  ]
}

If any errors occur during the migration, you will receive a 500 Internal Server Error response, which will include the error as well as the details for any successful migrations that were run. If no migrations were run, data will be null.

{
  "status": 500,
  "success": false,
  "data": [
    //...
  ],
  "error": "..."
}

Public

Health

You can send a GET request to the /health endpoint to see if the service is healthy.

curl -X GET \
  -H "Content-Type: application/json" \
  https://search.example.com/health

If the service is running, you should receive a 200 OK response.

{
  "status": 200,
  "success": true,
  "data": "OK"
}

Open API v3

You can send a GET request to the /open-api.json endpoint to see the OpenAPI v3 specification for the service.

curl -X GET \
  -H "Content-Type: application/json" \
  https://search.example.com/open-api.json

You will receive a 200 OK response if the specification was successfully retrieved.

{
  "openapi": "3.0.0",
  "info": {
    "version": "1.0.0",
    "title": "Workertown Search",
    "license": {
      "name": "MIT"
    }
  },
  "servers": [
    {
      "url": "..."
    }
  ],
  "paths": {
    //...
  },
  "components": {
    //...
  }
}
Previous
Search Introduction

See a problem with this page? Submit an issue