13
13
using Foundatio . Repositories . Elasticsearch . Configuration ;
14
14
using Foundatio . Repositories . Elasticsearch . Models ;
15
15
using Foundatio . Repositories . Elasticsearch . Queries . Builders ;
16
+ using Foundatio . Repositories . Exceptions ;
16
17
using Foundatio . Repositories . Extensions ;
17
18
using Foundatio . Repositories . JsonPatch ;
18
19
using Foundatio . Repositories . Models ;
@@ -108,10 +109,11 @@ public async Task PatchAsync(string id, object update, bool sendNotification = t
108
109
if ( update == null )
109
110
throw new ArgumentNullException ( nameof ( update ) ) ;
110
111
112
+ string pipeline = ElasticType is IHavePipelinedIndexType ? ( ( IHavePipelinedIndexType ) ElasticType ) . Pipeline : null ;
111
113
string script = update as string ;
112
114
var patch = update as PatchDocument ;
113
-
114
115
if ( script != null ) {
116
+ // TODO: Figure out how to specify a pipeline here.
115
117
var request = new UpdateRequest < T , T > ( GetIndexById ( id ) , ElasticType . Name , id ) {
116
118
Script = script ,
117
119
RetryOnConflict = 10
@@ -140,7 +142,7 @@ public async Task PatchAsync(string id, object update, bool sendNotification = t
140
142
var target = response . Source as JToken ;
141
143
new JsonPatcher ( ) . Patch ( ref target , patch ) ;
142
144
143
- var updateResponse = await _client . LowLevel . IndexPutAsync < object > ( response . Index , response . Type , id , new PostData < object > ( target . ToString ( ) ) ) . AnyContext ( ) ;
145
+ var updateResponse = await _client . LowLevel . IndexPutAsync < object > ( response . Index , response . Type , id , new PostData < object > ( target . ToString ( ) ) , p => p . Pipeline ( pipeline ) ) . AnyContext ( ) ;
144
146
_logger . Trace ( ( ) => updateResponse . GetRequest ( ) ) ;
145
147
146
148
if ( ! updateResponse . Success ) {
@@ -149,6 +151,7 @@ public async Task PatchAsync(string id, object update, bool sendNotification = t
149
151
throw new ApplicationException ( message , updateResponse . OriginalException ) ;
150
152
}
151
153
} else {
154
+ // TODO: Figure out how to specify a pipeline here.
152
155
var request = new UpdateRequest < T , object > ( GetIndexById ( id ) , ElasticType . Name , id ) {
153
156
Doc = update ,
154
157
RetryOnConflict = 10
@@ -195,9 +198,12 @@ public async Task PatchAsync(IEnumerable<string> ids, object update, bool sendNo
195
198
return ;
196
199
}
197
200
201
+ string pipeline = ElasticType is IHavePipelinedIndexType ? ( ( IHavePipelinedIndexType ) ElasticType ) . Pipeline : null ;
198
202
var script = update as string ;
199
203
var bulkResponse = await _client . BulkAsync ( b => {
200
204
foreach ( var id in idList ) {
205
+ b . Pipeline ( pipeline ) ;
206
+
201
207
if ( script != null )
202
208
b . Update < T > ( u => u
203
209
. Id ( id )
@@ -242,6 +248,7 @@ protected async Task<long> PatchAllAsync<TQuery>(TQuery query, object update, bo
242
248
throw new ArgumentNullException ( nameof ( update ) ) ;
243
249
244
250
long affectedRecords = 0 ;
251
+ string pipeline = ElasticType is IHavePipelinedIndexType ? ( ( IHavePipelinedIndexType ) ElasticType ) . Pipeline : null ;
245
252
var patch = update as PatchDocument ;
246
253
if ( patch != null ) {
247
254
var patcher = new JsonPatcher ( ) ;
@@ -256,6 +263,7 @@ protected async Task<long> PatchAllAsync<TQuery>(TQuery query, object update, bo
256
263
. Id ( h . Id )
257
264
. Index ( h . GetIndex ( ) )
258
265
. Type ( h . GetIndexType ( ) )
266
+ . Pipeline ( pipeline )
259
267
. Version ( h . Version ) ) ;
260
268
}
261
269
@@ -293,6 +301,7 @@ protected async Task<long> PatchAllAsync<TQuery>(TQuery query, object update, bo
293
301
Query = ElasticType . QueryBuilder . BuildQuery ( query , GetQueryOptions ( ) , new SearchDescriptor < T > ( ) ) ,
294
302
Conflicts = Conflicts . Proceed ,
295
303
Script = new InlineScript ( script ) ,
304
+ Pipeline = pipeline ,
296
305
Version = HasVersion
297
306
} ;
298
307
@@ -313,6 +322,8 @@ protected async Task<long> PatchAllAsync<TQuery>(TQuery query, object update, bo
313
322
314
323
affectedRecords += await BatchProcessAsync ( query , async results => {
315
324
var bulkResult = await _client . BulkAsync ( b => {
325
+ b . Pipeline ( pipeline ) ;
326
+
316
327
foreach ( var h in results . Hits ) {
317
328
if ( script != null )
318
329
b . Update < T > ( u => u
@@ -674,11 +685,13 @@ private async Task IndexDocumentsAsync(IReadOnlyCollection<T> documents, bool is
674
685
await TimeSeriesType . EnsureIndexAsync ( documentGroup . First ( ) ) . AnyContext ( ) ;
675
686
}
676
687
688
+ string pipeline = ElasticType is IHavePipelinedIndexType ? ( ( IHavePipelinedIndexType ) ElasticType ) . Pipeline : null ;
677
689
if ( documents . Count == 1 ) {
678
690
var document = documents . Single ( ) ;
679
691
var response = await _client . IndexAsync ( document , i => {
680
692
i . OpType ( isCreateOperation ? OpType . Create : OpType . Index ) ;
681
693
i . Type ( ElasticType . Name ) ;
694
+ i . Pipeline ( pipeline ) ;
682
695
683
696
if ( GetParentIdFunc != null )
684
697
i . Parent ( GetParentIdFunc ( document ) ) ;
@@ -687,8 +700,8 @@ private async Task IndexDocumentsAsync(IReadOnlyCollection<T> documents, bool is
687
700
i . Index ( GetDocumentIndexFunc ( document ) ) ;
688
701
689
702
if ( HasVersion && isCreateOperation ) {
690
- var versionDoc = ( IVersioned ) document ;
691
- i . Version ( versionDoc . Version ) ;
703
+ var versionedDoc = ( IVersioned ) document ;
704
+ i . Version ( versionedDoc . Version ) ;
692
705
}
693
706
694
707
return i ;
@@ -698,6 +711,9 @@ private async Task IndexDocumentsAsync(IReadOnlyCollection<T> documents, bool is
698
711
if ( ! response . IsValid ) {
699
712
string message = response . GetErrorMessage ( ) ;
700
713
_logger . Error ( ) . Exception ( response . OriginalException ) . Message ( message ) . Property ( "request" , response . GetRequest ( ) ) . Write ( ) ;
714
+ if ( response . ServerError . Status == 409 )
715
+ throw new DuplicateDocumentException ( message , response . OriginalException ) ;
716
+
701
717
throw new ApplicationException ( message , response . OriginalException ) ;
702
718
}
703
719
@@ -706,7 +722,30 @@ private async Task IndexDocumentsAsync(IReadOnlyCollection<T> documents, bool is
706
722
versionDoc . Version = response . Version ;
707
723
}
708
724
} else {
709
- var response = await _client . IndexManyAsync ( documents , GetParentIdFunc , GetDocumentIndexFunc , ElasticType . Name , isCreateOperation ) . AnyContext ( ) ;
725
+ var bulkRequest = new BulkRequest ( ) ;
726
+ var list = documents . Select ( d => {
727
+ IBulkOperation o = isCreateOperation
728
+ ? ( IBulkOperation ) new BulkCreateOperation < T > ( d ) { Pipeline = pipeline }
729
+ : new BulkIndexOperation < T > ( d ) { Pipeline = pipeline } ;
730
+
731
+ o . Type = ElasticType . Name ;
732
+ if ( GetParentIdFunc != null )
733
+ o . Parent = GetParentIdFunc ( d ) ;
734
+
735
+ if ( GetDocumentIndexFunc != null )
736
+ o . Index = GetDocumentIndexFunc ( d ) ;
737
+
738
+ if ( HasVersion && ! isCreateOperation ) {
739
+ var versionedDoc = ( IVersioned ) d ;
740
+ if ( versionedDoc != null )
741
+ o . Version = versionedDoc . Version ;
742
+ }
743
+
744
+ return o ;
745
+ } ) . ToList ( ) ;
746
+ bulkRequest . Operations = list ;
747
+
748
+ var response = await _client . BulkAsync ( bulkRequest ) . AnyContext ( ) ;
710
749
_logger . Trace ( ( ) => response . GetRequest ( ) ) ;
711
750
712
751
if ( HasVersion ) {
@@ -739,6 +778,9 @@ private async Task IndexDocumentsAsync(IReadOnlyCollection<T> documents, bool is
739
778
if ( ! response . IsValid ) {
740
779
string message = response . GetErrorMessage ( ) ;
741
780
_logger . Error ( ) . Exception ( response . OriginalException ) . Message ( message ) . Property ( "request" , response . GetRequest ( ) ) . Write ( ) ;
781
+ if ( allErrors . Any ( e => e . Status == 409 ) )
782
+ throw new DuplicateDocumentException ( message , response . OriginalException ) ;
783
+
742
784
throw new ApplicationException ( message , response . OriginalException ) ;
743
785
}
744
786
}
0 commit comments