Search Engine

Elasticsearch job data feed

Full-text and geo search over live jobs, mapping included.

Elasticsearch is where a job feed stops being a table and becomes a search index. Jobo creates the index with an explicit mapping rather than letting dynamic mapping guess — analyzed text on the fields you search, keywords on the fields you filter and aggregate, and a geo_point coordinates field on nested locations, so radius search works from the first push without a reindex. Documents are keyed on the Jobo job ID, so the 15-minute incremental sync updates in place, and because it is a document destination you can attach a pipeline to reshape jobs before they land.

Sync
Incremental, every 15 min
Deduplication
Upsert on job ID
Pipelines
Supported
Credentials
AES-256 at rest

Connection configuration

The fields Jobo collects to reach your Elasticsearch instance.

endpointstringrequired

Full server URL including protocol (https://my-cluster.es.amazonaws.com).

auth_methodselectrequired

Authentication method: basic, api_key, or none.

usernamestring

Required for Basic auth. Write-access user.

passwordstring

Required for Basic auth. Encrypted at rest.

api_key_idstring

Required for API Key auth. Key ID from Elasticsearch.

api_key_secretstring

Required for API Key auth. Encrypted at rest.

index_namestring

Target index name. Defaults to "jobs". Auto-created.

Elasticsearch config
{
  "endpoint": "https://my-cluster.es.amazonaws.com",
  "auth_method": "basic",
  "username": "elastic",
  "password": "••••••••",
  "index_name": "jobs"
}

How to sync jobs to Elasticsearch

One-time setup. After this, the feed maintains itself.

  1. 1

    Create a write-scoped credential

    Jobo needs to create the index, write documents, and read back index metadata. On Elastic Cloud or a self-managed cluster, POST to /_security/api_key with a role descriptor limited to the target index instead of handing over the elastic superuser. The response returns id and api_key, which map to the api_key_id and api_key_secret fields. Basic auth is fine too, as long as it is a dedicated user.

    json
    {
      "name": "jobo-feed",
      "role_descriptors": {
        "jobo_writer": {
          "indices": [
            {
              "names": ["jobs"],
              "privileges": ["create_index", "write", "view_index_metadata"]
            }
          ]
        }
      }
    }
  2. 2

    Point the feed at a dedicated index

    index_name defaults to jobs and the index is created on the first push. Force resync deletes and recreates that index before repopulating it, so it must be one nothing else owns — not an index your application writes to, and not one shared with a second feed.

  3. 3

    Enter the endpoint and authenticate

    endpoint takes the full URL including protocol, plus the port when it is non-standard. Choose basic and fill username and password, api_key and fill both key fields, or none for a cluster running with security disabled. Every secret is encrypted at rest with AES-256. Confirm the cluster answers on that URL before you save.

    bash
    curl -u elastic:password "https://my-cluster.es.amazonaws.com/_cluster/health?pretty"
  4. 4

    Search it, geo filters included

    Because Jobo installs the mapping, locations.coordinates is a real geo_point and a distance filter works against the very first push. Every document also carries a _jobo_synced_at stamp, which is how the feed finds and removes listings that have disappeared upstream.

    json
    {
      "query": {
        "bool": {
          "must": [{ "match": { "title": "backend engineer" } }],
          "filter": [
            {
              "geo_distance": {
                "distance": "25km",
                "locations.coordinates": { "lat": 52.37, "lon": 4.89 }
              }
            }
          ]
        }
      }
    }

Common issues

What actually goes wrong when connecting Elasticsearch, and the fix.

high

Every request comes back 401 or 403.

Half-filled credential pairs are the usual cause: basic needs username and password, api_key needs api_key_id and api_key_secret. If both are set, the key is missing create_index on the target index — write alone is not enough on the first push.

high

Connection refused or the endpoint cannot be reached.

endpoint must carry the protocol, and the port when it is not the default — https://my-cluster.es.amazonaws.com:9243, never a bare hostname. Managed clusters additionally need Jobo's IP range on their allowlist.

medium

Geo queries fail with an error about the coordinates field.

Only an index Jobo created carries the geo_point mapping. If you pre-created the index yourself, dynamic mapping has already typed coordinates as floats and Elasticsearch will not change it in place. Delete the index and let the next push recreate it.

low

The index is empty right after a force resync.

Force resync deletes and recreates the index before repopulating it. Wait for the push to finish; the row counter on the activity page tracks progress.

Best practices

  • Give the feed its own index — force resync deletes and recreates whatever index_name points at.
  • Let Jobo create the index so locations.coordinates gets the geo_point mapping.
  • Scope the API key to that one index instead of reusing the elastic superuser.
  • Leave the _jobo_synced_at field in place; stale-document cleanup filters on it.
  • Attach a pipeline to trim the document if you only search a handful of fields.

Start syncing jobs to Elasticsearch

Connect the destination, pick your filters, and let the feed run.