private static HighlightBuilder.Field createHighlighterField() { HighlightBuilder.Field field = new HighlightBuilder.Field(FIELD_NAME); field.highlighterType("fvh"); field.matchedFields( Stream.concat( Stream.of(FIELD_NAME), Arrays .stream(NAME_ANALYZERS) .map(a -> a.subField(FIELD_NAME))) .toArray(String[]::new)); return field; }
@Override QueryBuilder getQuery(String queryText) { String lowerCaseQueryText = queryText.toLowerCase(Locale.ENGLISH); return prefixAndPartialQuery(lowerCaseQueryText, SORTABLE_ANALYZER.subField(FIELD_NAME), FIELD_NAME) .boost(3f); } },
protected MatchQueryBuilder tokenQuery(String queryTerm, String fieldName, DefaultIndexSettingsElement analyzer) { // We will truncate the search to the maximum length of nGrams in the index. // Otherwise the search would for sure not find any results. String truncatedQuery = StringUtils.left(queryTerm, DefaultIndexSettings.MAXIMUM_NGRAM_LENGTH); return matchQuery(analyzer.subField(fieldName), truncatedQuery); }
protected MatchQueryBuilder partialTermQuery(String queryTerm, String fieldName) { // We will truncate the search to the maximum length of nGrams in the index. // Otherwise the search would for sure not find any results. String truncatedQuery = StringUtils.left(queryTerm, DefaultIndexSettings.MAXIMUM_NGRAM_LENGTH); return matchQuery(SEARCH_GRAMS_ANALYZER.subField(fieldName), truncatedQuery); } }
@Override QueryBuilder getQuery(String queryText) { return matchQuery(SORTABLE_ANALYZER.subField(FIELD_KEY), queryText) .boost(50f); } };
@Override QueryBuilder getQuery(String queryText) { return matchQuery(SORTABLE_ANALYZER.subField(FIELD_NAME), queryText) .boost(2.5f); } },
private static QueryBuilder termQuery(String field, String query, float boost) { return QueryBuilders.multiMatchQuery(query, field, SEARCH_WORDS_ANALYZER.subField(field)) .operator(Operator.AND) .boost(boost); }
private static void addSort(ProjectMeasuresQuery query, SearchRequestBuilder requestBuilder) { String sort = query.getSort(); if (SORT_BY_NAME.equals(sort)) { requestBuilder.addSort(DefaultIndexSettingsElement.SORTABLE_ANALYZER.subField(FIELD_NAME), query.isAsc() ? ASC : DESC); } else if (SORT_BY_LAST_ANALYSIS_DATE.equals(sort)) { requestBuilder.addSort(FIELD_ANALYSED_AT, query.isAsc() ? ASC : DESC); } else if (ALERT_STATUS_KEY.equals(sort)) { requestBuilder.addSort(FIELD_QUALITY_GATE_STATUS, query.isAsc() ? ASC : DESC); requestBuilder.addSort(DefaultIndexSettingsElement.SORTABLE_ANALYZER.subField(FIELD_NAME), ASC); } else { addMetricSort(query, requestBuilder, sort); requestBuilder.addSort(DefaultIndexSettingsElement.SORTABLE_ANALYZER.subField(FIELD_NAME), ASC); } // last sort is by key in order to be deterministic when same value requestBuilder.addSort(FIELD_KEY, ASC); }
@Override public QueryBuilder getQuery(ComponentTextSearchQuery query) { return matchQuery(SORTABLE_ANALYZER.subField(query.getFieldName()), query.getQueryText()) .boost(2.5f); } },
@Override public QueryBuilder getQuery(ComponentTextSearchQuery query) { return matchQuery(SORTABLE_ANALYZER.subField(query.getFieldKey()), query.getQueryText()) .boost(50f); } },
private static QueryBuilder buildQuery(RuleQuery query) { // No contextual query case String queryText = query.getQueryText(); if (StringUtils.isEmpty(queryText)) { return matchAllQuery(); } // Build RuleBased contextual query BoolQueryBuilder qb = boolQuery(); String queryString = query.getQueryText(); if (queryString != null && !queryString.isEmpty()) { BoolQueryBuilder textQuery = boolQuery(); JavaTokenizer.split(queryString) .stream().map(token -> boolQuery().should( matchQuery( SEARCH_GRAMS_ANALYZER.subField(FIELD_RULE_NAME), StringUtils.left(token, DefaultIndexSettings.MAXIMUM_NGRAM_LENGTH)).boost(20f)) .should( matchPhraseQuery( ENGLISH_HTML_ANALYZER.subField(FIELD_RULE_HTML_DESCRIPTION), token).boost(3f))) .forEach(textQuery::must); qb.should(textQuery.boost(20f)); } // Match and partial Match queries // Search by key uses the "sortable" sub-field as it requires to be case-insensitive (lower-case filtering) qb.should(matchQuery(SORTABLE_ANALYZER.subField(FIELD_RULE_KEY), queryString).operator(Operator.AND).boost(30f)); qb.should(matchQuery(SORTABLE_ANALYZER.subField(FIELD_RULE_RULE_KEY), queryString).operator(Operator.AND).boost(15f)); qb.should(termQuery(FIELD_RULE_LANGUAGE, queryString, 3f)); return qb; }
public SearchResult<UserDoc> search(UserQuery userQuery, SearchOptions options) { SearchRequestBuilder request = esClient.prepareSearch(UserIndexDefinition.INDEX_TYPE_USER) .setSize(options.getLimit()) .setFrom(options.getOffset()) .addSort(FIELD_NAME, SortOrder.ASC); BoolQueryBuilder filter = boolQuery().must(termQuery(FIELD_ACTIVE, true)); userQuery.getOrganizationUuid() .ifPresent(o -> filter.must(termQuery(FIELD_ORGANIZATION_UUIDS, o))); userQuery.getExcludedOrganizationUuid() .ifPresent(o -> filter.mustNot(termQuery(FIELD_ORGANIZATION_UUIDS, o))); QueryBuilder esQuery = matchAllQuery(); Optional<String> textQuery = userQuery.getTextQuery(); if (textQuery.isPresent()) { esQuery = QueryBuilders.multiMatchQuery(textQuery.get(), FIELD_LOGIN, USER_SEARCH_GRAMS_ANALYZER.subField(FIELD_LOGIN), FIELD_NAME, USER_SEARCH_GRAMS_ANALYZER.subField(FIELD_NAME), FIELD_EMAIL, USER_SEARCH_GRAMS_ANALYZER.subField(FIELD_EMAIL)) .operator(Operator.AND); } request.setQuery(boolQuery().must(esQuery).filter(filter)); return new SearchResult<>(request.get(), UserDoc::new, system2.getDefaultTimeZone()); }
private List<AnalyzeResponse.AnalyzeToken> analyzeIndexedTokens(String text) { return tester.client().nativeClient().admin().indices().prepareAnalyze(INDEX_TYPE_RULE.getIndex(), text) .setField(ENGLISH_HTML_ANALYZER.subField(FIELD_RULE_HTML_DESCRIPTION)) .execute().actionGet().getTokens(); } }
/** * Returns the active users (at most 3) who are associated to the given SCM account. This method can be used * to detect user conflicts. */ public List<UserDoc> getAtMostThreeActiveUsersForScmAccount(String scmAccount, String organizationUuid) { List<UserDoc> result = new ArrayList<>(); if (!StringUtils.isEmpty(scmAccount)) { SearchRequestBuilder request = esClient.prepareSearch(UserIndexDefinition.INDEX_TYPE_USER) .setQuery(boolQuery().must(matchAllQuery()).filter( boolQuery() .must(termQuery(FIELD_ACTIVE, true)) .must(termQuery(FIELD_ORGANIZATION_UUIDS, organizationUuid)) .should(termQuery(FIELD_LOGIN, scmAccount)) .should(matchQuery(SORTABLE_ANALYZER.subField(FIELD_EMAIL), scmAccount)) .should(matchQuery(SORTABLE_ANALYZER.subField(FIELD_SCM_ACCOUNTS), scmAccount)))) .setSize(3); for (SearchHit hit : request.get().getHits().getHits()) { result.add(new UserDoc(hit.getSourceAsMap())); } } return result; }
@Test public void support_long_html_description() { String longText = StringUtils.repeat("The quick brown fox jumps over the lazy dog ", 700); List<AnalyzeResponse.AnalyzeToken> tokens = analyzeIndexedTokens(longText); assertThat(tokens).extracting(AnalyzeResponse.AnalyzeToken::getTerm).containsOnly( "quick", "brown", "fox", "jump", "over", "lazi", "dog"); // the following method fails if PUT fails tester.putDocuments(INDEX_TYPE_RULE, new RuleDoc(ImmutableMap.of( FIELD_RULE_ID, "123", FIELD_RULE_HTML_DESCRIPTION, longText, FIELD_RULE_REPOSITORY, "squid", FIELD_RULE_KEY, "squid:S001"))); assertThat(tester.countDocuments(INDEX_TYPE_RULE)).isEqualTo(1); assertThat(tester.client().prepareSearch(INDEX_TYPE_RULE.getIndex()).setQuery(matchQuery(ENGLISH_HTML_ANALYZER.subField(FIELD_RULE_HTML_DESCRIPTION), "brown fox jumps lazy")) .get().getHits().getTotalHits()).isEqualTo(1); }
private void assertThatComponentHasName(ComponentDto component, String expectedName) { SearchHit[] hits = es.client() .prepareSearch(INDEX_TYPE_COMPONENT) .setQuery(matchQuery(SORTABLE_ANALYZER.subField(FIELD_NAME), expectedName)) .get() .getHits() .getHits(); assertThat(hits) .extracting(SearchHit::getId) .contains(component.uuid()); } }
public SearchIdResult<String> search(ComponentQuery query, SearchOptions searchOptions) { SearchRequestBuilder requestBuilder = client .prepareSearch(INDEX_TYPE_COMPONENT) .setFetchSource(false) .setFrom(searchOptions.getOffset()) .setSize(searchOptions.getLimit()); BoolQueryBuilder esQuery = boolQuery(); esQuery.filter(authorizationTypeSupport.createQueryFilter()); setNullable(query.getQuery(), q -> { ComponentTextSearchQuery componentTextSearchQuery = ComponentTextSearchQuery.builder() .setQueryText(q) .setFieldKey(FIELD_KEY) .setFieldName(FIELD_NAME) .build(); esQuery.must(ComponentTextSearchQueryFactory.createQuery(componentTextSearchQuery, ComponentTextSearchFeatureRepertoire.values())); }); setEmptiable(query.getQualifiers(), q -> esQuery.must(termsQuery(FIELD_QUALIFIER, q))); setNullable(query.getLanguage(), l -> esQuery.must(termQuery(FIELD_LANGUAGE, l))); setNullable(query.getOrganizationUuid(), o -> esQuery.must(termQuery(FIELD_ORGANIZATION_UUID, o))); requestBuilder.setQuery(esQuery); requestBuilder.addSort(SORTABLE_ANALYZER.subField(FIELD_NAME), SortOrder.ASC); return new SearchIdResult<>(requestBuilder.get(), id -> id, system2.getDefaultTimeZone()); }
protected MatchQueryBuilder partialTermQuery(String queryTerm, String fieldName) { // We will truncate the search to the maximum length of nGrams in the index. // Otherwise the search would for sure not find any results. String truncatedQuery = StringUtils.left(queryTerm, DefaultIndexSettings.MAXIMUM_NGRAM_LENGTH); return matchQuery(SEARCH_GRAMS_ANALYZER.subField(fieldName), truncatedQuery); } }
protected MatchQueryBuilder tokenQuery(String queryTerm, String fieldName, DefaultIndexSettingsElement analyzer) { // We will truncate the search to the maximum length of nGrams in the index. // Otherwise the search would for sure not find any results. String truncatedQuery = StringUtils.left(queryTerm, DefaultIndexSettings.MAXIMUM_NGRAM_LENGTH); return matchQuery(analyzer.subField(fieldName), truncatedQuery); }
@Override public QueryBuilder getQuery(ComponentTextSearchQuery query) { return matchQuery(SORTABLE_ANALYZER.subField(query.getFieldKey()), query.getQueryText()) .boost(50f); } },