OriginChain docs
reference · elasticsearch

Connect an Elasticsearch client

OriginChain answers the Elasticsearch REST API and Query DSL. Point the official @elastic client — or anything that speaks the Elasticsearch API — at your instance and index, search, and aggregate against the same data your HTTP API and SQL see. One store, one source of truth — and because the search index commits in the same write as the row, a document is findable the instant it is written.

preview · rolling out

The Elasticsearch endpoint is being enabled gradually. Find your instance's endpoint under Elasticsearch access in the console; if the panel isn't there yet, it isn't switched on for you. Everything on this page also works today over the HTTP API at /v1/tenants/<tenant>/es/ with your bearer token. This page states plainly what works and what doesn't — the honest version, not the optimistic one.

What you can connect.

Any client that speaks the Elasticsearch 7.x REST API. We verify against the official @elastic/elasticsearch Node client — it connects, clears its product check, and runs a full index → search → aggregate → delete lifecycle unchanged. Dashboards and app code that issue the Query DSL keep working; you change the endpoint, not the queries. The cluster reports version 7.14.2, so pin your client to the 7.x line.

Connection details.

Point the client at your endpoint and authenticate with an API key from the console. info() is the handshake — it is what the client uses to confirm it is talking to Elasticsearch.

const { Client } = require('@elastic/elasticsearch')

const es = new Client({
  node: 'https://<your-es-endpoint>',   // console -> your instance -> Elasticsearch access
  auth: { apiKey: '<your-api-key>' }
})

await es.info()   // clears the product check; reports version 7.14.2

Insert data.

Index a single document by _id. It is searchable the instant the call returns — there is no refresh interval to wait on.

await es.index({
  index: 'shop.products',
  id: 'sku-8842',
  document: { name: 'Carbon Marathon', brand: 'Aero', price: 149 }
})

Load many at once with _bulk (newline-delimited actions). This is the fast path for backfills and ingest.

await es.bulk({ operations: [
  { index: { _index: 'shop.products', _id: 'sku-1207' } },
  { name: 'Trail 24', brand: 'Aero', price: 89 },
  { index: { _index: 'shop.products', _id: 'sku-3355' } },
  { name: 'City Runner', brand: 'Metro', price: 72 }
]})

Or straight over HTTP — the same NDJSON body a stock Elasticsearch cluster takes:

POST /_bulk
{"index":{"_index":"shop.products","_id":"sku-1207"}}
{"name":"Trail 24","brand":"Aero","price":89}

_update is a partial merge — the fields you send are updated and every other field is preserved.

await es.update({
  index: 'shop.products', id: 'sku-8842',
  doc: { price: 139 }        // name, brand, ... untouched
})

Search and aggregate.

The Query DSL you already write — bool, match, term, filters — with aggregations in the same request.

await es.search({
  index: 'shop.products',
  query: { bool: {
    must:   [{ match: { name: 'marathon' } }],
    filter: [{ term:  { brand: 'Aero' } }]
  } },
  aggs: { by_brand: { terms: { field: 'brand' } } }
})

Also supported: _count, _msearch, _mget, search_after deep paging, collapse, _delete_by_query and _update_by_query (both honor max_docs), and _reindex into a fresh index.

Security comes with the search.

Row-level security and column masking apply to the search itself, not just to the documents it returns. A caller who cannot see a row will not find it through a query, and a query that searches a masked column is refused rather than answered — the match set can't be used to reconstruct a value the mask hides. This is enforcement a bolt-on search cluster can't give you, because it never sees your database's policies.

Limits, stated plainly.

This is a drop-in for the API a real client and its dashboards exercise — not the entire Elasticsearch surface. What we don't answer yet fails closed with an explicit error; it never returns a wrong or silently-partial result.

  • Aggregations: terms, metrics, range, histogram, date_histogram, sub-aggregations and pipeline aggs are in. percentiles, top_hits and extended_stats are on the way; composite/nested are not yet.
  • Scoring: function_score and per-field boosts are in; script_score and rescore are refused.
  • Deep paging: search_after within a 10,000-hit window; Point-in-Time (PIT) is not offered.
  • Cluster management: ILM, snapshots, and index templates are managed by OriginChain, not over the ES API. Vector / kNN search lives on a dedicated surface.
  • Version: the cluster reports 7.14.2; pin clients to the 7.x line.

Feature coverage is a separate question from scale — see Full-text search for how the index is built and what a single node holds.