From d9e4fbdebb7b1ba67156ab3ef213f9a861191a30 Mon Sep 17 00:00:00 2001 From: Sriharsha Chintalapani Date: Thu, 9 Mar 2023 08:07:08 -0800 Subject: [PATCH] =?UTF-8?q?Fix=20#10454:=20Improve=20Search=20Relevancy,?= =?UTF-8?q?=20by=20adding=20functional=20scoring=20an=E2=80=A6=20(#10455)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix #10454: Improve Search Relevancy, by adding functional scoring and add ngram analyzer; Fix #10452: Enable Table and Column search by BOTH name and displayName * fix stylecheck * Undo changes in table example names * remove ngram from teams & users * Fix topic tags * Fix #10429: Kafka Sample data improvements and adding support for JSONSchema and Protobuf (#10430) * Fix #10429: Kafka Sample data improvements and adding support for JSONSchema and Protobuf * Fix #10429: Kafka Sample data improvements and adding support for JSONSchema and Protobuf * Fix #10429: Kafka Sample data improvements and adding support for JSONSchema and Protobuf * Fix #10429: Kafka Sample data improvements and adding support for JSONSchema and Protobuf * Added top level parsing and unit tests * fix(ui): show schemaText and fields both * fix no data placeholder for fields & schema text * addressing comments * fixed py checkstyle --------- Co-authored-by: Onkar Ravgan Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com> * revert common_broker_source changes * revert common_broker_source changes * remove changes to user & team indexes * fix team index * fix glossary & tag index * Fix to TopicIndex * fix advance search pre-requisites cypress failure * fix group advance search cy failures --------- Co-authored-by: Nahuel Co-authored-by: Onkar Ravgan Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com> --- .../examples/sample_data/datasets/tables.json | 12 +- .../service/elasticsearch/DashboardIndex.java | 1 + .../ElasticSearchIndexDefinition.java | 8 ++ .../service/elasticsearch/TopicIndex.java | 47 +++++++ .../resources/search/SearchResource.java | 63 +++++---- .../en/dashboard_index_mapping.json | 22 ++- .../en/mlmodel_index_mapping.json | 13 +- .../en/pipeline_index_mapping.json | 7 +- .../elasticsearch/en/table_index_mapping.json | 13 +- .../elasticsearch/en/tag_index_mapping.json | 5 + .../elasticsearch/en/topic_index_mapping.json | 15 +- .../ui/cypress/common/advancedSearch.js | 130 ++++++------------ 12 files changed, 215 insertions(+), 121 deletions(-) diff --git a/ingestion/examples/sample_data/datasets/tables.json b/ingestion/examples/sample_data/datasets/tables.json index 487d04351c7..619d4ce8594 100644 --- a/ingestion/examples/sample_data/datasets/tables.json +++ b/ingestion/examples/sample_data/datasets/tables.json @@ -135,15 +135,15 @@ "tags": [], "usageSummary": { "dailyStats": { - "count": 100, + "count": 73, "percentileRank": 45 }, "weeklyStats": { - "count": 100, + "count": 73, "percentileRank": 45 }, "monthlyStats": { - "count": 100, + "count": 67, "percentileRank": 45 }, "date": "2021-12-01" @@ -803,15 +803,15 @@ "tags": [], "usageSummary": { "dailyStats": { - "count": 100, + "count": 87, "percentileRank": 45 }, "weeklyStats": { - "count": 100, + "count": 87, "percentileRank": 45 }, "monthlyStats": { - "count": 100, + "count": 87, "percentileRank": 45 }, "date": "2021-12-01" diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/elasticsearch/DashboardIndex.java b/openmetadata-service/src/main/java/org/openmetadata/service/elasticsearch/DashboardIndex.java index ba94e6c02d6..83ef6f9542c 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/elasticsearch/DashboardIndex.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/elasticsearch/DashboardIndex.java @@ -26,6 +26,7 @@ public class DashboardIndex implements ElasticSearchIndex { suggest.add(ElasticSearchSuggest.builder().input(dashboard.getDisplayName()).weight(10).build()); serviceSuggest.add(ElasticSearchSuggest.builder().input(dashboard.getService().getName()).weight(5).build()); ParseTags parseTags = new ParseTags(ElasticSearchIndexUtils.parseTags(dashboard.getTags())); + if (dashboard.getCharts() != null) { for (EntityReference chart : dashboard.getCharts()) { chartSuggest.add(ElasticSearchSuggest.builder().input(chart.getDisplayName()).weight(5).build()); diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/elasticsearch/ElasticSearchIndexDefinition.java b/openmetadata-service/src/main/java/org/openmetadata/service/elasticsearch/ElasticSearchIndexDefinition.java index 785ca3c271b..8a5d101895b 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/elasticsearch/ElasticSearchIndexDefinition.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/elasticsearch/ElasticSearchIndexDefinition.java @@ -281,6 +281,14 @@ class FlattenColumn { List tags; } +@Getter +@Builder +class FlattenSchemaField { + String name; + String description; + List tags; +} + class ParseTags { TagLabel tierTag; final List tags; diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/elasticsearch/TopicIndex.java b/openmetadata-service/src/main/java/org/openmetadata/service/elasticsearch/TopicIndex.java index 3219b695577..29ca808ab0f 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/elasticsearch/TopicIndex.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/elasticsearch/TopicIndex.java @@ -3,9 +3,13 @@ package org.openmetadata.service.elasticsearch; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Optional; +import java.util.function.Predicate; import org.openmetadata.schema.entity.data.Topic; +import org.openmetadata.schema.type.Field; import org.openmetadata.schema.type.TagLabel; import org.openmetadata.service.Entity; +import org.openmetadata.service.util.FullyQualifiedName; import org.openmetadata.service.util.JsonUtils; public class TopicIndex implements ElasticSearchIndex { @@ -20,6 +24,7 @@ public class TopicIndex implements ElasticSearchIndex { Map doc = JsonUtils.getMap(topic); List tags = new ArrayList<>(); List suggest = new ArrayList<>(); + List fieldSuggest = new ArrayList<>(); List serviceSuggest = new ArrayList<>(); suggest.add(ElasticSearchSuggest.builder().input(topic.getFullyQualifiedName()).weight(5).build()); suggest.add(ElasticSearchSuggest.builder().input(topic.getName()).weight(10).build()); @@ -28,12 +33,28 @@ public class TopicIndex implements ElasticSearchIndex { if (topic.getTags() != null) { tags.addAll(topic.getTags()); } + + if (topic.getMessageSchema() != null + && topic.getMessageSchema().getSchemaFields() != null + && !topic.getMessageSchema().getSchemaFields().isEmpty()) { + List flattenFields = new ArrayList<>(); + parseSchemaFields(topic.getMessageSchema().getSchemaFields(), flattenFields, null); + + for (FlattenSchemaField field : flattenFields) { + if (field.getTags() != null) { + tags.addAll(field.getTags()); + } + fieldSuggest.add(ElasticSearchSuggest.builder().input(field.getName()).weight(5).build()); + } + } + ParseTags parseTags = new ParseTags(tags); doc.put("displayName", topic.getDisplayName() != null ? topic.getDisplayName() : topic.getName()); doc.put("tags", parseTags.tags); doc.put("tier", parseTags.tierTag); doc.put("followers", ElasticSearchIndexUtils.parseFollowers(topic.getFollowers())); doc.put("suggest", suggest); + doc.put("field_suggest", fieldSuggest); doc.put("service_suggest", serviceSuggest); doc.put("entityType", Entity.TOPIC); doc.put("serviceType", topic.getServiceType()); @@ -41,4 +62,30 @@ public class TopicIndex implements ElasticSearchIndex { doc.put("schemaType", topic.getMessageSchema() != null ? topic.getMessageSchema().getSchemaType() : null); return doc; } + + private void parseSchemaFields( + List fields, List flattenSchemaFields, String parentSchemaField) { + Optional optParentField = Optional.ofNullable(parentSchemaField).filter(Predicate.not(String::isEmpty)); + List tags = new ArrayList<>(); + for (Field field : fields) { + String fieldName = field.getName(); + if (optParentField.isPresent()) { + fieldName = FullyQualifiedName.add(optParentField.get(), fieldName); + } + if (field.getTags() != null) { + tags = field.getTags(); + } + + FlattenSchemaField flattenSchemaField = + FlattenSchemaField.builder().name(fieldName).description(field.getDescription()).build(); + + if (!tags.isEmpty()) { + flattenSchemaField.tags = tags; + } + flattenSchemaFields.add(flattenSchemaField); + if (field.getChildren() != null) { + parseSchemaFields(field.getChildren(), flattenSchemaFields, field.getName()); + } + } + } } diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/resources/search/SearchResource.java b/openmetadata-service/src/main/java/org/openmetadata/service/resources/search/SearchResource.java index ccbf6a33f63..4034cbdf51d 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/resources/search/SearchResource.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/resources/search/SearchResource.java @@ -17,6 +17,7 @@ import static javax.ws.rs.core.Response.Status.OK; import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty; import static org.openmetadata.service.Entity.FIELD_DESCRIPTION; import static org.openmetadata.service.Entity.FIELD_DISPLAY_NAME; +import static org.openmetadata.service.Entity.FIELD_NAME; import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.Operation; @@ -43,6 +44,7 @@ import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; +import org.elasticsearch.common.lucene.search.function.CombineFunction; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.Fuzziness; import org.elasticsearch.common.unit.TimeValue; @@ -51,7 +53,7 @@ import org.elasticsearch.common.xcontent.NamedXContentRegistry; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.query.BoolQueryBuilder; -import org.elasticsearch.index.query.MatchNoneQueryBuilder; +import org.elasticsearch.index.query.MultiMatchQueryBuilder; import org.elasticsearch.index.query.Operator; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; @@ -84,10 +86,10 @@ public class SearchResource { private RestHighLevelClient client; private static final Integer MAX_AGGREGATE_SIZE = 50; private static final Integer MAX_RESULT_HITS = 10000; - private static final String NAME = "name"; private static final String NAME_KEYWORD = "name.keyword"; private static final String DISPLAY_NAME = "displayName"; private static final String DISPLAY_NAME_KEYWORD = "displayName.keyword"; + public static final String FIELD_DISPLAY_NAME_NGRAM = "displayName.ngram"; private static final String DESCRIPTION = "description"; private static final String UNIFIED = "unified"; @@ -402,20 +404,27 @@ public class SearchResource { private SearchSourceBuilder buildTableSearchBuilder(String query, int from, int size) { QueryStringQueryBuilder queryStringBuilder = QueryBuilders.queryStringQuery(query) - .field(FIELD_DISPLAY_NAME, 20.0f) - .field(FIELD_DESCRIPTION, 2.0f) + .field(FIELD_DISPLAY_NAME, 15.0f) + .field(FIELD_DISPLAY_NAME_NGRAM) + .field(FIELD_NAME, 15.0f) + .field(FIELD_DESCRIPTION, 1.0f) .field("columns.name", 2.0f) + .field("columns.name.ngram") + .field("columns.displayName", 2.0f) + .field("columns.displayName.ngram") .field("columns.description", 1.0f) .field("columns.children.name", 2.0f) + .type(MultiMatchQueryBuilder.Type.BEST_FIELDS) .defaultOperator(Operator.AND) .fuzziness(Fuzziness.AUTO); FieldValueFactorFunctionBuilder boostScoreBuilder = - ScoreFunctionBuilders.fieldValueFactorFunction("usageSummary.weeklyStats.count").missing(1).factor(4); + ScoreFunctionBuilders.fieldValueFactorFunction("usageSummary.weeklyStats.count").missing(0).factor(0.2f); FunctionScoreQueryBuilder.FilterFunctionBuilder[] functions = new FunctionScoreQueryBuilder.FilterFunctionBuilder[] { - new FunctionScoreQueryBuilder.FilterFunctionBuilder(new MatchNoneQueryBuilder(), boostScoreBuilder) + new FunctionScoreQueryBuilder.FilterFunctionBuilder(boostScoreBuilder) }; FunctionScoreQueryBuilder queryBuilder = QueryBuilders.functionScoreQuery(queryStringBuilder, functions); + queryBuilder.boostMode(CombineFunction.SUM); HighlightBuilder.Field highlightTableName = new HighlightBuilder.Field(FIELD_DISPLAY_NAME); highlightTableName.highlighterType(UNIFIED); HighlightBuilder.Field highlightDescription = new HighlightBuilder.Field(DESCRIPTION); @@ -446,8 +455,10 @@ public class SearchResource { private SearchSourceBuilder buildTopicSearchBuilder(String query, int from, int size) { QueryStringQueryBuilder queryBuilder = QueryBuilders.queryStringQuery(query) - .field(FIELD_DISPLAY_NAME, 10.0f) - .field(FIELD_DESCRIPTION, 2.0f) + .field(FIELD_DISPLAY_NAME, 15.0f) + .field(FIELD_DISPLAY_NAME_NGRAM) + .field(FIELD_NAME, 15.0f) + .field(FIELD_DESCRIPTION, 1.0f) .field("messageSchema.schemaFields.name", 2.0f) .field("messageSchema.schemaFields.description", 1.0f) .field("messageSchema.schemaFields.children.name", 2.0f) @@ -471,10 +482,12 @@ public class SearchResource { private SearchSourceBuilder buildDashboardSearchBuilder(String query, int from, int size) { QueryStringQueryBuilder queryBuilder = QueryBuilders.queryStringQuery(query) - .field(FIELD_DISPLAY_NAME, 10.0f) - .field(FIELD_DESCRIPTION, 2.0f) + .field(FIELD_DISPLAY_NAME, 15.0f) + .field(FIELD_DISPLAY_NAME_NGRAM) + .field(FIELD_NAME, 15.0f) + .field(FIELD_DESCRIPTION, 1.0f) .field("charts.name", 2.0f) - .field("charts.description") + .field("charts.description", 1.0f) .defaultOperator(Operator.AND) .fuzziness(Fuzziness.AUTO); HighlightBuilder.Field highlightDashboardName = new HighlightBuilder.Field(FIELD_DISPLAY_NAME); @@ -499,10 +512,12 @@ public class SearchResource { private SearchSourceBuilder buildPipelineSearchBuilder(String query, int from, int size) { QueryStringQueryBuilder queryBuilder = QueryBuilders.queryStringQuery(query) - .field(FIELD_DISPLAY_NAME, 10.0f) - .field(DESCRIPTION, 2.0f) + .field(FIELD_DISPLAY_NAME, 15.0f) + .field(FIELD_DISPLAY_NAME_NGRAM) + .field(FIELD_NAME, 15.0f) + .field(DESCRIPTION, 1.0f) .field("tasks.name", 2.0f) - .field("tasks.description") + .field("tasks.description", 1.0f) .defaultOperator(Operator.AND) .fuzziness(Fuzziness.AUTO); HighlightBuilder.Field highlightPipelineName = new HighlightBuilder.Field(FIELD_DISPLAY_NAME); @@ -525,10 +540,12 @@ public class SearchResource { private SearchSourceBuilder buildMlModelSearchBuilder(String query, int from, int size) { QueryStringQueryBuilder queryBuilder = QueryBuilders.queryStringQuery(query) - .field(FIELD_DISPLAY_NAME, 10.0f) - .field(DESCRIPTION, 2.0f) + .field(FIELD_DISPLAY_NAME, 15.0f) + .field(FIELD_DISPLAY_NAME_NGRAM) + .field(FIELD_NAME, 15.0f) + .field(DESCRIPTION, 1.0f) .field("mlFeatures.name", 2.0f) - .field("mlFeatures.description") + .field("mlFeatures.description", 1.0f) .defaultOperator(Operator.AND) .fuzziness(Fuzziness.AUTO); HighlightBuilder.Field highlightPipelineName = new HighlightBuilder.Field(FIELD_DISPLAY_NAME); @@ -575,7 +592,7 @@ public class SearchResource { QueryBuilders.queryStringQuery(query) .field(DISPLAY_NAME, 5.0f) .field(DISPLAY_NAME_KEYWORD, 3.0f) - .field(NAME, 2.0f) + .field(FIELD_NAME, 2.0f) .field(NAME_KEYWORD, 3.0f) .fuzziness(Fuzziness.AUTO); return searchBuilder(queryBuilder, null, from, size); @@ -586,7 +603,7 @@ public class SearchResource { QueryBuilders.queryStringQuery(query) .field(DISPLAY_NAME, 5.0f) .field(DISPLAY_NAME_KEYWORD, 3.0f) - .field(NAME, 2.0f) + .field(FIELD_NAME, 2.0f) .field(NAME_KEYWORD, 3.0f) .fuzziness(Fuzziness.AUTO); return searchBuilder(queryBuilder, null, from, size); @@ -595,12 +612,12 @@ public class SearchResource { private SearchSourceBuilder buildGlossaryTermSearchBuilder(String query, int from, int size) { QueryStringQueryBuilder queryBuilder = QueryBuilders.queryStringQuery(query) - .field(NAME, 10.0f) + .field(FIELD_NAME, 10.0f) .field(DESCRIPTION, 3.0f) .defaultOperator(Operator.AND) .fuzziness(Fuzziness.AUTO); - HighlightBuilder.Field highlightGlossaryName = new HighlightBuilder.Field(NAME); + HighlightBuilder.Field highlightGlossaryName = new HighlightBuilder.Field(FIELD_NAME); highlightGlossaryName.highlighterType(UNIFIED); HighlightBuilder.Field highlightDescription = new HighlightBuilder.Field(FIELD_DESCRIPTION); highlightDescription.highlighterType(UNIFIED); @@ -616,12 +633,12 @@ public class SearchResource { private SearchSourceBuilder buildTagSearchBuilder(String query, int from, int size) { QueryStringQueryBuilder queryBuilder = QueryBuilders.queryStringQuery(query) - .field(NAME, 10.0f) + .field(FIELD_NAME, 10.0f) .field(DESCRIPTION, 3.0f) .defaultOperator(Operator.AND) .fuzziness(Fuzziness.AUTO); - HighlightBuilder.Field highlightTagName = new HighlightBuilder.Field(NAME); + HighlightBuilder.Field highlightTagName = new HighlightBuilder.Field(FIELD_NAME); highlightTagName.highlighterType(UNIFIED); HighlightBuilder.Field highlightDescription = new HighlightBuilder.Field(FIELD_DESCRIPTION); highlightDescription.highlighterType(UNIFIED); diff --git a/openmetadata-service/src/main/resources/elasticsearch/en/dashboard_index_mapping.json b/openmetadata-service/src/main/resources/elasticsearch/en/dashboard_index_mapping.json index d0b751512e4..01760b57fe5 100644 --- a/openmetadata-service/src/main/resources/elasticsearch/en/dashboard_index_mapping.json +++ b/openmetadata-service/src/main/resources/elasticsearch/en/dashboard_index_mapping.json @@ -17,6 +17,11 @@ "lowercase", "om_stemmer" ] + }, + "om_ngram": { + "tokenizer": "ngram", + "min_gram": 1, + "max_gram": 2 } }, "filter": { @@ -47,7 +52,13 @@ }, "displayName": { "type": "text", - "analyzer": "om_analyzer" + "analyzer": "om_analyzer", + "fields": { + "ngram": { + "type": "text", + "analyzer": "om_ngram" + } + } }, "description": { "type": "text", @@ -92,6 +103,15 @@ } } }, + "displayName": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, "fullyQualifiedName": { "type": "text" }, diff --git a/openmetadata-service/src/main/resources/elasticsearch/en/mlmodel_index_mapping.json b/openmetadata-service/src/main/resources/elasticsearch/en/mlmodel_index_mapping.json index 9525fe0fce6..f907f53d6d5 100644 --- a/openmetadata-service/src/main/resources/elasticsearch/en/mlmodel_index_mapping.json +++ b/openmetadata-service/src/main/resources/elasticsearch/en/mlmodel_index_mapping.json @@ -17,6 +17,11 @@ "lowercase", "om_stemmer" ] + }, + "om_ngram": { + "tokenizer": "ngram", + "min_gram": 1, + "max_gram": 2 } }, "filter": { @@ -47,7 +52,13 @@ }, "displayName": { "type": "text", - "analyzer": "om_analyzer" + "analyzer": "om_analyzer", + "fields": { + "ngram": { + "type": "text", + "analyzer": "om_ngram" + } + } }, "description": { "type": "text", diff --git a/openmetadata-service/src/main/resources/elasticsearch/en/pipeline_index_mapping.json b/openmetadata-service/src/main/resources/elasticsearch/en/pipeline_index_mapping.json index 3599ec7a000..f0bceadce20 100644 --- a/openmetadata-service/src/main/resources/elasticsearch/en/pipeline_index_mapping.json +++ b/openmetadata-service/src/main/resources/elasticsearch/en/pipeline_index_mapping.json @@ -82,7 +82,12 @@ }, "displayName": { "type": "text", - "analyzer": "om_analyzer" + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } }, "description": { "type": "text", diff --git a/openmetadata-service/src/main/resources/elasticsearch/en/table_index_mapping.json b/openmetadata-service/src/main/resources/elasticsearch/en/table_index_mapping.json index 59206959cfa..f3f5e6e1b97 100644 --- a/openmetadata-service/src/main/resources/elasticsearch/en/table_index_mapping.json +++ b/openmetadata-service/src/main/resources/elasticsearch/en/table_index_mapping.json @@ -17,6 +17,11 @@ "lowercase", "om_stemmer" ] + }, + "om_ngram": { + "tokenizer": "ngram", + "min_gram": 1, + "max_gram": 2 } }, "filter": { @@ -47,7 +52,13 @@ }, "displayName": { "type": "text", - "analyzer": "om_analyzer" + "analyzer": "om_analyzer", + "fields": { + "ngram": { + "type": "text", + "analyzer": "om_ngram" + } + } }, "description": { "type": "text", diff --git a/openmetadata-service/src/main/resources/elasticsearch/en/tag_index_mapping.json b/openmetadata-service/src/main/resources/elasticsearch/en/tag_index_mapping.json index 0c6678a631d..2c22f4bff87 100644 --- a/openmetadata-service/src/main/resources/elasticsearch/en/tag_index_mapping.json +++ b/openmetadata-service/src/main/resources/elasticsearch/en/tag_index_mapping.json @@ -17,6 +17,11 @@ "lowercase", "om_stemmer" ] + }, + "om_ngram": { + "tokenizer": "ngram", + "min_gram": 1, + "max_gram": 2 } }, "filter": { diff --git a/openmetadata-service/src/main/resources/elasticsearch/en/topic_index_mapping.json b/openmetadata-service/src/main/resources/elasticsearch/en/topic_index_mapping.json index 47420be3999..30613cd7547 100644 --- a/openmetadata-service/src/main/resources/elasticsearch/en/topic_index_mapping.json +++ b/openmetadata-service/src/main/resources/elasticsearch/en/topic_index_mapping.json @@ -17,6 +17,11 @@ "lowercase", "om_stemmer" ] + }, + "om_ngram": { + "tokenizer": "ngram", + "min_gram": 1, + "max_gram": 2 } }, "filter": { @@ -47,7 +52,12 @@ }, "displayName": { "type": "text", - "analyzer": "om_analyzer" + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } }, "description": { "type": "text", @@ -227,6 +237,9 @@ } ] }, + "field_suggest": { + "type": "completion" + }, "service_suggest": { "type": "completion" } diff --git a/openmetadata-ui/src/main/resources/ui/cypress/common/advancedSearch.js b/openmetadata-ui/src/main/resources/ui/cypress/common/advancedSearch.js index ab9ae5b0d95..034309203a8 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/common/advancedSearch.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/common/advancedSearch.js @@ -10,8 +10,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { SEARCH_ENTITY_TABLE } from '../constants/constants'; import { MYSQL } from '../constants/service.constants'; -import { interceptURL, verifyResponseStatusCode } from './common'; +import { + interceptURL, + verifyResponseStatusCode, + visitEntityDetailsPage, +} from './common'; export const CONDITIONS_MUST = { equalTo: { @@ -47,9 +52,9 @@ export const FIELDS = { Owner: { name: 'Owner', testid: '[title="Owner"]', - searchTerm1: 'admin', - searchCriteriaFirstGroup: 'admin', - responseValueFirstGroup: `"displayName":"admin"`, + searchTerm1: 'Colin Ho', + searchCriteriaFirstGroup: 'Colin Ho', + responseValueFirstGroup: `"displayName":"Colin Ho"`, searchCriteriaSecondGroup: 'Aaron Singh', owner: true, responseValueSecondGroup: 'Aaron Singh', @@ -249,45 +254,11 @@ export const checkmust_notPaths = ( }; export const addOwner = (searchTerm, ownerName) => { - cy.get( - '[data-testid="dropdown-profile"] > [data-testid="dropdown-item"] > :nth-child(1) > [data-testid="menu-button"]' - ) - .should('exist') - .and('be.visible') - .click(); - - cy.get('[data-testid="user-name"]').should('exist').and('be.visible').click(); - - verifyResponseStatusCode('@userProfile', 200); - - cy.get('[data-testid="hiden-layer"]').should('exist').click(); - - cy.get('[data-testid="edit-displayName"]') - .should('exist') - .and('be.visible') - .click(); - - cy.get('[data-testid="displayName"]') - .should('exist') - .and('be.visible') - .clear() - .type(ownerName); - - cy.get('[data-testid="save-displayName"]') - .should('exist') - .and('be.visible') - .click(); - - cy.get('[data-testid="appbar-item-explore"]') - .should('exist') - .and('be.visible') - .click(); - - cy.get('#tabledatacard0-title') - .first() - .scrollIntoView() - .should('be.visible') - .click(); + visitEntityDetailsPage( + SEARCH_ENTITY_TABLE.table_1.term, + SEARCH_ENTITY_TABLE.table_1.serviceName, + SEARCH_ENTITY_TABLE.table_1.entity + ); interceptURL( 'GET', @@ -307,7 +278,7 @@ export const addOwner = (searchTerm, ownerName) => { interceptURL( 'GET', - `api/v1/search/query?q=*${searchTerm}*&from=0&size=*&index=*`, + `api/v1/search/query?q=*${encodeURI(searchTerm)}*&from=0&size=*&index=*`, 'searchOwner' ); cy.get('[data-testid="searchInputText"]') @@ -328,6 +299,8 @@ export const addOwner = (searchTerm, ownerName) => { .and('be.visible') .click(); + verifyResponseStatusCode('@tablePatch', 200); + cy.get('[data-testid="owner-link"]') .scrollIntoView() .invoke('text') @@ -337,17 +310,11 @@ export const addOwner = (searchTerm, ownerName) => { }; export const addTier = (tier) => { - cy.get('[data-testid="appbar-item-explore"]') - .scrollIntoView() - .should('exist') - .and('be.visible') - .click(); - - cy.get('#tabledatacard0-title') - .first() - .scrollIntoView() - .should('be.visible') - .click(); + visitEntityDetailsPage( + SEARCH_ENTITY_TABLE.table_2.term, + SEARCH_ENTITY_TABLE.table_2.serviceName, + SEARCH_ENTITY_TABLE.table_2.entity + ); cy.get('[data-testid="edit-Tier-icon"]') .scrollIntoView() @@ -368,42 +335,29 @@ export const addTier = (tier) => { }; export const addTag = (tag) => { - cy.intercept('/api/v1/testCase?fields=testCaseResult*').as('testCaseResults'); - cy.intercept('/api/v1/feed?entityLink=*').as('entityLink'); + visitEntityDetailsPage( + SEARCH_ENTITY_TABLE.table_3.term, + SEARCH_ENTITY_TABLE.table_3.serviceName, + SEARCH_ENTITY_TABLE.table_3.entity + ); - cy.get('[data-testid="appbar-item-explore"]') - .should('exist') - .and('be.visible') + cy.get('[data-testid="tags"] > [data-testid="add-tag"]') + .eq(0) + .should('be.visible') + .scrollIntoView() .click(); - cy.get('#tabledatacard0-title') - .first() + cy.get('[data-testid="tag-selector"]').should('be.visible').click().type(tag); + + cy.get('.ant-select-item-option-content').should('be.visible').click(); + cy.get( + '[data-testid="tags-wrapper"] > [data-testid="tag-container"]' + ).contains(tag); + cy.get('[data-testid="saveAssociatedTag"]').should('be.visible').click(); + cy.get('[data-testid="entity-tags"]') .scrollIntoView() .should('be.visible') - .click(); - - cy.wait(['@testCaseResults', '@entityLink']).then(() => { - cy.get('[data-testid="tags"] > [data-testid="add-tag"]') - .eq(0) - .should('be.visible') - .scrollIntoView() - .click(); - - cy.get('[data-testid="tag-selector"]') - .should('be.visible') - .click() - .type(tag); - - cy.get('.ant-select-item-option-content').should('be.visible').click(); - cy.get( - '[data-testid="tags-wrapper"] > [data-testid="tag-container"]' - ).contains(tag); - cy.get('[data-testid="saveAssociatedTag"]').should('be.visible').click(); - cy.get('[data-testid="entity-tags"]') - .scrollIntoView() - .should('be.visible') - .contains(tag); - }); + .contains(tag); }; export const checkAddGroupWithOperator = ( @@ -519,7 +473,9 @@ export const checkAddGroupWithOperator = ( interceptURL( 'GET', - `/api/v1/search/query?q=&index=*&from=0&size=10&deleted=false&query_filter=*${searchCriteria_1}*&sort_field=_score&sort_order=desc`, + `/api/v1/search/query?q=&index=*&from=0&size=10&deleted=false&query_filter=*${encodeURI( + searchCriteria_1 + )}*&sort_field=_score&sort_order=desc`, 'search' );