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
| Dialect | Aliases | Supported lossless subset |
|---|---|---|
| diffbot-dql | dql | Entity type, flat field filters, comparisons, or()/not(), has, Boolean groups, plain facets, sortBy/revSortBy |
| elasticsearch-query-dsl | elasticsearch · elastic-query-dsl | bool, term, terms, range, exists, match_phrase, sort, _source includes, terms aggregations, size |
| elasticsearch-query-dsl | opensearch · opensearch-query-dsl | The 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.
{
"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.
{
"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.
{
"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.
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
| Check | Requirement |
|---|---|
| Field map | Every provider field resolves to the intended product ontology field |
| Semantics | strict translation is lossless or every best-effort diagnostic is approved |
| Cardinality | Nested and multi-value conditions preserve the intended same-element behavior |
| Result shape | Projection and facets return the fields and buckets consumers expect |
| Pagination | Restart from page one and adopt Graph Query cursors |
| Verification | Compare representative source and target result sets before switching traffic |