Skip to content

Commit 1d89775

Browse files
committed
Update docs for scripted metric agg
Now that the default language is painless the examples didn't work at all. This fixes them. Closes #21536
1 parent 22a8a62 commit 1d89775

File tree

6 files changed

+112
-54
lines changed

6 files changed

+112
-54
lines changed

docs/build.gradle

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,10 @@ integTest {
175175
}
176176
configFile 'scripts/my_script.js'
177177
configFile 'scripts/my_script.py'
178+
configFile 'scripts/my_init_script.painless'
179+
configFile 'scripts/my_map_script.painless'
180+
configFile 'scripts/my_combine_script.painless'
181+
configFile 'scripts/my_reduce_script.painless'
178182
configFile 'userdict_ja.txt'
179183
configFile 'KeywordTokenizer.rbbi'
180184
// Whitelist reindexing from the local node so we can test it.
@@ -253,6 +257,39 @@ buildRestTests.setups['host'] = '''
253257
- set: {nodes.$master.http.publish_address: host}
254258
'''
255259

260+
// Used by scripted metric docs
261+
buildRestTests.setups['ledger'] = '''
262+
- do:
263+
indices.create:
264+
index: ledger
265+
body:
266+
settings:
267+
number_of_shards: 2
268+
number_of_replicas: 1
269+
mappings:
270+
sale:
271+
properties:
272+
type:
273+
type: keyword
274+
amount:
275+
type: double
276+
- do:
277+
bulk:
278+
index: ledger
279+
type: item
280+
refresh: true
281+
body: |
282+
{"index":{}}
283+
{"date": "2015/01/01 00:00:00", "amount": 200, "type": "sale", "description": "something"}
284+
{"index":{}}
285+
{"date": "2015/01/01 00:00:00", "amount": 10, "type": "expense", "decription": "another thing"}
286+
{"index":{}}
287+
{"date": "2015/01/01 00:00:00", "amount": 150, "type": "sale", "description": "blah"}
288+
{"index":{}}
289+
{"date": "2015/01/01 00:00:00", "amount": 50, "type": "expense", "description": "cost of blah"}
290+
{"index":{}}
291+
{"date": "2015/01/01 00:00:00", "amount": 50, "type": "expense", "description": "advertisement"}'''
292+
256293
// Used by pipeline aggregation docs
257294
buildRestTests.setups['sales'] = '''
258295
- do:

docs/reference/aggregations/metrics/scripted-metric-aggregation.asciidoc

Lines changed: 63 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,25 @@ Example:
99

1010
[source,js]
1111
--------------------------------------------------
12+
POST ledger/_search?size=0
1213
{
1314
"query" : {
1415
"match_all" : {}
1516
},
1617
"aggs": {
1718
"profit": {
1819
"scripted_metric": {
19-
"init_script" : "_agg['transactions'] = []",
20-
"map_script" : "if (doc['type'].value == \"sale\") { _agg.transactions.add(doc['amount'].value) } else { _agg.transactions.add(-1 * doc['amount'].value) }", <1>
21-
"combine_script" : "profit = 0; for (t in _agg.transactions) { profit += t }; return profit",
22-
"reduce_script" : "profit = 0; for (a in _aggs) { profit += a }; return profit"
20+
"init_script" : "params._agg.transactions = []",
21+
"map_script" : "params._agg.transactions.add(doc.type.value == 'sale' ? doc.amount.value : -1 * doc.amount.value)", <1>
22+
"combine_script" : "double profit = 0; for (t in params._agg.transactions) { profit += t } return profit",
23+
"reduce_script" : "double profit = 0; for (a in params._aggs) { profit += a } return profit"
2324
}
2425
}
2526
}
2627
}
2728
--------------------------------------------------
29+
// CONSOLE
30+
// TEST[setup:ledger]
2831

2932
<1> `map_script` is the only required parameter
3033

@@ -35,24 +38,24 @@ The response for the above aggregation:
3538
[source,js]
3639
--------------------------------------------------
3740
{
41+
"took": 218,
3842
...
39-
4043
"aggregations": {
4144
"profit": {
42-
"value": 170
45+
"value": 240.0
4346
}
4447
}
4548
}
4649
--------------------------------------------------
50+
// TESTRESPONSE[s/"took": 218/"took": $body.took/]
51+
// TESTRESPONSE[s/\.\.\./"_shards": $body._shards, "hits": $body.hits, "timed_out": false,/]
4752

4853
The above example can also be specified using file scripts as follows:
4954

5055
[source,js]
5156
--------------------------------------------------
57+
POST ledger/_search?size=0
5258
{
53-
"query" : {
54-
"match_all" : {}
55-
},
5659
"aggs": {
5760
"profit": {
5861
"scripted_metric": {
@@ -66,18 +69,42 @@ The above example can also be specified using file scripts as follows:
6669
"file": "my_combine_script"
6770
},
6871
"params": {
69-
"field": "amount" <1>
72+
"field": "amount", <1>
73+
"_agg": {} <2>
7074
},
7175
"reduce_script" : {
7276
"file": "my_reduce_script"
73-
},
77+
}
7478
}
7579
}
7680
}
7781
}
7882
--------------------------------------------------
83+
// CONSOLE
84+
// TEST[setup:ledger]
85+
86+
<1> script parameters for `init`, `map` and `combine` scripts must be specified
87+
in a global `params` object so that it can be share between the scripts.
88+
<2> if you specify script parameters then you must specify `"_agg": {}`.
89+
90+
////
91+
Verify this response as well but in a hidden block.
7992
80-
<1> script parameters for init, map and combine scripts must be specified in a global `params` object so that it can be share between the scripts
93+
[source,js]
94+
--------------------------------------------------
95+
{
96+
"took": 218,
97+
...
98+
"aggregations": {
99+
"profit": {
100+
"value": 240.0
101+
}
102+
}
103+
}
104+
--------------------------------------------------
105+
// TESTRESPONSE[s/"took": 218/"took": $body.took/]
106+
// TESTRESPONSE[s/\.\.\./"_shards": $body._shards, "hits": $body.hits, "timed_out": false,/]
107+
////
81108

82109
For more details on specifying scripts see <<modules-scripting, script documentation>>.
83110

@@ -88,7 +115,7 @@ Whilst and valid script object can be used within a single script. the scripts m
88115
* primitive types
89116
* String
90117
* Map (containing only keys and values of the types listed here)
91-
* Array (containing elements of only the types listed here)
118+
* Array (containing elements of only the types listed here)
92119

93120
==== Scope of scripts
94121

@@ -98,24 +125,24 @@ init_script:: Executed prior to any collection of documents. Allows the ag
98125
+
99126
In the above example, the `init_script` creates an array `transactions` in the `_agg` object.
100127

101-
map_script:: Executed once per document collected. This is the only required script. If no combine_script is specified, the resulting state
128+
map_script:: Executed once per document collected. This is the only required script. If no combine_script is specified, the resulting state
102129
needs to be stored in an object named `_agg`.
103130
+
104-
In the above example, the `map_script` checks the value of the type field. If the value is 'sale' the value of the amount field
105-
is added to the transactions array. If the value of the type field is not 'sale' the negated value of the amount field is added
131+
In the above example, the `map_script` checks the value of the type field. If the value is 'sale' the value of the amount field
132+
is added to the transactions array. If the value of the type field is not 'sale' the negated value of the amount field is added
106133
to transactions.
107134

108-
combine_script:: Executed once on each shard after document collection is complete. Allows the aggregation to consolidate the state returned from
135+
combine_script:: Executed once on each shard after document collection is complete. Allows the aggregation to consolidate the state returned from
109136
each shard. If a combine_script is not provided the combine phase will return the aggregation variable.
110137
+
111-
In the above example, the `combine_script` iterates through all the stored transactions, summing the values in the `profit` variable
138+
In the above example, the `combine_script` iterates through all the stored transactions, summing the values in the `profit` variable
112139
and finally returns `profit`.
113140

114-
reduce_script:: Executed once on the coordinating node after all shards have returned their results. The script is provided with access to a
115-
variable `_aggs` which is an array of the result of the combine_script on each shard. If a reduce_script is not provided
141+
reduce_script:: Executed once on the coordinating node after all shards have returned their results. The script is provided with access to a
142+
variable `_aggs` which is an array of the result of the combine_script on each shard. If a reduce_script is not provided
116143
the reduce phase will return the `_aggs` variable.
117144
+
118-
In the above example, the `reduce_script` iterates through the `profit` returned by each shard summing the values before returning the
145+
In the above example, the `reduce_script` iterates through the `profit` returned by each shard summing the values before returning the
119146
final combined profit which will be returned in the response of the aggregation.
120147

121148
==== Worked Example
@@ -124,36 +151,19 @@ Imagine a situation where you index the following documents into and index with
124151

125152
[source,js]
126153
--------------------------------------------------
127-
$ curl -XPUT 'http://localhost:9200/transactions/stock/1' -d '
128-
{
129-
"type": "sale",
130-
"amount": 80
131-
}
132-
'
133-
134-
$ curl -XPUT 'http://localhost:9200/transactions/stock/2' -d '
135-
{
136-
"type": "cost",
137-
"amount": 10
138-
}
139-
'
140-
141-
$ curl -XPUT 'http://localhost:9200/transactions/stock/3' -d '
142-
{
143-
"type": "cost",
144-
"amount": 30
145-
}
146-
'
147-
148-
$ curl -XPUT 'http://localhost:9200/transactions/stock/4' -d '
149-
{
150-
"type": "sale",
151-
"amount": 130
152-
}
153-
'
154+
PUT /transactions/stock/_bulk?refresh
155+
{"index":{"_id":1}}
156+
{"type": "sale","amount": 80}
157+
{"index":{"_id":2}}
158+
{"type": "cost","amount": 10}
159+
{"index":{"_id":2}}
160+
{"type": "cost","amount": 30}
161+
{"index":{"_id":2}}
162+
{"type": "sale","amount": 130}
154163
--------------------------------------------------
164+
// CONSOLE
155165

156-
Lets say that documents 1 and 3 end up on shard A and documents 2 and 4 end up on shard B. The following is a breakdown of what the aggregation result is
166+
Lets say that documents 1 and 3 end up on shard A and documents 2 and 4 end up on shard B. The following is a breakdown of what the aggregation result is
157167
at each stage of the example above.
158168

159169
===== Before init_script
@@ -221,7 +231,7 @@ Shard B::
221231

222232
===== After combine_script
223233

224-
The combine_script is executed on each shard after document collection is complete and reduces all the transactions down to a single profit figure for each
234+
The combine_script is executed on each shard after document collection is complete and reduces all the transactions down to a single profit figure for each
225235
shard (by summing the values in the transactions array) which is passed back to the coordinating node:
226236

227237
Shard A:: 50
@@ -239,7 +249,7 @@ The reduce_script receives an `_aggs` array containing the result of the combine
239249
]
240250
--------------------------------------------------
241251

242-
It reduces the responses for the shards down to a final overall profit figure (by summing the values) and returns this as the result of the aggregation to
252+
It reduces the responses for the shards down to a final overall profit figure (by summing the values) and returns this as the result of the aggregation to
243253
produce the response:
244254

245255
[source,js]
@@ -258,8 +268,8 @@ produce the response:
258268
==== Other Parameters
259269

260270
[horizontal]
261-
params:: Optional. An object whose contents will be passed as variables to the `init_script`, `map_script` and `combine_script`. This can be
262-
useful to allow the user to control the behavior of the aggregation and for storing state between the scripts. If this is not specified,
271+
params:: Optional. An object whose contents will be passed as variables to the `init_script`, `map_script` and `combine_script`. This can be
272+
useful to allow the user to control the behavior of the aggregation and for storing state between the scripts. If this is not specified,
263273
the default is the equivalent of providing:
264274
+
265275
[source,js]
@@ -268,4 +278,3 @@ params:: Optional. An object whose contents will be passed as variable
268278
"_agg" : {}
269279
}
270280
--------------------------------------------------
271-
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
double profit = 0;
2+
for (t in params._agg.transactions) {
3+
profit += t
4+
}
5+
return profit
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
params._agg.transactions = []
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
params._agg.transactions.add(doc.type.value == 'sale' ? doc.amount.value : -1 * doc.amount.value)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
double profit = 0;
2+
for (a in params._aggs) {
3+
profit += a
4+
}
5+
return profit

0 commit comments

Comments
 (0)