Skip to documentation content

Translate eight query dialects into Graph Query

Migrate Diffbot, Elastic, KQL, Lucene, PPL, SQL, Cypher, and legacy JSON with source verification, persistent runs, and explicit semantic diagnostics.

In this guide
  1. 1Choose a source dialect
  2. 2Translate in strict mode
  3. 3Review mappings and diagnostics
  4. 4Validate and execute the resulting Graph Query
In this guide
  1. 1Choose a source dialect
  2. 2Translate in strict mode
  3. 3Review mappings and diagnostics
  4. 4Validate and execute the resulting Graph Query

Migration workflow

POST /v1/graph/query/translate accepts a source dialect and either text or JSON. The framework selects a Query Translator Adapter, applies the product field map, validates the generated gq/1.3 query against the ontology, and returns the query with lossless status, mappings, and diagnostics. Translation does not execute the query or consume graph-query execution credits.

Supported dialects

DialectAliasesSupported lossless subset
diffbot-dqldqlEntity type, flat field filters, comparisons, or()/not(), has, Boolean groups, plain facets, sortBy/revSortBy
elasticsearch-query-dslelasticsearch · elastic-query-dslbool, term, terms, range, exists, match_phrase, sort, _source includes, terms aggregations, size
elasticsearch-query-dslopensearch · opensearch-query-dslThe same JSON subset through the shared Elastic/OpenSearch adapter

Diffbot DQL migration

DQL and Graph Query share an entity-first shape, implicit AND, field paths, comparisons, existence checks, Boolean expressions, and facets. Product field mappings convert provider ontology names such as locations.country.name, nbEmployees, and industries into Graph Query fields. Correlated DQL scopes inside braces translate losslessly to gq/1.3 Scoped Predicates, so every child condition still targets the same object-array item.

JSON
{
  "dialect": "diffbot-dql",
  "mode": "strict",
  "query": "type:Organization locations.country.name:"FI" nbEmployees>=100 sortBy:nbEmployees facet:industries"
}

Elasticsearch and OpenSearch migration

Provide entity_type because an Elastic index does not declare the Graph Query root type. bool must and filter become AND, must_not becomes NOT, and a required should group becomes OR. nested becomes a correlated Scoped Predicate. term, terms, range, exists, match_phrase, sorting, source includes, terms aggregations, and size translate directly. Scoring-only should clauses are omitted with a warning; analyzed match, query_string, offsets, and provider search_after values are rejected in strict mode.

JSON
{
  "dialect": "opensearch-query-dsl",
  "entity_type": "Organization",
  "mode": "strict",
  "query": {
    "query": { "bool": { "filter": [
      { "term": { "country": "FI" } },
      { "range": { "employees": { "gte": 100 } } }
    ] } },
    "sort": [{ "employees": "desc" }],
    "_source": ["businessId", "employees", "industry"],
    "aggs": { "industries": { "terms": { "field": "industry" } } },
    "size": 25
  }
}

Strict and best-effort modes

Use strict for production migrations. It returns valid:false and no target query when semantics cannot be preserved. best_effort is an explicit review workflow that may reduce an analyzed Elastic match query to a contains filter, always marks lossless:false, and attaches a stable warning code. Never execute a best-effort result without reviewing its diagnostics.

Verify source and target results

POST /v1/graph/query/translate/verify executes the target and compares identity, ordering, facets, and pagination with source_result captured from the real source system or returned by a configured Source Execution Adapter. The response names captured_source_result or source_adapter as its baseline. Without either, translated_fixture_replay is deliberately not claimed as provider equivalence.

Persist and audit migration runs

POST /v1/graph/query/migration-runs stores a batch of up to 100 queries with queued, running, completed, failed, or cancelled state, attempt history, result, and errors. Generated SDKs expose create, list, get, retry, cancel, and export operations. The synchronous /migrations endpoint remains available for small compatibility workflows.

Read the translation result

valid means the target query was generated and passed Graph Query ontology validation. lossless means no warning or approximation was needed. mappings lists every renamed field. diagnostics contains stable severity, code, path, message, and suggestion fields. validation contains the same target-language validation contract used by /graph/query/validate.

JSON
{
  "valid": true,
  "lossless": true,
  "query": "type:Organization location.country:"FI" employees>=100 sort:+employees facet:industry",
  "mappings": [
    { "source": "nbEmployees", "target": "employees", "lossless": true }
  ],
  "diagnostics": [],
  "validation": { "valid": true, "errors": [] }
}

Use the translator from an SDK

All generated SDKs expose translation, canonical formatting, source verification, and persistent migration-run operations. Store a translated Graph Query only after checking valid, lossless, diagnostics, and the reported verification baseline. Then format and explain it before execution.

TypeScript
const translated = await graphApi.translateKnowledgeGraphQuery({
  graphQueryTranslationInput: {
    dialect: 'diffbot-dql',
    mode: 'strict',
    query: 'type:Organization locations.country.name:"FI" nbEmployees>=100'
  }
});

if (!translated.valid || !translated.lossless) {
  throw new Error(JSON.stringify(translated.diagnostics));
}

await graphApi.explainKnowledgeGraphQuery({
  graphQueryInput: { query: translated.query }
});

Production migration checklist

CheckRequirement
Field mapEvery provider field resolves to the intended product ontology field
Semanticsstrict translation is lossless or every best-effort diagnostic is approved
CardinalityNested and multi-value conditions preserve the intended same-element behavior
Result shapeProjection and facets return the fields and buckets consumers expect
PaginationRestart from page one and adopt Graph Query cursors
VerificationCompare representative source and target result sets before switching traffic
Was this page helpful?