Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ public class ElasticSearchSearchManager implements SearchManagementClient {
private final String clusterAlias;
private final RBACConditionEvaluator rbacConditionEvaluator;
private final NLQService nlqService;
private static final String SORT_FIELD_SCORE = "_score";
private static final String SORT_TYPE_KEYWORD = "keyword";
private static final Set<String> FIELDS_TO_REMOVE =
Set.of(
"suggest",
Expand Down Expand Up @@ -975,7 +977,7 @@ public Response doSearch(
String clusterAlias)
throws IOException {
ElasticSearchRequestBuilder requestBuilder =
buildSearchRequestBuilder(request, subjectContext, searchSettings, clusterAlias);
buildSearchRequestBuilder(request, subjectContext, searchSettings, clusterAlias, false);

LOG.debug("Executing search on index: {}, query: {}", request.getIndex(), request.getQuery());

Expand Down Expand Up @@ -1017,7 +1019,7 @@ public SearchResultListMapper searchForExport(
SearchSettings searchSettings =
SettingsCache.getSetting(SettingsType.SEARCH_SETTINGS, SearchSettings.class);
ElasticSearchRequestBuilder requestBuilder =
buildSearchRequestBuilder(request, subjectContext, searchSettings, clusterAlias);
buildSearchRequestBuilder(request, subjectContext, searchSettings, clusterAlias, true);

try {
SearchRequest searchRequest = requestBuilder.build(request.getIndex());
Expand Down Expand Up @@ -1060,7 +1062,8 @@ private ElasticSearchRequestBuilder buildSearchRequestBuilder(
org.openmetadata.schema.search.SearchRequest request,
SubjectContext subjectContext,
SearchSettings searchSettings,
String clusterAlias)
String clusterAlias,
boolean isExport)
throws IOException {
if (!isClientAvailable) {
throw new IOException("Elasticsearch client is not available");
Expand Down Expand Up @@ -1191,18 +1194,17 @@ private ElasticSearchRequestBuilder buildSearchRequestBuilder(
+ request.getSortOrder().substring(1).toLowerCase();
SortOrder sortOrder = SortOrder.valueOf(sortTypeCapitalized);

if (!sortField.equalsIgnoreCase("_score")) {
if (!sortField.equalsIgnoreCase(SORT_FIELD_SCORE)) {
boolean isKeywordField =
sortField.endsWith(".keyword")
|| SearchSourceBuilderFactory.KEYWORD_SORT_FIELDS.contains(sortField);
requestBuilder.sort(sortField, sortOrder, isKeywordField ? "keyword" : "integer");
requestBuilder.sort(sortField, sortOrder, isKeywordField ? SORT_TYPE_KEYWORD : "integer");
} else {
requestBuilder.sort(sortField, sortOrder, null);
}

// Add tiebreaker sort for stable pagination when sorting by score
if (sortField.equalsIgnoreCase("_score")) {
requestBuilder.sort("name.keyword", SortOrder.Asc, "keyword");
if (sortField.equalsIgnoreCase(SORT_FIELD_SCORE) || isExport) {
requestBuilder.sort("name.keyword", SortOrder.Asc, SORT_TYPE_KEYWORD);
}
}

Expand Down Expand Up @@ -1370,10 +1372,8 @@ private ElasticSearchRequestBuilder buildHierarchyQuery(
}
}

// Add sorting by score first for relevance, then by fullyQualifiedName for consistent hierarchy
// ordering
requestBuilder.sort("_score", SortOrder.Desc, null);
requestBuilder.sort("fullyQualifiedName", SortOrder.Asc, "keyword");
requestBuilder.sort(SORT_FIELD_SCORE, SortOrder.Desc, null);
requestBuilder.sort("fullyQualifiedName", SortOrder.Asc, SORT_TYPE_KEYWORD);

return requestBuilder;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ public class OpenSearchSearchManager implements SearchManagementClient {
private final String clusterAlias;
private final RBACConditionEvaluator rbacConditionEvaluator;
private final NLQService nlqService;
private static final String SORT_FIELD_SCORE = "_score";
private static final String SORT_TYPE_KEYWORD = "keyword";
private static final Set<String> FIELDS_TO_REMOVE =
Set.of(
"suggest",
Expand Down Expand Up @@ -1016,7 +1018,7 @@ public Response doSearch(
String clusterAlias)
throws IOException {
OpenSearchRequestBuilder requestBuilder =
buildSearchRequestBuilder(request, subjectContext, searchSettings, clusterAlias);
buildSearchRequestBuilder(request, subjectContext, searchSettings, clusterAlias, false);

LOG.debug("Executing search on index: {}, query: {}", request.getIndex(), request.getQuery());

Expand Down Expand Up @@ -1053,7 +1055,7 @@ public SearchResultListMapper searchForExport(
SearchSettings searchSettings =
SettingsCache.getSetting(SettingsType.SEARCH_SETTINGS, SearchSettings.class);
OpenSearchRequestBuilder requestBuilder =
buildSearchRequestBuilder(request, subjectContext, searchSettings, clusterAlias);
buildSearchRequestBuilder(request, subjectContext, searchSettings, clusterAlias, true);

try {
SearchRequest searchRequest = requestBuilder.build(request.getIndex());
Expand Down Expand Up @@ -1096,7 +1098,8 @@ private OpenSearchRequestBuilder buildSearchRequestBuilder(
org.openmetadata.schema.search.SearchRequest request,
SubjectContext subjectContext,
SearchSettings searchSettings,
String clusterAlias)
String clusterAlias,
boolean isExport)
throws IOException {
if (!isClientAvailable) {
throw new IOException("OpenSearch client is not available");
Expand Down Expand Up @@ -1230,18 +1233,17 @@ private OpenSearchRequestBuilder buildSearchRequestBuilder(
+ request.getSortOrder().substring(1).toLowerCase();
SortOrder sortOrder = SortOrder.valueOf(sortTypeCapitalized);

if (!sortField.equalsIgnoreCase("_score")) {
if (!sortField.equalsIgnoreCase(SORT_FIELD_SCORE)) {
boolean isKeywordField =
sortField.endsWith(".keyword")
|| SearchSourceBuilderFactory.KEYWORD_SORT_FIELDS.contains(sortField);
requestBuilder.sort(sortField, sortOrder, isKeywordField ? "keyword" : "integer");
requestBuilder.sort(sortField, sortOrder, isKeywordField ? SORT_TYPE_KEYWORD : "integer");
} else {
requestBuilder.sort(sortField, sortOrder, null);
}

// Add tiebreaker sort for stable pagination when sorting by score
if (sortField.equalsIgnoreCase("_score")) {
requestBuilder.sort("name.keyword", SortOrder.Asc, "keyword");
if (sortField.equalsIgnoreCase(SORT_FIELD_SCORE) || isExport) {
requestBuilder.sort("name.keyword", SortOrder.Asc, SORT_TYPE_KEYWORD);
}
}

Expand Down Expand Up @@ -1408,10 +1410,8 @@ private OpenSearchRequestBuilder buildHierarchyQuery(
}
}

// Add sorting by score first for relevance, then by fullyQualifiedName for consistent hierarchy
// ordering
requestBuilder.sort("_score", SortOrder.Desc, null);
requestBuilder.sort("fullyQualifiedName", SortOrder.Asc, "keyword");
requestBuilder.sort(SORT_FIELD_SCORE, SortOrder.Desc, null);
requestBuilder.sort("fullyQualifiedName", SortOrder.Asc, SORT_TYPE_KEYWORD);

return requestBuilder;
}
Expand Down
Loading