Search in sources :

Example 1 with IndexSearchResult

use of org.finra.herd.model.api.xml.IndexSearchResult in project herd by FINRAOS.

the class IndexSearchDaoTest method testIndexSearch.

private void testIndexSearch(Set<String> fields, Set<String> match, List<IndexSearchFilter> searchFilters, List<String> facetList, boolean isHitHighlightingEnabled, boolean testExceptions, boolean setInvalidSearchResultIndexName, boolean isColumnFields) throws IOException {
    // Build the mocks
    SearchRequestBuilder searchRequestBuilder = mock(SearchRequestBuilder.class);
    SearchRequestBuilder searchRequestBuilderWithSource = mock(SearchRequestBuilder.class);
    SearchRequestBuilder searchRequestBuilderWithSize = mock(SearchRequestBuilder.class);
    SearchRequestBuilder searchRequestBuilderWithSorting = mock(SearchRequestBuilder.class);
    SearchRequestBuilder searchRequestBuilderWithHighlighting = mock(SearchRequestBuilder.class);
    SearchResponse searchResponse = mock(SearchResponse.class);
    SearchHits searchHits = mock(SearchHits.class);
    SearchHit searchHit1 = mock(SearchHit.class);
    SearchHit searchHit2 = mock(SearchHit.class);
    SearchShardTarget searchShardTarget1 = mock(SearchShardTarget.class);
    SearchShardTarget searchShardTarget2 = mock(SearchShardTarget.class);
    SearchHit[] searchHitArray = new SearchHit[2];
    searchHitArray[0] = searchHit1;
    searchHitArray[1] = searchHit2;
    HighlightField highlightField = mock(HighlightField.class);
    when(highlightField.getName()).thenReturn("displayName");
    Text[] value = { new Text("match <hlt>fragment</hlt class=\"highlight\">"), new Text("<hlt class=\"highlight\">match</hlt>") };
    when(highlightField.getFragments()).thenReturn(value);
    @SuppressWarnings("unchecked") ListenableActionFuture<SearchResponse> listenableActionFuture = mock(ListenableActionFuture.class);
    final String highlightFieldsConfigValue = "{\"highlightFields\":[{\"fieldName\":\"displayName\",\"fragmentSize\":100,\"matchedFields\":[\"displayName\",\"displayName.stemmed\",\"displayName.ngrams\"],\"numOfFragments\":5}]}";
    final String highlightFieldsColumnMatchConfigValue = "{\"highlightFields\":[{\"fieldName\":\"columnName\",\"fragmentSize\":100,\"matchedFields\":[\"columnName\",\"columnName.stemmed\",\"columnName.ngrams\"],\"numOfFragments\":5}]}";
    // Mock the call to external methods
    when(configurationHelper.getProperty(ConfigurationValue.TAG_SHORT_DESCRIPTION_LENGTH, Integer.class)).thenReturn(300);
    when(configurationHelper.getProperty(ConfigurationValue.BUSINESS_OBJECT_DEFINITION_SHORT_DESCRIPTION_LENGTH, Integer.class)).thenReturn(300);
    when(configurationHelper.getProperty(ConfigurationValue.ELASTICSEARCH_SEARCHABLE_FIELDS_NGRAMS)).thenReturn("{\"displayName\":\"1.0\"}");
    when(configurationHelper.getProperty(ConfigurationValue.ELASTICSEARCH_SEARCHABLE_FIELDS_STEMMED)).thenReturn("{\"displayName\":\"1.0\"}");
    when(configurationHelper.getProperty(ConfigurationValue.ELASTICSEARCH_SEARCHABLE_FIELDS_SHINGLES)).thenReturn("{\"displayName\":\"1.0\"}");
    when(configurationHelper.getProperty(ConfigurationValue.ELASTICSEARCH_HIGHLIGHT_PRETAGS)).thenReturn("<hlt class=\"highlight\">");
    when(configurationHelper.getProperty(ConfigurationValue.ELASTICSEARCH_HIGHLIGHT_POSTTAGS)).thenReturn("</hlt>");
    if (match != null && match.contains(MATCH_COLUMN)) {
        when(configurationHelper.getProperty(ConfigurationValue.ELASTICSEARCH_COLUMN_MATCH_HIGHLIGHT_FIELDS)).thenReturn(highlightFieldsColumnMatchConfigValue);
    } else {
        when(configurationHelper.getProperty(ConfigurationValue.ELASTICSEARCH_HIGHLIGHT_FIELDS)).thenReturn(highlightFieldsConfigValue);
    }
    when(configurationHelper.getProperty(ConfigurationValue.ELASTICSEARCH_BEST_FIELDS_QUERY_BOOST, Float.class)).thenReturn(1f);
    when(configurationHelper.getProperty(ConfigurationValue.ELASTICSEARCH_PHRASE_PREFIX_QUERY_BOOST, Float.class)).thenReturn(1f);
    when(configurationHelper.getProperty(ConfigurationValue.ELASTICSEARCH_PHRASE_QUERY_BOOST, Float.class)).thenReturn(1f);
    when(configurationHelper.getProperty(ConfigurationValue.ELASTICSEARCH_PHRASE_QUERY_SLOP, Integer.class)).thenReturn(5);
    Map<String, String> fieldsBoostMap = new HashMap<>();
    fieldsBoostMap.put("displayName", "1.0");
    if (isColumnFields) {
        fieldsBoostMap.put(COLUMNS_NAME_FIELD, "1.0");
        fieldsBoostMap.put(SCHEMA_COLUMNS_NAME_FIELD, "1.0");
    }
    if (testExceptions) {
        when(jsonHelper.unmarshallJsonToObject(Map.class, "{\"displayName\":\"1.0\"}")).thenThrow(new IOException());
    } else {
        when(jsonHelper.unmarshallJsonToObject(Map.class, "{\"displayName\":\"1.0\"}")).thenReturn(fieldsBoostMap);
    }
    IndexSearchHighlightField indexSearchHighlightField = new IndexSearchHighlightField("displayName", 100, Arrays.asList("displayName", "displayName.stemmed", "displayName.ngrams"), 5);
    IndexSearchHighlightFields highlightFields = new IndexSearchHighlightFields(Collections.singletonList(indexSearchHighlightField));
    IndexSearchHighlightField indexSearchHighlightFieldColumnOnly = new IndexSearchHighlightField("columnName", 100, Arrays.asList("columnName", "columnName.stemmed", "columnName.ngrams"), 5);
    IndexSearchHighlightFields highlightFieldsColumnOnly = new IndexSearchHighlightFields(Collections.singletonList(indexSearchHighlightFieldColumnOnly));
    if (testExceptions) {
        when(jsonHelper.unmarshallJsonToObject(IndexSearchHighlightFields.class, highlightFieldsConfigValue)).thenThrow(new IOException());
    } else {
        if (match != null && match.contains(MATCH_COLUMN)) {
            when(jsonHelper.unmarshallJsonToObject(IndexSearchHighlightFields.class, highlightFieldsColumnMatchConfigValue)).thenReturn(highlightFieldsColumnOnly);
        } else {
            when(jsonHelper.unmarshallJsonToObject(IndexSearchHighlightFields.class, highlightFieldsConfigValue)).thenReturn(highlightFields);
        }
    }
    when(searchRequestBuilder.setSource(any(SearchSourceBuilder.class))).thenReturn(searchRequestBuilderWithSource);
    when(searchRequestBuilderWithSource.setSize(SEARCH_RESULT_SIZE)).thenReturn(searchRequestBuilderWithSize);
    when(searchRequestBuilderWithSize.addSort(any(SortBuilder.class))).thenReturn(searchRequestBuilderWithSorting);
    when(searchRequestBuilderWithSorting.highlighter(any(HighlightBuilder.class))).thenReturn(searchRequestBuilderWithHighlighting);
    when(searchRequestBuilder.execute()).thenReturn(listenableActionFuture);
    when(listenableActionFuture.actionGet()).thenReturn(searchResponse);
    when(searchResponse.getHits()).thenReturn(searchHits);
    when(searchHits.hits()).thenReturn(searchHitArray);
    Map<String, Object> sourceMap1 = new HashMap<>();
    Map<String, Object> tagTypeMap = new HashMap<>();
    tagTypeMap.put(CODE, TAG_TYPE_CODE);
    sourceMap1.put(TAG_TYPE, tagTypeMap);
    when(searchHit1.sourceAsMap()).thenReturn(sourceMap1);
    Map<String, Object> sourceMap2 = new HashMap<>();
    Map<String, Object> businessObjectDefinitionMap = new HashMap<>();
    businessObjectDefinitionMap.put(CODE, NAMESPACE_CODE);
    sourceMap2.put(NAMESPACE, businessObjectDefinitionMap);
    when(searchHit2.sourceAsMap()).thenReturn(sourceMap2);
    when(searchHit1.getShard()).thenReturn(searchShardTarget1);
    when(searchHit2.getShard()).thenReturn(searchShardTarget2);
    when(searchShardTarget1.getIndex()).thenReturn(TAG_SEARCH_INDEX_NAME);
    when(searchShardTarget2.getIndex()).thenReturn(BUSINESS_OBJECT_DEFINITION_SEARCH_INDEX_NAME);
    when(searchHits.getTotalHits()).thenReturn(200L);
    Map<String, HighlightField> highlightFieldMap = new HashMap<>();
    highlightFieldMap.put("displayName", highlightField);
    when(searchHit1.getHighlightFields()).thenReturn(highlightFieldMap);
    when(searchHit2.getHighlightFields()).thenReturn(highlightFieldMap);
    // Create index search request
    final IndexSearchRequest indexSearchRequest = new IndexSearchRequest(SEARCH_TERM, searchFilters, facetList, isHitHighlightingEnabled);
    List<TagTypeIndexSearchResponseDto> tagTypeIndexSearchResponseDtos = Collections.singletonList(new TagTypeIndexSearchResponseDto("code", Collections.singletonList(new TagIndexSearchResponseDto("tag1", 1, null)), null));
    List<ResultTypeIndexSearchResponseDto> resultTypeIndexSearchResponseDto = Collections.singletonList(new ResultTypeIndexSearchResponseDto("type", 1, null));
    when(elasticsearchHelper.getNestedTagTagIndexSearchResponseDto(searchResponse)).thenReturn(tagTypeIndexSearchResponseDtos);
    when(elasticsearchHelper.getResultTypeIndexSearchResponseDto(searchResponse)).thenReturn(resultTypeIndexSearchResponseDto);
    when(elasticsearchHelper.getFacetsResponse(any(ElasticsearchResponseDto.class), eq(BUSINESS_OBJECT_DEFINITION_SEARCH_INDEX_NAME), eq(TAG_SEARCH_INDEX_NAME))).thenCallRealMethod();
    when(elasticsearchHelper.addIndexSearchFilterBooleanClause(any(), any(), any())).thenCallRealMethod();
    when(elasticsearchHelper.addFacetFieldAggregations(any(), any(SearchRequestBuilder.class))).thenReturn(searchRequestBuilder);
    when(herdSearchQueryHelper.determineNegationTermsPresent(any(IndexSearchRequest.class))).thenCallRealMethod();
    when(herdSearchQueryHelper.extractNegationTerms(any(IndexSearchRequest.class))).thenCallRealMethod();
    when(herdSearchQueryHelper.extractSearchPhrase(any(IndexSearchRequest.class))).thenCallRealMethod();
    SearchResult searchResult = mock(SearchResult.class);
    when(jestClientHelper.searchExecute(any())).thenReturn(searchResult);
    List<SearchResult.Hit<Map, Void>> searchHitList = new ArrayList<>();
    Gson gson = new Gson();
    Map<String, Object> map = new HashMap<>();
    map.put(DISPLAY_NAME_SOURCE, "Display Name");
    Map<String, Object> codeMap = new HashMap<>();
    codeMap.put(CODE, "Code");
    map.put(TAG_TYPE, codeMap);
    map.put(NAMESPACE, codeMap);
    JsonElement element = gson.toJsonTree(map);
    List<String> highlightList = new ArrayList<>();
    highlightList.add("Highlight 1");
    Map<String, List<String>> highlightMap = new HashMap<>();
    highlightMap.put("field", highlightList);
    SearchResult.Hit<Map, Void> hit1 = new SearchResult(gson).new Hit(HashMap.class, element, HashMap.class, null, highlightMap, null, setInvalidSearchResultIndexName ? INVALID_VALUE : TAG_SEARCH_INDEX_NAME, TAG_SEARCH_INDEX_NAME, "type", 1.0);
    SearchResult.Hit<Map, Void> hit2 = new SearchResult(gson).new Hit(HashMap.class, element, HashMap.class, null, highlightMap, null, BUSINESS_OBJECT_DEFINITION_SEARCH_INDEX_NAME, BUSINESS_OBJECT_DEFINITION_SEARCH_INDEX_NAME, "type", 2.0);
    searchHitList.add(hit1);
    searchHitList.add(hit2);
    when(searchResult.getHits(Map.class)).thenReturn(searchHitList);
    when(searchResult.getTotal()).thenReturn(200L);
    MetricAggregation metricAggregation = mock(MetricAggregation.class);
    TermsAggregation termsAggregation = mock(TermsAggregation.class);
    when(searchResult.getAggregations()).thenReturn(metricAggregation);
    when(metricAggregation.getTermsAggregation(TAG_TYPE_FACET_AGGS)).thenReturn(termsAggregation);
    List<TermsAggregation.Entry> buckets = new ArrayList<>();
    TermsAggregation.Entry entry1 = mock(TermsAggregation.Entry.class);
    TermsAggregation.Entry entry2 = mock(TermsAggregation.Entry.class);
    buckets.add(entry1);
    buckets.add(entry2);
    when(termsAggregation.getBuckets()).thenReturn(buckets);
    // Call the method under test
    IndexSearchResponse indexSearchResponse = indexSearchDao.indexSearch(indexSearchRequest, fields, match, BUSINESS_OBJECT_DEFINITION_SEARCH_INDEX_NAME, TAG_SEARCH_INDEX_NAME);
    List<IndexSearchResult> indexSearchResults = indexSearchResponse.getIndexSearchResults();
    assertThat("Index search results list is null.", indexSearchResults, not(nullValue()));
    assertThat(indexSearchResponse.getTotalIndexSearchResults(), is(200L));
    // Verify external method calls.
    verify(herdSearchQueryHelper).determineNegationTermsPresent(indexSearchRequest);
    verify(herdSearchQueryHelper).extractNegationTerms(indexSearchRequest);
    verify(herdSearchQueryHelper).extractSearchPhrase(indexSearchRequest);
    verify(configurationHelper).getProperty(ConfigurationValue.TAG_SHORT_DESCRIPTION_LENGTH, Integer.class);
    verify(configurationHelper).getProperty(ConfigurationValue.BUSINESS_OBJECT_DEFINITION_SHORT_DESCRIPTION_LENGTH, Integer.class);
    verify(configurationHelper, times(3)).getProperty(ConfigurationValue.ELASTICSEARCH_SEARCHABLE_FIELDS_STEMMED);
    verify(configurationHelper).getProperty(ConfigurationValue.ELASTICSEARCH_SEARCHABLE_FIELDS_NGRAMS);
    verify(configurationHelper).getProperty(ConfigurationValue.ELASTICSEARCH_SEARCHABLE_FIELDS_SHINGLES);
    verify(configurationHelper).getProperty(ConfigurationValue.ELASTICSEARCH_PHRASE_PREFIX_QUERY_BOOST, Float.class);
    verify(configurationHelper).getProperty(ConfigurationValue.ELASTICSEARCH_BEST_FIELDS_QUERY_BOOST, Float.class);
    verify(configurationHelper, times(2)).getProperty(ConfigurationValue.ELASTICSEARCH_PHRASE_QUERY_BOOST, Float.class);
    verify(configurationHelper, times(5)).getProperty(ConfigurationValue.ELASTICSEARCH_PHRASE_QUERY_SLOP, Integer.class);
    verify(jsonHelper, times(5)).unmarshallJsonToObject(Map.class, "{\"displayName\":\"1.0\"}");
    if (CollectionUtils.isNotEmpty(indexSearchRequest.getIndexSearchFilters())) {
        verify(elasticsearchHelper).addIndexSearchFilterBooleanClause(indexSearchRequest.getIndexSearchFilters(), BUSINESS_OBJECT_DEFINITION_SEARCH_INDEX_NAME, TAG_SEARCH_INDEX_NAME);
    }
    if (indexSearchRequest.isEnableHitHighlighting() != null) {
        verifyHitHighlightingInteractions(searchRequestBuilder, indexSearchRequest.isEnableHitHighlighting(), match);
    }
    if (CollectionUtils.isNotEmpty(indexSearchRequest.getFacetFields())) {
        verify(elasticsearchHelper).addFacetFieldAggregations(any(), any(SearchRequestBuilder.class));
        if (indexSearchRequest.getFacetFields().contains(ElasticsearchHelper.TAG_FACET)) {
            verify(elasticsearchHelper).getNestedTagTagIndexSearchResponseDto(searchResult);
            verify(elasticsearchHelper).getTagTagIndexSearchResponseDto(searchResult);
        }
        if (indexSearchRequest.getFacetFields().contains(ElasticsearchHelper.RESULT_TYPE_FACET)) {
            verify(elasticsearchHelper).getResultTypeIndexSearchResponseDto(searchResult);
        }
        verify(elasticsearchHelper).getFacetsResponse(any(ElasticsearchResponseDto.class), eq(BUSINESS_OBJECT_DEFINITION_SEARCH_INDEX_NAME), eq(TAG_SEARCH_INDEX_NAME));
    }
    verify(jestClientHelper).searchExecute(any());
    verify(searchResult).getTotal();
    verify(searchResult).getHits(Map.class);
    verifyNoMoreInteractions(searchRequestBuilder, searchRequestBuilderWithSource, searchRequestBuilderWithSize, searchRequestBuilderWithSorting, searchRequestBuilderWithHighlighting, searchResponse, searchHits, searchHit1, searchHit2, searchShardTarget1, searchShardTarget2, highlightField, listenableActionFuture, searchResult, metricAggregation, termsAggregation, entry1, entry2);
    verifyNoMoreInteractionsHelper();
}
Also used : SortBuilder(org.elasticsearch.search.sort.SortBuilder) HashMap(java.util.HashMap) TagIndexSearchResponseDto(org.finra.herd.model.dto.TagIndexSearchResponseDto) ArrayList(java.util.ArrayList) SearchSourceBuilder(org.elasticsearch.search.builder.SearchSourceBuilder) ResultTypeIndexSearchResponseDto(org.finra.herd.model.dto.ResultTypeIndexSearchResponseDto) IndexSearchResult(org.finra.herd.model.api.xml.IndexSearchResult) List(java.util.List) ArrayList(java.util.ArrayList) TermsAggregation(io.searchbox.core.search.aggregation.TermsAggregation) MetricAggregation(io.searchbox.core.search.aggregation.MetricAggregation) SearchResponse(org.elasticsearch.action.search.SearchResponse) IndexSearchResponse(org.finra.herd.model.api.xml.IndexSearchResponse) Map(java.util.Map) HashMap(java.util.HashMap) SearchHit(org.elasticsearch.search.SearchHit) Gson(com.google.gson.Gson) IndexSearchRequest(org.finra.herd.model.api.xml.IndexSearchRequest) IndexSearchResponse(org.finra.herd.model.api.xml.IndexSearchResponse) IndexSearchHighlightFields(org.finra.herd.model.dto.IndexSearchHighlightFields) TagTypeIndexSearchResponseDto(org.finra.herd.model.dto.TagTypeIndexSearchResponseDto) SearchHits(org.elasticsearch.search.SearchHits) IndexSearchHighlightField(org.finra.herd.model.dto.IndexSearchHighlightField) SearchRequestBuilder(org.elasticsearch.action.search.SearchRequestBuilder) HighlightField(org.elasticsearch.search.fetch.subphase.highlight.HighlightField) IndexSearchHighlightField(org.finra.herd.model.dto.IndexSearchHighlightField) Text(org.elasticsearch.common.text.Text) IndexSearchResult(org.finra.herd.model.api.xml.IndexSearchResult) SearchResult(io.searchbox.core.SearchResult) IOException(java.io.IOException) SearchHit(org.elasticsearch.search.SearchHit) JsonElement(com.google.gson.JsonElement) SearchShardTarget(org.elasticsearch.search.SearchShardTarget) ElasticsearchResponseDto(org.finra.herd.model.dto.ElasticsearchResponseDto) HighlightBuilder(org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder)

Example 2 with IndexSearchResult

use of org.finra.herd.model.api.xml.IndexSearchResult in project herd by FINRAOS.

the class IndexSearchDaoImpl method buildIndexSearchResults.

/**
 * Extracts and builds a list of {@link IndexSearchResult}s from a given {@link SearchResult}
 *
 * @param fields the specified fields to be included in the response
 * @param tagActiveIndex the name of the active tag index
 * @param bdefActiveIndex the name of the active business object definition index
 * @param searchResult the raw search result returned by the elasticsearch client
 * @param isHighlightingEnabled boolean which specifies if highlighting is requested or not
 *
 * @return A {@link List} of {@link IndexSearchResult} which represent the search response
 */
private List<IndexSearchResult> buildIndexSearchResults(Set<String> fields, String tagActiveIndex, String bdefActiveIndex, SearchResult searchResult, Boolean isHighlightingEnabled) {
    final Integer tagShortDescMaxLength = configurationHelper.getProperty(ConfigurationValue.TAG_SHORT_DESCRIPTION_LENGTH, Integer.class);
    final Integer businessObjectDefinitionShortDescMaxLength = configurationHelper.getProperty(ConfigurationValue.BUSINESS_OBJECT_DEFINITION_SHORT_DESCRIPTION_LENGTH, Integer.class);
    List<IndexSearchResult> indexSearchResults = new ArrayList<>();
    final List<SearchResult.Hit<Map, Void>> searchHitList = searchResult.getHits(Map.class);
    // For each indexSearch hit
    for (final SearchResult.Hit<Map, Void> hit : searchHitList) {
        // Get the source map from the indexSearch hit
        @SuppressWarnings("unchecked") final Map<String, Object> sourceMap = hit.source;
        // Get the index from which this result is from
        final String index = hit.index;
        // Create a new document to populate with the indexSearch results
        final IndexSearchResult indexSearchResult = new IndexSearchResult();
        // Populate the results
        indexSearchResult.setSearchIndexKey(new SearchIndexKey(index));
        if (fields.contains(DISPLAY_NAME_FIELD)) {
            indexSearchResult.setDisplayName((String) sourceMap.get(DISPLAY_NAME_SOURCE));
        }
        // Populate tag index specific key
        if (index.equals(tagActiveIndex)) {
            if (fields.contains(SHORT_DESCRIPTION_FIELD)) {
                indexSearchResult.setShortDescription(HerdStringUtils.getShortDescription((String) sourceMap.get(DESCRIPTION_SOURCE), tagShortDescMaxLength));
            }
            final TagKey tagKey = new TagKey();
            tagKey.setTagCode((String) sourceMap.get(TAG_CODE_SOURCE));
            tagKey.setTagTypeCode((String) ((Map) sourceMap.get(TAG_TYPE)).get(CODE));
            indexSearchResult.setIndexSearchResultType(SearchIndexTypeEntity.SearchIndexTypes.TAG.name());
            indexSearchResult.setIndexSearchResultKey(new IndexSearchResultKey(tagKey, null));
        } else // Populate business object definition key
        if (index.equals(bdefActiveIndex)) {
            if (fields.contains(SHORT_DESCRIPTION_FIELD)) {
                indexSearchResult.setShortDescription(HerdStringUtils.getShortDescription((String) sourceMap.get(DESCRIPTION_SOURCE), businessObjectDefinitionShortDescMaxLength));
            }
            final BusinessObjectDefinitionKey businessObjectDefinitionKey = new BusinessObjectDefinitionKey();
            businessObjectDefinitionKey.setNamespace((String) ((Map) sourceMap.get(NAMESPACE)).get(CODE));
            businessObjectDefinitionKey.setBusinessObjectDefinitionName((String) sourceMap.get(NAME_SOURCE));
            indexSearchResult.setIndexSearchResultType(SearchIndexTypeEntity.SearchIndexTypes.BUS_OBJCT_DFNTN.name());
            indexSearchResult.setIndexSearchResultKey(new IndexSearchResultKey(null, businessObjectDefinitionKey));
        } else {
            throw new IllegalStateException(String.format("Search result index name \"%s\" does not match any of the active search indexes. tagActiveIndex=%s bdefActiveIndex=%s", index, tagActiveIndex, bdefActiveIndex));
        }
        if (BooleanUtils.isTrue(isHighlightingEnabled)) {
            // Fetch configured 'tag' values for highlighting
            String preTag = configurationHelper.getProperty(ConfigurationValue.ELASTICSEARCH_HIGHLIGHT_PRETAGS);
            String postTag = configurationHelper.getProperty(ConfigurationValue.ELASTICSEARCH_HIGHLIGHT_POSTTAGS);
            // Extract highlighted content from the search hit and clean html tags except the pre/post-tags as configured
            Highlight highlightedContent = extractHighlightedContent(hit, preTag, postTag);
            // Set highlighted content in the response element
            indexSearchResult.setHighlight(highlightedContent);
        }
        indexSearchResults.add(indexSearchResult);
    }
    return indexSearchResults;
}
Also used : Highlight(org.finra.herd.model.api.xml.Highlight) BusinessObjectDefinitionKey(org.finra.herd.model.api.xml.BusinessObjectDefinitionKey) ArrayList(java.util.ArrayList) IndexSearchResult(org.finra.herd.model.api.xml.IndexSearchResult) SearchResult(io.searchbox.core.SearchResult) IndexSearchResultKey(org.finra.herd.model.api.xml.IndexSearchResultKey) SearchHit(org.elasticsearch.search.SearchHit) SearchIndexKey(org.finra.herd.model.api.xml.SearchIndexKey) TagKey(org.finra.herd.model.api.xml.TagKey) IndexSearchResult(org.finra.herd.model.api.xml.IndexSearchResult) Map(java.util.Map) HashMap(java.util.HashMap)

Example 3 with IndexSearchResult

use of org.finra.herd.model.api.xml.IndexSearchResult in project herd by FINRAOS.

the class IndexSearchDaoImpl method indexSearch.

@Override
public IndexSearchResponse indexSearch(final IndexSearchRequest indexSearchRequest, final Set<String> fields, final Set<String> match, final String bdefActiveIndex, final String tagActiveIndex) {
    boolean negationTermsExist = herdSearchQueryHelper.determineNegationTermsPresent(indexSearchRequest);
    // Build a basic Boolean query upon which add all the necessary clauses as needed
    BoolQueryBuilder indexSearchQueryBuilder = QueryBuilders.boolQuery();
    String searchPhrase = indexSearchRequest.getSearchTerm();
    // Add the negation queries builder within a 'must-not' clause to the parent bool query if negation terms exist
    if (negationTermsExist) {
        // Build negation queries- each term is added to the query with a 'must-not' clause,
        List<String> negationTerms = herdSearchQueryHelper.extractNegationTerms(indexSearchRequest);
        if (CollectionUtils.isNotEmpty(negationTerms)) {
            negationTerms.forEach(term -> {
                indexSearchQueryBuilder.mustNot(buildMultiMatchQuery(term, PHRASE, 100f, FIELD_TYPE_STEMMED, match));
            });
        }
        // Remove the negation terms from the search phrase
        searchPhrase = herdSearchQueryHelper.extractSearchPhrase(indexSearchRequest);
    }
    // Build a Dismax query with three primary components (multi-match queries) with boost values, these values can be configured in the
    // DB which provides a way to dynamically tune search behavior at runtime:
    // 1. Phrase match query on shingles fields.
    // 2. Phrase prefix query on stemmed fields.
    // 3. Best fields query on ngrams fields.
    final MultiMatchQueryBuilder phrasePrefixMultiMatchQueryBuilder = buildMultiMatchQuery(searchPhrase, PHRASE_PREFIX, configurationHelper.getProperty(ConfigurationValue.ELASTICSEARCH_PHRASE_PREFIX_QUERY_BOOST, Float.class), FIELD_TYPE_STEMMED, match);
    final MultiMatchQueryBuilder bestFieldsMultiMatchQueryBuilder = buildMultiMatchQuery(searchPhrase, BEST_FIELDS, configurationHelper.getProperty(ConfigurationValue.ELASTICSEARCH_BEST_FIELDS_QUERY_BOOST, Float.class), FIELD_TYPE_NGRAMS, match);
    final MultiMatchQueryBuilder phraseMultiMatchQueryBuilder = buildMultiMatchQuery(searchPhrase, PHRASE, configurationHelper.getProperty(ConfigurationValue.ELASTICSEARCH_PHRASE_QUERY_BOOST, Float.class), FIELD_TYPE_SHINGLES, match);
    final MultiMatchQueryBuilder phraseStemmedMultiMatchQueryBuilder = buildMultiMatchQuery(searchPhrase, PHRASE, configurationHelper.getProperty(ConfigurationValue.ELASTICSEARCH_PHRASE_QUERY_BOOST, Float.class), FIELD_TYPE_STEMMED, match);
    // Add the multi match queries to a dis max query and add to the parent bool query within a 'must' clause
    indexSearchQueryBuilder.must(disMaxQuery().add(phrasePrefixMultiMatchQueryBuilder).add(bestFieldsMultiMatchQueryBuilder).add(phraseMultiMatchQueryBuilder).add(phraseStemmedMultiMatchQueryBuilder));
    // Add filter clauses if index search filters are specified in the request
    if (CollectionUtils.isNotEmpty(indexSearchRequest.getIndexSearchFilters())) {
        indexSearchQueryBuilder.filter(elasticsearchHelper.addIndexSearchFilterBooleanClause(indexSearchRequest.getIndexSearchFilters(), bdefActiveIndex, tagActiveIndex));
    }
    // Get function score query builder
    FunctionScoreQueryBuilder functionScoreQueryBuilder = getFunctionScoreQueryBuilder(indexSearchQueryBuilder, bdefActiveIndex);
    // The fields in the search indexes to return
    final String[] searchSources = { NAME_SOURCE, NAMESPACE_CODE_SOURCE, TAG_CODE_SOURCE, TAG_TYPE_CODE_SOURCE, DISPLAY_NAME_SOURCE, DESCRIPTION_SOURCE, BDEF_TAGS_SOURCE, BDEF_TAGS_SEARCH_SCORE_MULTIPLIER };
    // Create a new indexSearch source builder
    final SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    // Fetch only the required fields
    searchSourceBuilder.fetchSource(searchSources, null);
    searchSourceBuilder.query(functionScoreQueryBuilder);
    // Create a indexSearch request builder
    SearchRequestBuilder searchRequestBuilder = new SearchRequestBuilder(new ElasticsearchClientImpl(), SearchAction.INSTANCE);
    searchRequestBuilder.setIndices(bdefActiveIndex, tagActiveIndex);
    searchRequestBuilder.setSource(searchSourceBuilder).setSize(SEARCH_RESULT_SIZE).addSort(SortBuilders.scoreSort());
    // Add highlighting if specified in the request
    if (BooleanUtils.isTrue(indexSearchRequest.isEnableHitHighlighting())) {
        // Fetch configured 'tag' values for highlighting
        String preTag = configurationHelper.getProperty(ConfigurationValue.ELASTICSEARCH_HIGHLIGHT_PRETAGS);
        String postTag = configurationHelper.getProperty(ConfigurationValue.ELASTICSEARCH_HIGHLIGHT_POSTTAGS);
        searchRequestBuilder.highlighter(buildHighlightQuery(preTag, postTag, match));
    }
    // Add facet aggregations if specified in the request
    if (CollectionUtils.isNotEmpty(indexSearchRequest.getFacetFields())) {
        searchRequestBuilder = elasticsearchHelper.addFacetFieldAggregations(new HashSet<>(indexSearchRequest.getFacetFields()), searchRequestBuilder);
    }
    // Log the actual elasticsearch query when debug is enabled
    LOGGER.debug("indexSearchRequest={}", searchRequestBuilder.toString());
    // Retrieve the indexSearch response
    final Search.Builder searchBuilder = new Search.Builder(searchRequestBuilder.toString()).addIndices(Arrays.asList(bdefActiveIndex, tagActiveIndex));
    final SearchResult searchResult = jestClientHelper.searchExecute(searchBuilder.build());
    final List<IndexSearchResult> indexSearchResults = buildIndexSearchResults(fields, tagActiveIndex, bdefActiveIndex, searchResult, indexSearchRequest.isEnableHitHighlighting());
    List<Facet> facets = null;
    if (CollectionUtils.isNotEmpty(indexSearchRequest.getFacetFields())) {
        // Extract facets from the search response
        facets = new ArrayList<>(extractFacets(indexSearchRequest, searchResult, bdefActiveIndex, tagActiveIndex));
    }
    return new IndexSearchResponse(searchResult.getTotal(), indexSearchResults, facets);
}
Also used : SearchRequestBuilder(org.elasticsearch.action.search.SearchRequestBuilder) IndexSearchResult(org.finra.herd.model.api.xml.IndexSearchResult) SearchResult(io.searchbox.core.SearchResult) MultiMatchQueryBuilder(org.elasticsearch.index.query.MultiMatchQueryBuilder) ElasticsearchClientImpl(org.finra.herd.dao.helper.ElasticsearchClientImpl) SearchSourceBuilder(org.elasticsearch.search.builder.SearchSourceBuilder) FunctionScoreQueryBuilder(org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder) BoolQueryBuilder(org.elasticsearch.index.query.BoolQueryBuilder) Search(io.searchbox.core.Search) IndexSearchResponse(org.finra.herd.model.api.xml.IndexSearchResponse) IndexSearchResult(org.finra.herd.model.api.xml.IndexSearchResult) HashSet(java.util.HashSet) Facet(org.finra.herd.model.api.xml.Facet)

Example 4 with IndexSearchResult

use of org.finra.herd.model.api.xml.IndexSearchResult in project herd by FINRAOS.

the class IndexSearchServiceTest method testIndexSearchWithResultTypeFilter.

@Test
public void testIndexSearchWithResultTypeFilter() {
    // Create an index search key
    final IndexSearchKey indexSearchKey = new IndexSearchKey();
    // Create a tag key
    final IndexSearchResultTypeKey resultTypeKey = new IndexSearchResultTypeKey(SearchIndexTypeEntity.SearchIndexTypes.BUS_OBJCT_DFNTN.name());
    indexSearchKey.setIndexSearchResultTypeKey(resultTypeKey);
    // Create an index search keys list and add the previously defined key to it
    final List<IndexSearchKey> indexSearchKeys = Collections.singletonList(indexSearchKey);
    // Create an index search filter with the keys previously defined
    final IndexSearchFilter indexSearchFilter = new IndexSearchFilter(EXCLUSION_SEARCH_FILTER, indexSearchKeys);
    List<IndexSearchFilter> indexSearchFilters = Collections.singletonList(indexSearchFilter);
    // Create index search request
    final IndexSearchRequest indexSearchRequest = new IndexSearchRequest(SEARCH_TERM, indexSearchFilters, null, false);
    // Create a set of fields.
    final Set<String> fields = Sets.newHashSet(FIELD_DISPLAY_NAME, FIELD_SHORT_DESCRIPTION);
    // Create a new index search result key and populate it with a tag key
    final IndexSearchResultKey indexSearchResultKeyBusinessObjectDefinition = new IndexSearchResultKey(null, new BusinessObjectDefinitionKey(NAMESPACE, BDEF_NAME));
    // Create a new index search result key and populate it with a tag key
    final IndexSearchResultKey indexSearchResultKeyTag = new IndexSearchResultKey(new TagKey(TAG_TYPE, TAG_CODE), null);
    // Create a new index search results
    final IndexSearchResult indexSearchResultBusinessObjectDefinition = new IndexSearchResult(SearchIndexTypeEntity.SearchIndexTypes.BUS_OBJCT_DFNTN.name(), new SearchIndexKey(BUSINESS_OBJECT_DEFINITION_SEARCH_INDEX_NAME), indexSearchResultKeyBusinessObjectDefinition, BDEF_DISPLAY_NAME, BDEF_SHORT_DESCRIPTION, null);
    final IndexSearchResult indexSearchResultTag = new IndexSearchResult(SearchIndexTypeEntity.SearchIndexTypes.TAG.name(), new SearchIndexKey(TAG_SEARCH_INDEX_NAME), indexSearchResultKeyTag, TAG_DISPLAY_NAME, TAG_DESCRIPTION, null);
    // Create a list to contain the index search results
    final List<IndexSearchResult> indexSearchResults = new ArrayList<>();
    indexSearchResults.add(indexSearchResultBusinessObjectDefinition);
    indexSearchResults.add(indexSearchResultTag);
    // Construct an index search response
    final IndexSearchResponse indexSearchResponse = new IndexSearchResponse(TOTAL_INDEX_SEARCH_RESULTS, indexSearchResults, null);
    // Mock the call to the index search service
    when(alternateKeyHelper.validateStringParameter("An", "index search result type", SearchIndexTypeEntity.SearchIndexTypes.BUS_OBJCT_DFNTN.name())).thenReturn(SearchIndexTypeEntity.SearchIndexTypes.BUS_OBJCT_DFNTN.name());
    when(searchIndexDaoHelper.getActiveSearchIndex(SearchIndexTypeEntity.SearchIndexTypes.BUS_OBJCT_DFNTN.name())).thenReturn(SEARCH_INDEX_NAME);
    when(searchIndexDaoHelper.getActiveSearchIndex(SearchIndexTypeEntity.SearchIndexTypes.TAG.name())).thenReturn(SEARCH_INDEX_NAME_2);
    when(indexSearchDao.indexSearch(indexSearchRequest, fields, NO_MATCH, SEARCH_INDEX_NAME, SEARCH_INDEX_NAME_2)).thenReturn(indexSearchResponse);
    // Call the method under test.
    IndexSearchResponse result = indexSearchService.indexSearch(indexSearchRequest, fields, NO_MATCH);
    // Verify the external calls.
    verify(alternateKeyHelper).validateStringParameter("An", "index search result type", SearchIndexTypeEntity.SearchIndexTypes.BUS_OBJCT_DFNTN.name());
    verify(searchIndexTypeDaoHelper).getSearchIndexTypeEntity(SearchIndexTypeEntity.SearchIndexTypes.BUS_OBJCT_DFNTN.name());
    verify(searchIndexDaoHelper).getActiveSearchIndex(SearchIndexTypeEntity.SearchIndexTypes.BUS_OBJCT_DFNTN.name());
    verify(searchIndexDaoHelper).getActiveSearchIndex(SearchIndexTypeEntity.SearchIndexTypes.TAG.name());
    verify(indexSearchDao).indexSearch(indexSearchRequest, fields, NO_MATCH, SEARCH_INDEX_NAME, SEARCH_INDEX_NAME_2);
    verifyNoMoreInteractionsHelper();
    // Validate the result.
    assertEquals(indexSearchResponse, result);
}
Also used : IndexSearchKey(org.finra.herd.model.api.xml.IndexSearchKey) BusinessObjectDefinitionKey(org.finra.herd.model.api.xml.BusinessObjectDefinitionKey) ArrayList(java.util.ArrayList) IndexSearchResultTypeKey(org.finra.herd.model.api.xml.IndexSearchResultTypeKey) IndexSearchRequest(org.finra.herd.model.api.xml.IndexSearchRequest) IndexSearchResultKey(org.finra.herd.model.api.xml.IndexSearchResultKey) SearchIndexKey(org.finra.herd.model.api.xml.SearchIndexKey) IndexSearchResponse(org.finra.herd.model.api.xml.IndexSearchResponse) TagKey(org.finra.herd.model.api.xml.TagKey) IndexSearchResult(org.finra.herd.model.api.xml.IndexSearchResult) IndexSearchFilter(org.finra.herd.model.api.xml.IndexSearchFilter) Test(org.junit.Test)

Example 5 with IndexSearchResult

use of org.finra.herd.model.api.xml.IndexSearchResult in project herd by FINRAOS.

the class IndexSearchServiceTest method testIndexSearchWithMatch.

@Test
public void testIndexSearchWithMatch() {
    // Create a tag key.
    TagKey tagKey = new TagKey(TAG_TYPE_CODE, TAG_CODE);
    // Create an index search request.
    final IndexSearchRequest indexSearchRequest = new IndexSearchRequest(SEARCH_TERM, ImmutableList.of(new IndexSearchFilter(EXCLUSION_SEARCH_FILTER, ImmutableList.of(new IndexSearchKey(tagKey, NO_INDEX_SEARCH_RESULT_TYPE_KEY))), new IndexSearchFilter(EXCLUSION_SEARCH_FILTER, ImmutableList.of(new IndexSearchKey(NO_TAG_KEY, new IndexSearchResultTypeKey(INDEX_SEARCH_RESULT_TYPE))))), Collections.singletonList(ElasticsearchHelper.TAG_FACET), ENABLE_HIT_HIGHLIGHTING);
    // Create a set of fields.
    final Set<String> fields = Sets.newHashSet(FIELD_DISPLAY_NAME, FIELD_SHORT_DESCRIPTION);
    // Create a set of match fields.
    final Set<String> match = Sets.newHashSet(MATCH_COLUMN);
    // Create a new index search result key and populate it with a tag key
    final IndexSearchResultKey indexSearchResultKeyBusinessObjectDefinition = new IndexSearchResultKey(null, new BusinessObjectDefinitionKey(NAMESPACE, BDEF_NAME));
    // Create a new index search result key and populate it with a tag key
    final IndexSearchResultKey indexSearchResultKeyTag = new IndexSearchResultKey(new TagKey(TAG_TYPE, TAG_CODE), null);
    // Create a new index search results
    final IndexSearchResult indexSearchResultBusinessObjectDefinition = new IndexSearchResult(SearchIndexTypeEntity.SearchIndexTypes.BUS_OBJCT_DFNTN.name(), new SearchIndexKey(BUSINESS_OBJECT_DEFINITION_SEARCH_INDEX_NAME), indexSearchResultKeyBusinessObjectDefinition, BDEF_DISPLAY_NAME, BDEF_SHORT_DESCRIPTION, null);
    final IndexSearchResult indexSearchResultTag = new IndexSearchResult(SearchIndexTypeEntity.SearchIndexTypes.TAG.name(), new SearchIndexKey(TAG_SEARCH_INDEX_NAME), indexSearchResultKeyTag, TAG_DISPLAY_NAME, TAG_DESCRIPTION, null);
    // Create a list to contain the index search results
    final List<IndexSearchResult> indexSearchResults = new ArrayList<>();
    indexSearchResults.add(indexSearchResultBusinessObjectDefinition);
    indexSearchResults.add(indexSearchResultTag);
    // Construct an index search response
    final IndexSearchResponse indexSearchResponse = new IndexSearchResponse(TOTAL_INDEX_SEARCH_RESULTS, indexSearchResults, null);
    // Construct a search index entity
    SearchIndexTypeEntity searchIndexTypeEntity = new SearchIndexTypeEntity();
    searchIndexTypeEntity.setCode(SearchIndexTypeEntity.SearchIndexTypes.BUS_OBJCT_DFNTN.name());
    // Create a tag type entity.
    TagTypeEntity tagTypeEntity = new TagTypeEntity();
    tagTypeEntity.setCode(tagKey.getTagTypeCode());
    // Create a tag entity.
    TagEntity tagEntity = new TagEntity();
    tagEntity.setTagCode(tagKey.getTagCode());
    tagEntity.setTagType(tagTypeEntity);
    // Mock the call to the index search service
    when(tagDaoHelper.getTagEntity(tagKey)).thenReturn(tagEntity);
    when(alternateKeyHelper.validateStringParameter("An", "index search result type", INDEX_SEARCH_RESULT_TYPE)).thenReturn(INDEX_SEARCH_RESULT_TYPE);
    when(searchIndexDaoHelper.getActiveSearchIndex(SearchIndexTypeEntity.SearchIndexTypes.BUS_OBJCT_DFNTN.name())).thenReturn(SEARCH_INDEX_NAME);
    when(searchIndexDaoHelper.getActiveSearchIndex(SearchIndexTypeEntity.SearchIndexTypes.TAG.name())).thenReturn(SEARCH_INDEX_NAME_2);
    when(indexSearchDao.indexSearch(indexSearchRequest, fields, match, SEARCH_INDEX_NAME, SEARCH_INDEX_NAME_2)).thenReturn(indexSearchResponse);
    // Call the method under test.
    IndexSearchResponse result = indexSearchService.indexSearch(indexSearchRequest, fields, match);
    // Verify the external calls.
    verify(tagHelper).validateTagKey(tagKey);
    verify(tagDaoHelper).getTagEntity(tagKey);
    verify(alternateKeyHelper).validateStringParameter("An", "index search result type", INDEX_SEARCH_RESULT_TYPE);
    verify(searchIndexTypeDaoHelper).getSearchIndexTypeEntity(INDEX_SEARCH_RESULT_TYPE);
    verify(indexSearchDao).indexSearch(indexSearchRequest, fields, match, SEARCH_INDEX_NAME, SEARCH_INDEX_NAME_2);
    verify(searchIndexDaoHelper).getActiveSearchIndex(SearchIndexTypeEntity.SearchIndexTypes.BUS_OBJCT_DFNTN.name());
    verify(searchIndexDaoHelper).getActiveSearchIndex(SearchIndexTypeEntity.SearchIndexTypes.TAG.name());
    verifyNoMoreInteractionsHelper();
    // Validate the result.
    assertEquals(indexSearchResponse, result);
}
Also used : IndexSearchKey(org.finra.herd.model.api.xml.IndexSearchKey) BusinessObjectDefinitionKey(org.finra.herd.model.api.xml.BusinessObjectDefinitionKey) ArrayList(java.util.ArrayList) TagTypeEntity(org.finra.herd.model.jpa.TagTypeEntity) IndexSearchResultTypeKey(org.finra.herd.model.api.xml.IndexSearchResultTypeKey) IndexSearchRequest(org.finra.herd.model.api.xml.IndexSearchRequest) SearchIndexTypeEntity(org.finra.herd.model.jpa.SearchIndexTypeEntity) IndexSearchResultKey(org.finra.herd.model.api.xml.IndexSearchResultKey) SearchIndexKey(org.finra.herd.model.api.xml.SearchIndexKey) TagEntity(org.finra.herd.model.jpa.TagEntity) IndexSearchResponse(org.finra.herd.model.api.xml.IndexSearchResponse) TagKey(org.finra.herd.model.api.xml.TagKey) IndexSearchResult(org.finra.herd.model.api.xml.IndexSearchResult) IndexSearchFilter(org.finra.herd.model.api.xml.IndexSearchFilter) Test(org.junit.Test)

Aggregations

IndexSearchResult (org.finra.herd.model.api.xml.IndexSearchResult)7 ArrayList (java.util.ArrayList)6 IndexSearchResponse (org.finra.herd.model.api.xml.IndexSearchResponse)6 BusinessObjectDefinitionKey (org.finra.herd.model.api.xml.BusinessObjectDefinitionKey)5 IndexSearchRequest (org.finra.herd.model.api.xml.IndexSearchRequest)5 IndexSearchResultKey (org.finra.herd.model.api.xml.IndexSearchResultKey)5 SearchIndexKey (org.finra.herd.model.api.xml.SearchIndexKey)5 TagKey (org.finra.herd.model.api.xml.TagKey)5 SearchResult (io.searchbox.core.SearchResult)3 IndexSearchFilter (org.finra.herd.model.api.xml.IndexSearchFilter)3 IndexSearchKey (org.finra.herd.model.api.xml.IndexSearchKey)3 IndexSearchResultTypeKey (org.finra.herd.model.api.xml.IndexSearchResultTypeKey)3 SearchIndexTypeEntity (org.finra.herd.model.jpa.SearchIndexTypeEntity)3 Test (org.junit.Test)3 HashMap (java.util.HashMap)2 Map (java.util.Map)2 SearchRequestBuilder (org.elasticsearch.action.search.SearchRequestBuilder)2 SearchHit (org.elasticsearch.search.SearchHit)2 SearchSourceBuilder (org.elasticsearch.search.builder.SearchSourceBuilder)2 TagEntity (org.finra.herd.model.jpa.TagEntity)2