Painless syntax-context bridge
Serverless Stack
One of the most distinctive aspects of Painless scripting is how data access methods (doc, ctx, and _source) are directly tied to the context of use. Unlike other scripting languages where data access patterns remain consistent, Painless provides different access mechanisms that are optimized for specific use cases and contexts within Elasticsearch.
Understanding when and why to use each access method is crucial for writing efficient Painless scripts.
If you're new to Painless contexts, refer to Painless contexts in the Reference section for comprehensive context documentation. For hands-on examples of field access, refer to our set of Painless script tutorials.
docvalues are a columnar field value store, enabled by default on all the fields except analyzed text fields. They can only return simple field values such as numbers, dates, geo-points, and terms.ctxaccess provides structured access to document content during modification contexts, with fields accessible as map and list structures for existing document fields._sourceaccess loads the complete document as a map-of-maps, optimized for returning several fields per result but slower than doc values for single field access.
Check the decision matrix to decide between these.
- You should always start with
docvalues as your first option for field access. This is the fastest and most efficient way to access field values in Painless scripts. Refer to Doc values to learn more. - Painless context examples:
- Syntax pattern:
doc[‘field_name’].value
The following example calculates the average price per item across all orders by dividing taxful_total_price by total_quantity for each document. The avg aggregation then computes the average of these calculated values.
GET kibana_sample_data_ecommerce/_search
{
"size": 0,
"aggs": {
"avg_price_per_item": {
"avg": {
"script": {
"source": "doc['taxful_total_price'].value / doc['total_quantity'].value"
}
}
}
}
}
- Use
ctxfor document modification and pipeline processing where you need access to document metadata, content, and operational control. - Painless context examples:
- Syntax pattern:
ctx.field_name,ctx._source.field_name, and `ctx[‘field_name’]`
The following example creates an ingest pipeline named create_summary with a script processor. This script assigns a text value to the field order_summary by combining the customer name and the price.
PUT _ingest/pipeline/create_summary
{
"processors": [
{
"script": {
"source": """
ctx.order_summary = ctx.customer_full_name + ' - $' + ctx.taxful_total_price;
"""
}
}
]
}
- Use
_sourcefor document updates and transformations where you need full JSON document access. - Painless context examples:
- Syntax patterns:
ctx._source.field_name
Let’s use _update_by_query to calculate loyalty points from the order’s total price multiplied by a parameter rate for high-value orders.
POST /kibana_sample_data_ecommerce/_update_by_query
{
"query": {
"range": {
"taxful_total_price": {"gte": 1000}
}
},
"script": {
"source": """
ctx._source.loyalty_points = Math.round(ctx._source.taxful_total_price * params.points_rate);
""",
"params": {
"points_rate": 2.0
}
}
}
| Scenario | Required Access Method | Reason |
|---|---|---|
| Aggregation calculations | doc |
Columnar storage provides fastest performance |
| Document scoring | doc |
Optimized for search-time calculations |
| Script fields (top results) | _source |
Optimized for returning several fields per result |
| Adding fields during ingest | ctx |
Direct field access during pipeline processing |
| Updating existing documents | ctx._source |
Full document modification capabilities |
| Document transformation during reindex | ctx._source |
Complete document restructuring with metadata access |
| Sort operations | doc |
Single-field performance optimization for sorting |
| Runtime field with simple values | doc |
Performance advantage for repeated calculations |
| Runtime field with complex logic | params[‘_source’] |
Access to complete document structure with emit |
- New users: Explore Accessing document fields and special variables
- Advanced users: Review Painless contexts for context-specific implementation details