/// <summary> /// Executes a <see cref="IFtsQuery" /> request including any <see cref="ISearchParams" /> parameters asynchronously. /// </summary> /// <returns>A <see cref="ISearchQueryResult"/> wrapped in a <see cref="Task"/> for awaiting on.</returns> public async Task <ISearchQueryResult> QueryAsync(SearchQuery searchQuery) { var searchResult = new SearchQueryResult(); var baseUri = ConfigContextBase.GetSearchUri(); var requestUri = new Uri(baseUri, searchQuery.RelativeUri()); var searchBody = searchQuery.ToJson(); try { using (var content = new StringContent(searchBody, Encoding.UTF8, MediaType.Json)) using (var response = await _httpClient.PostAsync(requestUri, content).ContinueOnAnyContext()) using (var stream = await response.Content.ReadAsStreamAsync().ContinueOnAnyContext()) { if (response.IsSuccessStatusCode) { searchResult = DataMapper.Map <SearchQueryResult>(stream); } else { // ReSharper disable once UseStringInterpolation var message = string.Format("{0}: {1}", (int)response.StatusCode, response.ReasonPhrase); ProcessError(new HttpRequestException(message), searchResult); using (var reader = new StreamReader(stream)) { searchResult.Errors.Add(await reader.ReadToEndAsync().ContinueOnAnyContext()); } if (response.StatusCode == HttpStatusCode.NotFound) { baseUri.IncrementFailed(); } } } baseUri.ClearFailed(); } catch (HttpRequestException e) { Log.Info("Search failed {0}: {1}{2}", baseUri, Environment.NewLine, searchBody); baseUri.IncrementFailed(); ProcessError(e, searchResult); Log.Error(e); } catch (AggregateException ae) { ae.Flatten().Handle(e => { Log.Info("Search failed {0}: {1}{2}", baseUri, Environment.NewLine, searchBody); ProcessError(e, searchResult); return(true); }); } catch (Exception e) { Log.Info("Search failed {0}: {1}{2}", baseUri, Environment.NewLine, searchBody); Log.Info(e); ProcessError(e, searchResult); } return(searchResult); }
/// <summary> /// Executes a <see cref="IFtsQuery" /> request including any <see cref="ISearchParams" /> parameters asynchronously. /// </summary> /// <returns>A <see cref="ISearchQueryResult"/> wrapped in a <see cref="Task"/> for awaiting on.</returns> public async Task<ISearchQueryResult> QueryAsync(SearchQuery searchQuery) { var searchResult = new SearchQueryResult(); var baseUri = ConfigContextBase.GetSearchUri(); var requestUri = new Uri(baseUri, searchQuery.RelativeUri()); var searchBody = searchQuery.ToJson(); try { using (var content = new StringContent(searchBody, Encoding.UTF8, MediaType.Json)) using (var response = await _httpClient.PostAsync(requestUri, content).ContinueOnAnyContext()) using (var stream = await response.Content.ReadAsStreamAsync().ContinueOnAnyContext()) { if (response.IsSuccessStatusCode) { searchResult = DataMapper.Map<SearchQueryResult>(stream); } else { // ReSharper disable once UseStringInterpolation var message = string.Format("{0}: {1}", (int)response.StatusCode, response.ReasonPhrase); ProcessError(new HttpRequestException(message), searchResult); using (var reader = new StreamReader(stream)) { searchResult.Errors.Add(await reader.ReadToEndAsync().ContinueOnAnyContext()); } if (response.StatusCode == HttpStatusCode.NotFound) { baseUri.IncrementFailed(); } } } baseUri.ClearFailed(); } catch (HttpRequestException e) { Log.InfoFormat("Search failed {0}: {1}{2}", baseUri, Environment.NewLine, searchBody); baseUri.IncrementFailed(); ProcessError(e, searchResult); Log.Error(e); } catch (AggregateException ae) { ae.Flatten().Handle(e => { Log.InfoFormat("Search failed {0}: {1}{2}", baseUri, Environment.NewLine, searchBody); ProcessError(e, searchResult); return true; }); } catch (Exception e) { Log.InfoFormat("Search failed {0}: {1}{2}", baseUri, Environment.NewLine, searchBody); Log.Info(e); ProcessError(e, searchResult); } return searchResult; }
public void ToJson_WithFacets() { var searchParams = new SearchQuery().Facets( new TermFacet("termfacet", "thefield", 10), new DateRangeFacet("daterangefacet", "thefield", 10).AddRange(DateTime.Now, DateTime.Now.AddDays(1)), new NumericRangeFacet("numericrangefacet", "thefield", 2).AddRange(2.2f, 3.5f)); Console.WriteLine(searchParams.ToJson()); }
public void ToJson_JsonStringIsValid() { var searchParams = new SearchQuery(). Skip(20). Limit(10).Explain(true). Timeout(TimeSpan.FromMilliseconds(10000)). #pragma warning disable 618 WithConsistency(ScanConsistency.AtPlus); #pragma warning restore 618 //var expected = "{\"ctl\":{\"timeout\":10000,\"consistency\":{\"level\":\"at_plus\",\"vectors\":{\"customerIndex\":{\"0\":123,\"1/a0b1c2\":234}}}},\"query\":{\"query\":\"alice smith\",\"boost\": 1},\"size\": 10,\"from\":20,\"highlight\":{\"style\": null,\"fields\":null},\"fields\":[\"*\"],\"facets\":null,\"explain\":true}"; var expected = "{\"ctl\":{\"timeout\":10000,\"consistency\":{\"level\":\"at_plus\",\"vectors\":{}}},\"size\":10,\"from\":20,\"explain\":true}"; var actual = searchParams.ToJson().ToString().Replace("\r\n", "").Replace(" ", ""); Console.WriteLine(actual); Console.WriteLine(expected); Assert.AreEqual(expected, actual); }
/// <summary> /// Executes a <see cref="IFtsQuery" /> request including any <see cref="ISearchParams" /> parameters asynchronously. /// </summary> /// <returns>A <see cref="ISearchQueryResult"/> wrapped in a <see cref="Task"/> for awaiting on.</returns> public async Task <ISearchQueryResult> QueryAsync(SearchQuery searchQuery, CancellationToken cancellationToken) { var searchResult = new SearchQueryResult(); var baseUri = ConfigContextBase.GetSearchUri(); var requestUri = new Uri(baseUri, searchQuery.RelativeUri()); string searchBody; using (ClientConfiguration.Tracer.BuildSpan(searchQuery, CouchbaseOperationNames.RequestEncoding).Start()) { searchBody = searchQuery.ToJson(); } try { using (var content = new StringContent(searchBody, Encoding.UTF8, MediaType.Json)) { HttpResponseMessage response; using (ClientConfiguration.Tracer.BuildSpan(searchQuery, CouchbaseOperationNames.DispatchToServer).Start()) { response = await HttpClient.PostAsync(requestUri, content, cancellationToken).ContinueOnAnyContext(); } using (ClientConfiguration.Tracer.BuildSpan(searchQuery, CouchbaseOperationNames.ResponseDecoding).Start()) using (var stream = await response.Content.ReadAsStreamAsync().ContinueOnAnyContext()) { if (response.IsSuccessStatusCode) { searchResult = DataMapper.Map <SearchQueryResult>(stream); } else { string responseContent; using (var reader = new StreamReader(stream)) { responseContent = await reader.ReadToEndAsync().ContinueOnAnyContext(); } if (response.Content.Headers.TryGetValues("Content-Type", out var values) && values.Any(value => value.Contains(MediaType.Json))) { // server 5.5+ responds with JSON content var result = JsonConvert.DeserializeObject <FailedSearchQueryResult>(responseContent); ProcessError(new HttpRequestException(result.Message), searchResult); searchResult.Errors.Add(result.Message); } else { // use response content as raw string // ReSharper disable once UseStringInterpolation var message = string.Format("{0}: {1}", (int)response.StatusCode, response.ReasonPhrase); ProcessError(new HttpRequestException(message), searchResult); searchResult.Errors.Add(responseContent); } if (response.StatusCode == HttpStatusCode.NotFound) { baseUri.IncrementFailed(); } } } } baseUri.ClearFailed(); } catch (TaskCanceledException) { var operationContext = new OperationContext("fts", string.Empty) { RemoteEndpoint = baseUri.Authority }; Log.Info(operationContext.ToString()); } catch (HttpRequestException e) { Log.Info("Search failed {0}: {1}{2}", baseUri, Environment.NewLine, User(searchBody)); baseUri.IncrementFailed(); ProcessError(e, searchResult); Log.Error(e); } catch (AggregateException ae) { ae.Flatten().Handle(e => { Log.Info("Search failed {0}: {1}{2}", baseUri, Environment.NewLine, User(searchBody)); ProcessError(e, searchResult); return(true); }); } catch (Exception e) { Log.Info("Search failed {0}: {1}{2}", baseUri, Environment.NewLine, User(searchBody)); Log.Info(e); ProcessError(e, searchResult); } UpdateLastActivity(); return(searchResult); }
/// <summary> /// Executes a <see cref="IFtsQuery" /> request including any <see cref="ISearchOptions" /> parameters asynchronously. /// </summary> /// <returns>A <see cref="ISearchResult"/> wrapped in a <see cref="Task"/> for awaiting on.</returns> public async Task <ISearchResult> QueryAsync(SearchQuery searchQuery, CancellationToken cancellationToken = default) { // try get Search node var node = Context.GetRandomNodeForService(ServiceType.Search); var uri = new UriBuilder(node.SearchUri) { Path = $"api/index/{searchQuery.Index}/query" }; var searchResult = new SearchResult(); string searchBody; //using (ClientConfiguration.Tracer.BuildSpan(searchQuery, CouchbaseOperationNames.RequestEncoding).StartActive()) //{ searchBody = searchQuery.ToJson(); //} try { using (var content = new StringContent(searchBody, Encoding.UTF8, MediaType.Json)) { HttpResponseMessage response; //using (ClientConfiguration.Tracer.BuildSpan(searchQuery, CouchbaseOperationNames.DispatchToServer).StartActive()) //{ response = await HttpClient.PostAsync(node.SearchUri, content, cancellationToken).ConfigureAwait(false); //} //using (ClientConfiguration.Tracer.BuildSpan(searchQuery, CouchbaseOperationNames.ResponseDecoding).StartActive()) using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) { if (response.IsSuccessStatusCode) { searchResult = DataMapper.Map <SearchResult>(stream); } else { string responseContent; using (var reader = new StreamReader(stream)) { responseContent = await reader.ReadToEndAsync().ConfigureAwait(false); } if (response.Content.Headers.TryGetValues("Content-Type", out var values) && values.Any(value => value.Contains(MediaType.Json))) { // server 5.5+ responds with JSON content var result = JsonConvert.DeserializeObject <FailedSearchQueryResult>(responseContent); ProcessError(new HttpRequestException(result.Message), searchResult); //searchResult.Errors.Add(result.Message); } else { // use response content as raw string // ReSharper disable once UseStringInterpolation var message = string.Format("{0}: {1}", (int)response.StatusCode, response.ReasonPhrase); ProcessError(new HttpRequestException(message), searchResult); //searchResult.Errors.Add(responseContent); } if (response.StatusCode == HttpStatusCode.NotFound) { //baseUri.IncrementFailed(); } } } searchResult.HttpStatusCode = response.StatusCode; } //baseUri.ClearFailed(); } catch (OperationCanceledException e) { //var operationContext = OperationContext.CreateSearchContext(ClusterOptions.BucketName, baseUri?.Authority); //operationContext.TimeoutMicroseconds = searchQuery.TimeoutValue; //Log.Info(operationContext.ToString()); ProcessError(e, searchResult); } catch (HttpRequestException e) { //Log.Info("Search failed {0}: {1}{2}", baseUri, Environment.NewLine, User(searchBody)); //baseUri.IncrementFailed(); ProcessError(e, searchResult); //Log.Error(e); } catch (AggregateException ae) { ae.Flatten().Handle(e => { //Log.Info("Search failed {0}: {1}{2}", baseUri, Environment.NewLine, User(searchBody)); ProcessError(e, searchResult); return(true); }); } catch (Exception e) { //Log.Info("Search failed {0}: {1}{2}", baseUri, Environment.NewLine, User(searchBody)); //Log.Info(e); ProcessError(e, searchResult); } UpdateLastActivity(); return(searchResult); }