Loading

ES|QL COMPLETION command

The ES|QL COMPLETION command enables LLM inference directly within ES|QL queries. It sends a prompt to a configured inference endpoint and returns the completion result as a new column. This supports both RAG (retrieval-augmented generation) pipelines and standalone completions.

COMPLETION [column =] prompt WITH { "inference_id" : "endpoint-id" }
		
  • prompt - a field reference or expression containing the prompt text
  • inference_id - the inference endpoint ID configured in your Elasticsearch cluster
  • column (optional) - output column name; defaults to completion if omitted

The InferenceEndpoints class provides constants for preconfigured serverless inference endpoints:

using Elastic.Esql;

InferenceEndpoints.Anthropic.Claude46Opus    // ".anthropic-claude-4.6-opus-completion"
InferenceEndpoints.Anthropic.Claude45Sonnet  // ".anthropic-claude-4.5-sonnet-completion"
InferenceEndpoints.Anthropic.Claude45Opus    // ".anthropic-claude-4.5-opus-completion"
InferenceEndpoints.Anthropic.Claude37Sonnet  // ".anthropic-claude-3.7-sonnet-completion"
InferenceEndpoints.Google.Gemini25Pro        // ".google-gemini-2.5-pro-completion"
InferenceEndpoints.Google.Gemini25Flash      // ".google-gemini-2.5-flash-completion"
InferenceEndpoints.OpenAi.Gpt52             // ".openai-gpt-5.2-completion"
InferenceEndpoints.OpenAi.Gpt41             // ".openai-gpt-4.1-completion"
InferenceEndpoints.OpenAi.Gpt41Mini         // ".openai-gpt-4.1-mini-completion"
InferenceEndpoints.OpenAi.GptOss120B        // ".openai-gpt-oss-120b-completion"
InferenceEndpoints.Elastic.GpLlmV2          // ".gp-llm-v2-completion"
		

You can also pass any string as the inference ID for custom endpoints.

Append .Completion() to a FROM-based query to run LLM inference on query results. This is the typical RAG pattern: retrieve documents, then send a field to the LLM.

var esql = client.CreateQuery<LogEntry>()
    .Where(l => l.StatusCode >= 500)
    .Take(1)
    .Completion("message", InferenceEndpoints.OpenAi.Gpt41, column: "analysis")
    .Keep("message", "analysis")
    .ToString();
		
FROM logs-*
| WHERE statusCode >= 500
| LIMIT 1
| COMPLETION analysis = message WITH { "inference_id" : ".openai-gpt-4.1-completion" }
| KEEP message, analysis
		

Use a lambda selector for type-safe field resolution. Field names are resolved from [JsonPropertyName] attributes or the configured naming policy:

var esql = client.CreateQuery<LogEntry>()
    .Completion(l => l.Message, InferenceEndpoints.Anthropic.Claude46Opus, column: "summary")
    .ToString();
		
FROM logs-*
| COMPLETION summary = message WITH { "inference_id" : ".anthropic-claude-4.6-opus-completion" }
		

When column is omitted, ES|QL defaults the output column to completion:

var esql = client.CreateQuery<LogEntry>()
    .Completion(l => l.Message, InferenceEndpoints.Google.Gemini25Flash)
    .ToString();
		
FROM logs-*
| COMPLETION message WITH { "inference_id" : ".google-gemini-2.5-flash-completion" }
		

Use .Row() to create a standalone ROW + COMPLETION pipeline for sending a prompt without querying an index. The Row() extension method accepts an anonymous object — property names become column names and values are automatically escaped:

var esql = client.CreateQuery<CompletionResult>()
    .Row(() => new { prompt = "Tell me about Elasticsearch" })
    .Completion("prompt", InferenceEndpoints.Anthropic.Claude46Opus, column: "answer")
    .ToString();
		
ROW prompt = "Tell me about Elasticsearch"
| COMPLETION answer = prompt WITH { "inference_id" : ".anthropic-claude-4.6-opus-completion" }
		

A full retrieval-augmented generation pipeline that fetches error logs, builds a prompt, sends it to an LLM, and keeps only the relevant output:

var esql = client.CreateQuery<LogEntry>()
    .Where(l => l.StatusCode >= 500)
    .OrderByDescending(l => l.Timestamp)
    .Take(10)
    .Completion(l => l.Message, InferenceEndpoints.OpenAi.Gpt41, column: "analysis")
    .Keep("message", "analysis")
    .ToString();
		
FROM logs-*
| WHERE statusCode >= 500
| SORT @timestamp DESC
| LIMIT 10
| COMPLETION analysis = message WITH { "inference_id" : ".openai-gpt-4.1-completion" }
| KEEP message, analysis
		

The ROW source command produces a row with literal values. It is primarily used with COMPLETION for standalone prompts, but is available as a general-purpose command:

var esql = client.CreateQuery<MyType>()
    .Row(() => new { a = 1, b = "hello" })
    .ToString();
		
ROW a = 1, b = "hello"
		
Method Description
.Row(Expression<Func<object>> columns) Produces a row with literal values (ROW command)
.Completion(string prompt, string inferenceId, string? column) Adds a COMPLETION command with a string field name
.Completion(Expression<Func<T, string>> prompt, string inferenceId, string? column) Adds a COMPLETION command with a type-safe lambda selector