@@ -39,6 +39,15 @@ import (
3939 "github.com/elastic/go-elasticsearch/v8/esutil"
4040)
4141
42+ type BulkRequestItemMeta struct {
43+ Action string `json:"-"`
44+ Index string `json:"_index"`
45+ DocumentID string `json:"_id"`
46+ Pipeline string `json:"pipeline"`
47+ DynamicTemplates map [string ]string `json:"dynamic_templates"`
48+ RequireDataStream bool `json:"require_data_stream"`
49+ }
50+
4251// TimestampFormat holds the time format for formatting timestamps according to
4352// Elasticsearch's strict_date_optional_time date format, which includes a fractional
4453// seconds component.
@@ -60,6 +69,18 @@ func DecodeBulkRequestWithStats(r *http.Request) (
6069 return indexed , result , stats
6170}
6271
72+ // DecodeBulkRequestWithStatsAndMeta decodes a /_bulk request's body,
73+ // returning the decoded bulk request action/meta and documents,
74+ // and a response body and stats about the request.
75+ func DecodeBulkRequestWithStatsAndMeta (r * http.Request ) (
76+ docs [][]byte ,
77+ meta []BulkRequestItemMeta ,
78+ res esutil.BulkIndexerResponse ,
79+ stats RequestStats ,
80+ ) {
81+ return decodeBulkRequest (r )
82+ }
83+
6384// DecodeBulkRequestWithStatsAndDynamicTemplates decodes a /_bulk request's body,
6485// returning the decoded documents and a response body and stats about request, and per-request dynamic templates.
6586func DecodeBulkRequestWithStatsAndDynamicTemplates (r * http.Request ) (
@@ -79,7 +100,22 @@ func DecodeBulkRequestWithStatsAndDynamicTemplatesAndPipelines(r *http.Request)
79100 res esutil.BulkIndexerResponse ,
80101 stats RequestStats ,
81102 dynamicTemplates []map [string ]string ,
82- pipelines []string ) {
103+ pipelines []string ,
104+ ) {
105+ docs , meta , res , stats := decodeBulkRequest (r )
106+ for _ , meta := range meta {
107+ dynamicTemplates = append (dynamicTemplates , meta .DynamicTemplates )
108+ pipelines = append (pipelines , meta .Pipeline )
109+ }
110+ return docs , res , stats , dynamicTemplates , pipelines
111+ }
112+
113+ func decodeBulkRequest (r * http.Request ) (
114+ docs [][]byte ,
115+ meta []BulkRequestItemMeta ,
116+ result esutil.BulkIndexerResponse ,
117+ stats RequestStats ,
118+ ) {
83119 body := r .Body
84120 switch r .Header .Get ("Content-Encoding" ) {
85121 case "gzip" :
@@ -95,15 +131,10 @@ func DecodeBulkRequestWithStatsAndDynamicTemplatesAndPipelines(r *http.Request)
95131 }
96132 body = cr
97133 defer cr .Close ()
134+
98135 scanner := bufio .NewScanner (body )
99- var indexed [][]byte
100- var result esutil.BulkIndexerResponse
101136 for scanner .Scan () {
102- action := make (map [string ]struct {
103- Index string `json:"_index"`
104- DynamicTemplates map [string ]string `json:"dynamic_templates"`
105- Pipeline string `json:"pipeline"`
106- })
137+ action := make (map [string ]BulkRequestItemMeta )
107138 if err := json .NewDecoder (strings .NewReader (scanner .Text ())).Decode (& action ); err != nil {
108139 panic (err )
109140 }
@@ -118,14 +149,16 @@ func DecodeBulkRequestWithStatsAndDynamicTemplatesAndPipelines(r *http.Request)
118149 if ! json .Valid (doc ) {
119150 panic (fmt .Errorf ("invalid JSON: %s" , doc ))
120151 }
121- indexed = append (indexed , doc )
152+ docs = append (docs , doc )
122153
123154 item := esutil.BulkIndexerResponseItem {Status : http .StatusCreated , Index : action [actionType ].Index }
124155 result .Items = append (result .Items , map [string ]esutil.BulkIndexerResponseItem {actionType : item })
125- dynamicTemplates = append (dynamicTemplates , action [actionType ].DynamicTemplates )
126- pipelines = append (pipelines , action [actionType ].Pipeline )
156+
157+ itemMeta := action [actionType ]
158+ itemMeta .Action = actionType
159+ meta = append (meta , itemMeta )
127160 }
128- return indexed , result , RequestStats {int64 (cr .bytesRead )}, dynamicTemplates , pipelines
161+ return docs , meta , result , RequestStats {int64 (cr .bytesRead )}
129162}
130163
131164// NewMockElasticsearchClient returns an elasticsearch.Client which sends /_bulk requests to bulkHandler.
0 commit comments