/// <summary> /// Execute bulk index, create, update, or delete actions. This version uses explicit action parameters /// for each action to be executed. /// </summary> /// <param name="index">The index and type.</param> /// <param name="requests"> /// The documents, if <see cref="BulkActionType.Index"/> or <see cref="BulkActionType.Create"/> /// is specified, this is the source document to index or create, if <see cref="BulkActionType.Update"/> /// is specified this should be an update statement, and if <see cref="BulkActionType.Delete"/> is specified /// this is either the ID or a document which implements <see cref="IKeyDocument"/>. /// </param> /// <param name="options">Any options for the request such as 'refresh'.</param> /// <param name="throwOnFailure"> /// If true, an exception will be thrown if any of the requested actions fail. (Normally the _bulk /// API endpoint returns a 200 if the request was processed successfully, even if document actions fail.) /// </param> /// <param name="cancel">A cancellation token for the request.</param> /// <returns></returns> /// <exception cref="ArgumentNullException">An index is required - index</exception> public Task <BulkActionResult> BulkActionAsync(string index, IEnumerable <BulkActionRequest> requests, object options = null, bool throwOnFailure = true, CancellationToken cancel = default(CancellationToken)) { // No punishment for providing null/empty requests if (requests?.Any() != true) { return(Task.FromResult(new BulkActionResult { Took = TimeSpan.Zero, HasErrors = false, Items = Array.Empty <BulkActionResultItem>() })); } var request = new StringBuilder(); foreach (var requestItem in requests) { request.Append(JsonConvert.SerializeObject(requestItem, _jsonSettings)); } var path = String.IsNullOrEmpty(index) ? "_bulk" : $"{index}/_bulk"; var requestUri = new Uri(_hostProvider.Next() + $"{path}{QueryStringParser.GetQueryString(options)}"); return(MakeRequestAsync <BulkActionResult>( HttpMethod.Post, requestUri, request.ToString(), MediaTypes.ApplicationNewlineDelimittedJson, cancel, "bulk_action")); }
/// <summary> /// Execute bulk index, create, update, or delete actions. This is the simpler version which /// assumes you are only performing a single action type on a single index and document type. /// </summary> /// <param name="index">The index and type.</param> /// <param name="type">The document type.</param> /// <param name="actionType">Type of the action.</param> /// <param name="documents">The documents, if <see cref="BulkActionType.Index" /> or <see cref="BulkActionType.Create" /> /// is specified, this is the source document to index or create, if <see cref="BulkActionType.Update" /> /// is specified this should be an update statement, and if <see cref="BulkActionType.Delete" /> is specified /// this is either the ID or a document which implements <see cref="IKeyDocument" />.</param> /// <param name="options">Any options for the request such as 'refresh'.</param> /// <param name="throwOnFailure">If true, an exception will be thrown if any of the requested actions fail. (Normally the _bulk /// API endpoint returns a 200 if the request was processed successfully, even if document actions fail.)</param> /// <param name="cancel">A cancellation token for the request.</param> /// <returns></returns> public Task <BulkActionResult> BulkActionAsync(string index, string type, BulkActionType actionType, IEnumerable <object> documents, object options = null, bool throwOnFailure = true, CancellationToken cancel = default(CancellationToken)) { if (index == null) { throw new ArgumentNullException("An index is required", nameof(index)); } // No punishment for providing null/empty requests if (documents?.Any() != true) { return(Task.FromResult(new BulkActionResult { Took = TimeSpan.Zero, HasErrors = false, Items = Array.Empty <BulkActionResultItem>() })); } var actionName = actionType.ToString().ToLower(); var request = new StringBuilder(); foreach (var document in documents) { if (actionType == BulkActionType.Delete) { var key = (document as IKeyDocument)?.Key ?? document ?? throw new ArgumentException("No key was provided for delete operation", nameof(documents)); var requestItem = new BulkActionRequest(actionType) { ID = key }; request.Append(JsonConvert.SerializeObject(requestItem, _jsonSettings)); } else { var requestItem = new BulkActionRequest(actionType) { ID = (document as IKeyDocument)?.Key, Document = document }; request.Append(JsonConvert.SerializeObject(requestItem, _jsonSettings)); } } var requestUri = new Uri(_hostProvider.Next() + $"{index}/{type}/_bulk{QueryStringParser.GetQueryString(options)}"); return(MakeRequestAsync <BulkActionResult>( HttpMethod.Post, requestUri, request.ToString(), MediaTypes.ApplicationNewlineDelimittedJson, cancel, "bulk_action")); }
/// <summary> /// Executes a _search with the specified parameters. /// </summary> /// <typeparam name="TSource"> /// The index type model to use, this should support the mapping from the '_source' /// document object. /// </typeparam> /// <param name="index">The index (or indexes or index pattern) to search.</param> /// <param name="query">The query object.</param> /// <param name="options">The options for the search query.</param> /// <param name="cancel">A cancellation token for the request.</param> /// <returns>The result of the requested search.</returns> public async Task <SearchResult <TSource> > SearchAsync <TSource>(string index, object query = null, object options = null, CancellationToken cancel = default(CancellationToken)) { var requestUri = new Uri(_hostProvider.Next() + $"{index}/_search{QueryStringParser.GetQueryString(options)}"); SearchResponse <TSource> result; if (query == null) { result = await MakeRequestAsync <SearchResponse <TSource> >( HttpMethod.Get, requestUri, cancel, "search"); } else { result = await MakeRequestAsync <SearchResponse <TSource> >( HttpMethod.Post, requestUri, JsonConvert.SerializeObject(query, _jsonSettings), MediaTypes.ApplicationJson, cancel, "search"); } return(new SearchResult <TSource>( hits: result.Hits.Hits.Select(h => { if (h.Source is IScoreDocument scoreDoc) { scoreDoc.Score = h.Score; } if (h.Source is IKeyDocument keyDoc) { keyDoc.Key = h.ID; } return h.Source; }), total: result.Hits.Total, aggregations: result.Aggregations, suggestions: null )); }
/// <summary> /// Executes a get document by ID request. /// </summary> /// <typeparam name="TSource"> /// The index type model to use, this should support the mapping from the '_source' /// document object. /// </typeparam> /// <param name="index">The index to search.</param> /// <param name="document">The document type to return.</param> /// <param name="id">The document ID.</param> /// <param name="options">The options for the search query.</param> /// <param name="cancel">A cancellation token for the request.</param> /// <returns>Result of the get request.</returns> public Task <TSource> GetSourceAsync <TSource>( string index, string document, string id, object options = null, CancellationToken cancel = default(CancellationToken)) { var requestUri = new Uri(_hostProvider.Next() + $"{index}/{document}/{id}/_source{QueryStringParser.GetQueryString(options)}"); return(MakeRequestAsync <TSource>(HttpMethod.Get, requestUri, cancel, "get_source")); }