/// <summary> /// Calls the database to retrieve a single dictionary term based on its specific Term ID. /// Similar, but not identical, to GetTerm(). Instead of retrieving the term for a specific /// dictionary, the term is fetched for a preferred audience. If no records are available for that audience, /// then any other avaiable records are returned instead. /// </summary> /// <param name="termId">The ID of the Term to be retrieved</param> /// <param name="language">The Term's desired language. /// Supported values are: /// en - English /// es - Spanish /// </param> /// <param name="preferredAudience">Preferred target audieince for the definition.</param> /// <param name="version">String identifying which vereion of the API to match.</param> /// <returns></returns> public DataTable GetTermForAudience(int termId, Language language, AudienceType preferredAudience, String version) { log.DebugFormat("Enter GetTermForAudience( {0}, {1}, {2}, {3} ).", termId, language, preferredAudience, version); DataTable results = null; SqlParameter[] parameters = new SqlParameter[] { new SqlParameter("@TermID", SqlDbType.Int) { Value = termId }, new SqlParameter("@Language", SqlDbType.NVarChar) { Value = language.ToString() }, new SqlParameter("@PreferredAudience", SqlDbType.NVarChar) { Value = preferredAudience.ToString() }, new SqlParameter("@ApiVers", SqlDbType.NVarChar) { Value = version }, }; using (SqlConnection conn = SqlHelper.CreateConnection(DBConnectionString)) { results = SqlHelper.ExecuteDatatable(conn, CommandType.StoredProcedure, SP_GET_DICTIONARY_TERM_FOR_AUDIENCE, parameters); } return(results); }
/// <summary> /// Get Term deatils based on the input values /// <param name="dictionary">The value for dictionary.</param> /// <param name="audience">Patient or Healthcare provider</param> /// <param name="language">The language in which the details needs to be fetched</param> /// <param name="id">The Id for the term</param> /// <param name="requestedFields"> The list of fields that needs to be sent in the response</param> /// <returns>An object of GlossaryTerm</returns> /// </summary> public async Task <GlossaryTerm> GetById(string dictionary, AudienceType audience, string language, long id, string[] requestedFields) { IGetResponse <GlossaryTerm> response = null; try { string idValue = id + "_" + dictionary + "_" + language + "_" + audience.ToString().ToLower(); response = await _elasticClient.GetAsync <GlossaryTerm>(new DocumentPath <GlossaryTerm>(idValue), g => g.Index( this._apiOptions.AliasName ).Type("terms")); } catch (Exception ex) { String msg = String.Format("Could not search dictionary '{0}', audience '{1}', language '{2}' and id '{3}.", dictionary, audience, language, id); _logger.LogError(msg, ex); throw new APIErrorException(500, msg); } if (!response.IsValid) { String msg = String.Format("Invalid response when searching for dictionary '{0}', audience '{1}', language '{2}' and id '{3}.", dictionary, audience, language, id); _logger.LogError(msg); throw new APIErrorException(500, msg); } if (null == response.Source) { string msg = String.Format("Empty response when searching for dictionary '{0}', audience '{1}', language '{2}' and id '{3}.", dictionary, audience, language, id); _logger.LogError(msg); throw new APIErrorException(200, msg); } return(response.Source); }
/// <summary> /// Builds the SearchRequest for terms containing with the search text. /// </summary> /// <param name="index">The index which will be searched against.</param> /// <param name="types">The list of document types to search.</param> /// <param name="dictionary">The value for dictionary.</param> /// <param name="audience">Patient or Healthcare provider</param> /// <param name="language">The language in which the details needs to be fetched</param> /// <param name="query">The text to search for.</param> /// <param name="size">The number of records to retrieve.</param> private SearchRequest BuildContainsRequest(Indices index, Types types, string dictionary, string language, AudienceType audience, string query, int size) { /* * Create a query similar to the following. The bool subquery is written with an overloaded version * of operator && which supplies the `{"bool" : {"must": [` portion for you. * This is somewhat explained here: https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/bool-queries.html. * * curl -XPOST http://SERVER_NAME/glossaryv1/terms/_search -H 'Content-Type: application/x-ndjson' -d '{ * "query": { * "bool" : { * "must" : * [{"term" : { "language" : "es" }}, * {"term" : { "dictionary" : "Cancer.gov" }}, * {"term": { "audience": "Patient"}}, * {"match_phrase":{"term_name._autocomplete":"cutáneo"}} * ], * "must_not" : {"prefix" : {"term_name" : "cutáneo"}} * } * } * ,"sort": ["term_name"] * , "_source": ["term_id", "term_name"] * , "from": 0 * , "size": 10 * }' */ SearchRequest request = new SearchRequest(index, types) { Query = new TermQuery { Field = "language", Value = language.ToString() } && new TermQuery { Field = "audience", Value = audience.ToString() } && new TermQuery { Field = "dictionary", Value = dictionary.ToString() } && new MatchPhraseQuery { Field = "term_name._autocomplete", Query = query.ToString() } && !new PrefixQuery { Field = "term_name", Value = query.ToString() }, Sort = new List <ISort> { new SortField { Field = "term_name" } }, Source = new SourceFilter { Includes = new string[] { "term_id", "term_name" } }, Size = size }; return(request); }
public Audience tag_not(HashSet <string> values) { if (allAudience != null) { allAudience = null; } AudienceTarget audienceTarget = AudienceTarget.tag_not(values); allAudience = null; if (dictionary == null) { dictionary = new Dictionary <string, HashSet <string> >(); } Dictionary <string, HashSet <string> > dictionary1 = dictionary; AudienceType audienceType = audienceTarget.audienceType; string key1 = audienceType.ToString(); if (dictionary1.ContainsKey(key1)) { Dictionary <string, HashSet <string> > dictionary2 = dictionary; audienceType = audienceTarget.audienceType; string index = audienceType.ToString(); HashSet <string> stringSet = dictionary2[index]; foreach (string str in values) { stringSet.Add(str); } } else { Dictionary <string, HashSet <string> > dictionary2 = dictionary; audienceType = audienceTarget.audienceType; string key2 = audienceType.ToString(); HashSet <string> stringSet = values; dictionary2.Add(key2, stringSet); } return(Check()); }
/// <summary> /// Common code for building the results data structure from Search and Expand. /// </summary> /// <param name="results"></param> /// <returns></returns> private SearchReturn BuildSearchResultsStructure(SearchResults results, Language language, AudienceType audience, int offset) { List <String> messages = new List <string>(); int resultCount = results.MatchCount; // Report the count in a human-readable format. String message = String.Format("Found {0} results.", resultCount); log.Debug(message); messages.Add(message); // Retrieve results. We already know the number of results, so let's preset the // list to the size we know we're going to need. (Use the number of rows in the results // since MatchCount/resultCount is conceivably much larger than we need and might even be int.MaxValue.) List <DictionarySearchResultEntry> foundTerms = new List <DictionarySearchResultEntry>(results.Data.Rows.Count); foreach (DataRow row in results.Data.Rows) { try { int id = row.Field <int>("termID"); string matchName = row.Field <string>("TermName"); string detail = row.Field <string>("object"); detail = RewriteMediaFileLocations(detail); foundTerms.Add(new DictionarySearchResultEntry(id, matchName, detail)); } catch (Exception ex) { log.Debug("Error retrieving search results.", ex); } } // Populate return metadata structure SearchReturnMeta meta = new SearchReturnMeta() { Language = language.ToString(), Audience = audience.ToString(), Offset = offset, ResultCount = resultCount, Messages = messages.ToArray() }; // Combine meta and results to create the final return object. SearchReturn srchReturn = new SearchReturn() { Result = foundTerms.ToArray(), Meta = meta }; return(srchReturn); }
/// <summary> /// Infrastructure for turning the DataTable returned for one of the GetTerm family of query /// methods into a TermReturn object. /// </summary> /// <param name="termId">The ID of the Term which was retrieved</param> /// <param name="language">The Term's desired language. /// Supported values are: /// en - English /// es - Spanish /// </param> /// <param name="audience">The Term's desired audience. /// Supported values are: /// Patient /// HealthProfessional /// </param> /// <returns>A data structure containing both meta data about the request and a string containing a JSON representation /// of the particular definition identified by the inputs to the method. /// </returns> private TermReturn GetTermCommon(DataTable dtTerm, int termId, Language language, AudienceType audience) { List <String> messages = new List <string>(); String term = string.Empty; // Normal, found 1 match. int resultCount = dtTerm.Rows.Count; if (resultCount == 1) { log.Debug("Found 1 result."); messages.Add("OK"); term = dtTerm.Rows[0].Field <string>("object"); term = RewriteMediaFileLocations(term); } // "Normal", found no matches. else if (resultCount == 0) { log.Debug("Found 0 results."); messages.Add("No result found."); term = string.Empty; } // "Odd" case. With multiple matches, return the first one. else // result count must be greater than 1 { log.WarnFormat("Expected to find one result for term {0}, found {1} instead.", termId, resultCount); messages.Add("OK"); term = dtTerm.Rows[0].Field <string>("object"); term = RewriteMediaFileLocations(term); } // Build up the return data structure. TermReturn trmReturn = new TermReturn(); TermReturnMeta meta = new TermReturnMeta(); meta.Language = language.ToString(); meta.Audience = audience.ToString(); meta.Messages = messages.ToArray(); trmReturn.Meta = meta; trmReturn.Term = term; return(trmReturn); }
/// <summary> /// Get the total number of terms available in the version of a dictionary matching a specific audience and language. /// </summary> /// <param name="dictionary">The specific dictionary to retrieve from.</param> /// <param name="audience">The target audience.</param> /// <param name="language">Language (English - en; Spanish - es).</param> /// <returns>The number of terms available.</returns> public async Task <long> GetCount(string dictionary, AudienceType audience, string language) { // Set up the CountRequest to send to elasticsearch. Indices index = Indices.Index(new string[] { this._apiOptions.AliasName }); Types types = Types.Type(new string[] { "terms" }); CountRequest request = new CountRequest(index, types) { Query = new TermQuery { Field = "language", Value = language.ToString() } && new TermQuery { Field = "audience", Value = audience.ToString() } && new TermQuery { Field = "dictionary", Value = dictionary.ToString() } }; ICountResponse response = null; try { response = await _elasticClient.CountAsync <GlossaryTerm>(request); } catch (Exception ex) { String msg = $"Could not get a count for dictionary '{dictionary}', audience '{audience}', language '{language}'"; _logger.LogError($"Error getting count on index: '{this._apiOptions.AliasName}'."); _logger.LogError(msg, ex); throw new APIErrorException(500, msg); } if (!response.IsValid) { String msg = $"Invalid response when searching for dictionary '{dictionary}', audience '{audience}', language '{language}'"; _logger.LogError(msg); throw new APIErrorException(500, "errors occured"); } return(response.Count); }
/// <summary> /// Search for Terms based on the search criteria. /// <param name="dictionary">The value for dictionary.</param> /// <param name="audience">Patient or Healthcare provider</param> /// <param name="language">The language in which the details needs to be fetched</param> /// <param name="query">The search query</param> /// <param name="matchType">Defines if the search should begin with or contain the key word</param> /// <param name="size">Defines the size of the search</param> /// <param name="from">Defines the Offset for search</param> /// <param name="requestedFields"> The list of fields that needs to be sent in the response</param> /// <returns>A list of GlossaryTerm</returns> /// </summary> public async Task <List <GlossaryTerm> > Expand(string dictionary, AudienceType audience, string language, string query, string matchType, int size, int from, string[] requestedFields) { // // Temporary Solution till we have Elastic Search // List<GlossaryTerm> glossaryTermList = new List<GlossaryTerm>(); // glossaryTermList.Add(GenerateSampleTerm(requestedFields)); // glossaryTermList.Add(GenerateSampleTerm(requestedFields)); // return glossaryTermList; // Set up the SearchRequest to send to elasticsearch. Indices index = Indices.Index(new string[] { this._apiOptions.AliasName }); Types types = Types.Type(new string[] { "terms" }); SearchRequest request = new SearchRequest(index, types) { Query = new BoolQuery { Must = new QueryContainer[] { new TermQuery { Field = "language", Value = language.ToString() } && new TermQuery { Field = "audience", Value = audience.ToString() } && new TermQuery { Field = "dictionary", Value = dictionary.ToString() } && new TermQuery { Field = "first_letter", Value = query.ToString() } } }, Sort = new List <ISort> { new SortField { Field = "term_name" } }, Size = size, From = from, // Source = new SourceFilter // { // Includes = requestedFields // }, }; // The below 3 lines of code help to debug the query that is used for ES. // Delete this 3 lines after code starts working. var stream = new System.IO.MemoryStream(); _elasticClient.Serializer.Serialize(request, stream); var jsonQuery = System.Text.Encoding.UTF8.GetString(stream.ToArray()); // End of Debug code ISearchResponse <GlossaryTerm> response = null; try { response = await _elasticClient.SearchAsync <GlossaryTerm>(request); } catch (Exception ex) { String msg = String.Format("Could not search dictionary '{0}', audience '{1}', language '{2}', query '{3}', matchType '{4}', size '{5}', from '{6}'.", dictionary, audience, language, query, matchType, size, from); _logger.LogError(msg, ex); throw new APIErrorException(500, msg); } if (!response.IsValid) { String msg = String.Format("Invalid response when searching for dictionary '{0}', audience '{1}', language '{2}', query '{3}', matchType '{4}', size '{5}', from '{6}'.", dictionary, audience, language, query, matchType, size, from); _logger.LogError(msg); throw new APIErrorException(500, "errors occured"); } // If ES returns terms matching the params, return them. // List<GlossaryTerm> glossaryTermList = new List<GlossaryTerm>(); // if (response.Total > 0) // { // foreach(GlossaryTerm term in response.Documents) // } // return glossaryTermList; List <GlossaryTerm> glossaryTermList = new List <GlossaryTerm>(); foreach (GlossaryTerm gt in response.Documents) { glossaryTermList.Add(gt); } // Temporary Solution till we have Elastic Search // List<GlossaryTerm> glossaryTermList = new List<GlossaryTerm>(); // glossaryTermList.Add(GenerateSampleTerm(requestedFields)); // glossaryTermList.Add(GenerateSampleTerm(requestedFields)); return(glossaryTermList); }
/// <summary> /// Calls the database to search for terms matching searchText. Results are sorted by the matched term name or alias. /// </summary> /// <param name="searchText">text to search for.</param> /// <param name="includeTypes">A filter for the types of name aliases to include. Multiple values are separated by the pipe character (|). /// If no filter is supplied, the result </param> /// <param name="offset">Offset into the list of matches for the first result to return.</param> /// <param name="numResults">The maximum number of results to return. Must be at least 10.</param> /// <param name="dictionary">The dictionary to retreive the Term from. /// Valid values are /// Term - Dictionary of Cancer Terms /// drug - Drug Dictionary /// genetic - Dictionary of Genetics Terms /// </param> /// <param name="language">The Term's desired language. /// Supported values are: /// en - English /// es - Spanish /// </param> /// <param name="version">String identifying which vereion of the JSON structure to retrieve.</param> /// <returns>DataTable containing a list of matching records. Results are sorted by the matching term name.</returns> public SearchResults Expand(String searchText, String[] includeTypes, int offset, int numResults, DictionaryType dictionary, Language language, AudienceType audience, String version) { log.DebugFormat("Enter Expand( {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7} ).", searchText, includeTypes, offset, numResults, dictionary, language, audience, version); DataTable results; // Set up table parameter for specific types to include. DataTable includeFilter = new DataTable("includes"); includeFilter.Columns.Add("NameType"); Array.ForEach(includeTypes, typeName => includeFilter.Rows.Add(typeName)); SqlParameter matchCountParam = new SqlParameter("@matchCount", SqlDbType.Int) { Direction = ParameterDirection.Output }; int matchCount; SqlParameter[] parameters = new SqlParameter[] { new SqlParameter("@searchText", SqlDbType.NVarChar) { Value = searchText }, new SqlParameter("@IncludeTypes", SqlDbType.Structured) { Value = includeFilter }, new SqlParameter("@offset", SqlDbType.Int) { Value = offset }, new SqlParameter("@maxResults", SqlDbType.Int) { Value = numResults }, new SqlParameter("@Dictionary", SqlDbType.NVarChar) { Value = dictionary.ToString() }, new SqlParameter("@Language", SqlDbType.NVarChar) { Value = language.ToString() }, new SqlParameter("@Audience", SqlDbType.NVarChar) { Value = audience.ToString() }, new SqlParameter("@ApiVers", SqlDbType.NVarChar) { Value = version }, matchCountParam }; using (SqlConnection conn = SqlHelper.CreateConnection(DBConnectionString)) { results = SqlHelper.ExecuteDatatable(conn, CommandType.StoredProcedure, SP_EXPAND_DICTIONARY, parameters); // There's some unresolved weirdness with matchCountParam.Value coming back as NULL even though // the value is set unconditionally. This appears to have been due to retrieving the value // after the connection had been closed. But, since that's not definite, check that the parameter // value is not null (or DBNull) and if so, log an error and retrieve a value that will allow // execution to continue. if (DBNull.Value.Equals(matchCountParam.Value) || matchCountParam.Value == null) { log.Warn("Expand() encountered null when attempting to retrieve the @matchCount parameter."); matchCount = int.MaxValue; } else { matchCount = (int)matchCountParam.Value; } } return(new SearchResults(results, matchCount)); }
/// <summary> /// Calls the database to search for terms matching searchText. This method is intended for use with autosuggest /// and returns a maximum of 10 results /// </summary> /// <param name="searchText">text to search for.</param> /// <param name="searchType">The type of search to perform. /// Valid values are: /// Begins - Search for terms beginning with searchText. /// Contains - Search for terms containing searchText. /// Magic - Search for terms beginning with searchText, followed by those containing searchText. /// </param> /// <param name="numResults">Maximum number of results to return.</param> /// <param name="dictionary">The dictionary to retreive the Term from. /// Valid values are /// Term - Dictionary of Cancer Terms /// drug - Drug Dictionary /// genetic - Dictionary of Genetics Terms /// </param> /// <param name="language">The Term's desired language. /// Supported values are: /// en - English /// es - Spanish /// </param> /// <param name="audience">The desired target audience - Patient or Health professional</param> /// <param name="version">String identifying which vereion of the JSON structure to retrieve.</param> /// <returns>DataTable containing a list of matching records.</returns> public SuggestionResults SearchSuggest(String searchText, SearchType searchType, int numResults, DictionaryType dictionary, Language language, AudienceType audience, String version) { log.DebugFormat("Enter SearchSuggest( {0}, {1}, {2}, {3}, {4}, {5}, {6} ).", searchText, searchType, numResults, dictionary, language, audience, version); DataTable results = null; SqlParameter matchCountParam = new SqlParameter("@matchCount", SqlDbType.Int) { Direction = ParameterDirection.Output }; int matchCount; SqlParameter[] parameters = new SqlParameter[] { new SqlParameter("@searchText", SqlDbType.NVarChar) { Value = searchText }, new SqlParameter("@searchType", SqlDbType.NVarChar) { Value = searchType.ToString() }, new SqlParameter("@maxResults", SqlDbType.Int) { Value = numResults }, new SqlParameter("@Dictionary", SqlDbType.NVarChar) { Value = dictionary.ToString() }, new SqlParameter("@Language", SqlDbType.NVarChar) { Value = language.ToString() }, new SqlParameter("@Audience", SqlDbType.NVarChar) { Value = audience.ToString() }, new SqlParameter("@ApiVers", SqlDbType.NVarChar) { Value = version }, matchCountParam }; using (SqlConnection conn = SqlHelper.CreateConnection(DBConnectionString)) { results = SqlHelper.ExecuteDatatable(conn, CommandType.StoredProcedure, SP_SEARCH_SUGGEST_DICTIONARY, parameters); // There's some unresolved weirdness with matchCountParam.Value coming back as NULL even though // the value is set unconditionally. This appears to have been due to retrieving the value // after the connection had been closed. But, since that's not definite, check that the parameter // value is not null (or DBNull) and if so, log an error and retrieve a value that will allow // execution to continue. if (DBNull.Value.Equals(matchCountParam.Value) || matchCountParam.Value == null) { log.Warn("SearchSuggest() encountered null when attempting to retrieve the @matchCount parameter."); matchCount = int.MaxValue; } else { matchCount = (int)matchCountParam.Value; } } return(new SuggestionResults(results, matchCount)); }
/// <summary> /// Performs a search for terms with names matching searchText. Results are sorted by the matching term name. /// </summary> /// <param name="searchText">text to search for.</param> /// <param name="searchType">The type of search to perform. /// Valid values are: /// Begins - Search for terms beginning with searchText. /// Contains - Search for terms containing searchText. /// Magic - Search for terms beginning with searchText, followed by those containing searchText. /// </param> /// <param name="offset">Offset into the list of matches for the first result to return.</param> /// <param name="numResults">The maximum number of results to return. Must be at least 10.</param> /// <param name="dictionary">The dictionary to retreive the Term from. /// Valid values are /// Term - Dictionary of Cancer Terms /// drug - Drug Dictionary /// genetic - Dictionary of Genetics Terms /// </param> /// <param name="language">The Term's desired language. /// Supported values are: /// en - English /// es - Spanish /// </param> /// <param name="audience">The desired target audience - Patient or Health professional</param> /// <param name="version">String identifying which vereion of the JSON structure to retrieve.</param> /// <returns>DataTable containing a list of matching records. Results are sorted by the matching term name.</returns> public SearchResults Search(String searchText, SearchType searchType, int offset, int numResults, DictionaryType dictionary, Language language, AudienceType audience, String version) { log.DebugFormat("Enter Search( {0}, {1}, {2}, {3}, {4}, {5}, {6} ).", searchText, offset, numResults, dictionary, language, audience, version); DataTable results = null; switch (searchType) { case SearchType.Begins: searchText += "%"; break; case SearchType.Contains: searchText = "%" + searchText + "%"; break; case SearchType.Exact: break; default: { String message = String.Format("Unsupport search type '{0}'.", searchType); log.Error(message); throw new ArgumentException(message); } } SqlParameter matchCountParam = new SqlParameter("@matchCount", SqlDbType.Int) { Direction = ParameterDirection.Output }; int matchCount; SqlParameter[] parameters = new SqlParameter[] { new SqlParameter("@searchText", SqlDbType.NVarChar) { Value = searchText }, new SqlParameter("@offset", SqlDbType.Int) { Value = offset }, new SqlParameter("@maxResults", SqlDbType.Int) { Value = numResults }, new SqlParameter("@Dictionary", SqlDbType.NVarChar) { Value = dictionary.ToString() }, new SqlParameter("@Language", SqlDbType.NVarChar) { Value = language.ToString() }, new SqlParameter("@Audience", SqlDbType.NVarChar) { Value = audience.ToString() }, new SqlParameter("@ApiVers", SqlDbType.NVarChar) { Value = version }, matchCountParam }; using (SqlConnection conn = SqlHelper.CreateConnection(DBConnectionString)) { results = SqlHelper.ExecuteDatatable(conn, CommandType.StoredProcedure, SP_SEARCH_DICTIONARY, parameters); // There's some unresolved weirdness with matchCountParam.Value coming back as NULL even though // the value is set unconditionally. This appears to have been due to retrieving the value // after the connection had been closed. But, since that's not definite, check that the parameter // value is not null (or DBNull) and if so, log an error and attempt to mretrieve a value that // will allow execution to continue. if (DBNull.Value.Equals(matchCountParam.Value) || matchCountParam.Value == null) { log.Warn("Search() encountered null when attempting to retrieve the @matchCount parameter."); matchCount = int.MaxValue; } else { matchCount = (int)matchCountParam.Value; } } return(new SearchResults(results, matchCount)); }
/// <summary> /// Get Term details based on the input values /// <param name="dictionary">The value for dictionary.</param> /// <param name="audience">Patient or Healthcare provider</param> /// <param name="language">The language in which the details needs to be fetched</param> /// <param name="id">The Id for the term</param> /// <returns>An object of GlossaryTerm</returns> /// </summary> public async Task <GlossaryTerm> GetById(string dictionary, AudienceType audience, string language, long id) { IGetResponse <GlossaryTerm> response = null; try { string idValue = $"{id}_{dictionary?.ToLower()}_{language?.ToLower()}_{audience.ToString().ToLower()}"; response = await _elasticClient.GetAsync <GlossaryTerm>(new DocumentPath <GlossaryTerm>(idValue), g => g.Index( this._apiOptions.AliasName ).Type("terms")); } catch (Exception ex) { String msg = $"Could not search dictionary '{dictionary}', audience '{audience}', language '{language}' and id '{id}."; _logger.LogError($"Error searching index: '{this._apiOptions.AliasName}'."); _logger.LogError(ex, msg); throw new APIErrorException(500, msg); } if (!response.IsValid) { String msg = $"Invalid response when searching for dictionary '{dictionary}', audience '{audience}', language '{language}' and id '{id}."; _logger.LogError(msg); throw new APIErrorException(500, msg); } if (null == response.Source) { string msg = $"No match for dictionary '{dictionary}', audience '{audience}', language '{language}' and id '{id}."; _logger.LogDebug(msg); throw new APIErrorException(404, msg); } return(response.Source); }
/// <summary> /// Get all Terms starting with the character passed. /// <param name="dictionary">The value for dictionary.</param> /// <param name="audience">Patient or Healthcare provider</param> /// <param name="language">The language in which the details needs to be fetched</param> /// <param name="expandCharacter">The character to search the query</param> /// <param name="size">Defines the size of the search</param> /// <param name="from">Defines the Offset for search</param> /// <param name="includeAdditionalInfo">If true, the RelatedResources and Media fields will be populated. Else, they will be empty.</param> /// <returns>A GlossaryTermResults object containing the desired records.</returns> /// </summary> public async Task <GlossaryTermResults> Expand(string dictionary, AudienceType audience, string language, string expandCharacter, int size, int from, bool includeAdditionalInfo) { // Elasticsearch knows how to figure out what the ElasticSearch name is for // a given field when given a PropertyInfo. Field[] requestedESFields = (includeAdditionalInfo ? ALL_FIELDS : DEFAULT_FIELDS) .Select(pi => new Field(pi)) .ToArray(); // Set up the SearchRequest to send to elasticsearch. Indices index = Indices.Index(new string[] { this._apiOptions.AliasName }); Types types = Types.Type(new string[] { "terms" }); SearchRequest request = new SearchRequest(index, types) { Query = new TermQuery { Field = "language", Value = language.ToString() } && new TermQuery { Field = "audience", Value = audience.ToString() } && new TermQuery { Field = "dictionary", Value = dictionary.ToString() } && new TermQuery { Field = "first_letter", Value = expandCharacter.ToString() } , Sort = new List <ISort> { new SortField { Field = "term_name" } }, Size = size, From = from, Source = new SourceFilter { Includes = requestedESFields } }; ISearchResponse <GlossaryTerm> response = null; try { response = await _elasticClient.SearchAsync <GlossaryTerm>(request); } catch (Exception ex) { String msg = $"Could not search dictionary '{dictionary}', audience '{audience}', language '{language}', character '{expandCharacter}', size '{size}', from '{from}'."; _logger.LogError($"Error searching index: '{this._apiOptions.AliasName}'."); _logger.LogError(msg, ex); throw new APIErrorException(500, msg); } if (!response.IsValid) { String msg = $"Invalid response when searching for '{dictionary}', audience '{audience}', language '{language}', character '{expandCharacter}', size '{size}', from '{from}'."; _logger.LogError(msg); throw new APIErrorException(500, "errors occured"); } GlossaryTermResults glossaryTermResults = new GlossaryTermResults(); if (response.Total > 0) { // Build the array of glossary terms for the returned results. List <GlossaryTerm> termResults = new List <GlossaryTerm>(); foreach (GlossaryTerm res in response.Documents) { termResults.Add(res); } glossaryTermResults.Results = termResults.ToArray(); // Add the metadata for the returned results glossaryTermResults.Meta = new ResultsMetadata() { TotalResults = (int)response.Total, From = from }; } else if (response.Total == 0) { // Add the defualt value of empty GlossaryTerm list. glossaryTermResults.Results = new GlossaryTerm[] {}; // Add the metadata for the returned results glossaryTermResults.Meta = new ResultsMetadata() { TotalResults = (int)response.Total, From = from }; } return(glossaryTermResults); }
/// <summary> /// Search for Term based on the pretty URL name passed. /// <param name="dictionary">The value for dictionary.</param> /// <param name="audience">Patient or Healthcare provider</param> /// <param name="language">The language in which the details needs to be fetched</param> /// <param name="prettyUrlName">The pretty url name to search for</param> /// <returns>An object of GlossaryTerm</returns> /// </summary> public async Task <GlossaryTerm> GetByName(string dictionary, AudienceType audience, string language, string prettyUrlName) { // Set up the SearchRequest to send to elasticsearch. Indices index = Indices.Index(new string[] { this._apiOptions.AliasName }); Types types = Types.Type(new string[] { "terms" }); SearchRequest request = new SearchRequest(index, types) { Query = new TermQuery { Field = "language", Value = language.ToString() } && new TermQuery { Field = "audience", Value = audience.ToString() } && new TermQuery { Field = "dictionary", Value = dictionary.ToString() } && new TermQuery { Field = "pretty_url_name", Value = prettyUrlName.ToString() } , Sort = new List <ISort> { new SortField { Field = "term_name" } } }; ISearchResponse <GlossaryTerm> response = null; try { response = await _elasticClient.SearchAsync <GlossaryTerm>(request); } catch (Exception ex) { String msg = $"Could not search dictionary '{dictionary}', audience '{audience}', language '{language}', pretty URL name '{prettyUrlName}'."; _logger.LogError($"Error searching index: '{this._apiOptions.AliasName}'."); _logger.LogError(ex, msg); throw new APIErrorException(500, msg); } if (!response.IsValid) { String msg = $"Invalid response when searching for dictionary '{dictionary}', audience '{audience}', language '{language}', pretty URL name '{prettyUrlName}'."; _logger.LogError(msg); throw new APIErrorException(500, "errors occured"); } GlossaryTerm glossaryTerm = new GlossaryTerm(); // If there is only one term in the response, then the search by pretty URL name was successful. if (response.Total == 1) { glossaryTerm = response.Documents.First(); } else if (response.Total == 0) { string msg = $"No match for dictionary '{dictionary}', audience '{audience}', language '{language}', pretty URL name '{prettyUrlName}'."; _logger.LogDebug(msg); throw new APIErrorException(404, msg); } else { string msg = $"Incorrect response when searching for dictionary '{dictionary}', audience '{audience}', language '{language}', pretty URL name '{prettyUrlName}'."; _logger.LogError(msg); throw new APIErrorException(500, "Errors have occured."); } return(glossaryTerm); }