Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(browse): Improving Browse Feature Performance #6073

Merged
Merged
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 @@ -184,7 +184,7 @@ public BrowseResult browse(
int limit,
@Nonnull final Authentication authentication) throws RemoteInvocationException {
return ValidationUtils.validateBrowseResult(
_entitySearchService.browse(entityType, path, newFilter(requestFilters), start, limit), _entityService);
_cachingEntitySearchService.browse(entityType, path, newFilter(requestFilters), start, limit, null), _entityService);
}

@SneakyThrows
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.linkedin.metadata.search.client;

import com.linkedin.metadata.browse.BrowseResult;
import com.linkedin.metadata.query.AutoCompleteResult;
import com.linkedin.metadata.query.SearchFlags;
import com.linkedin.metadata.query.filter.Filter;
Expand All @@ -19,6 +20,7 @@
public class CachingEntitySearchService {
private static final String ENTITY_SEARCH_SERVICE_SEARCH_CACHE_NAME = "entitySearchServiceSearch";
private static final String ENTITY_SEARCH_SERVICE_AUTOCOMPLETE_CACHE_NAME = "entitySearchServiceAutoComplete";
private static final String ENTITY_SEARCH_SERVICE_BROWSE_CACHE_NAME = "entitySearchServiceBrowse";

private final CacheManager cacheManager;
private final EntitySearchService entitySearchService; // This is a shared component, also used in search aggregation
Expand Down Expand Up @@ -71,6 +73,29 @@ public AutoCompleteResult autoComplete(
return getCachedAutoCompleteResults(entityName, input, field, filters, limit, flags);
}

/**
* Retrieves cached auto complete results
*
* @param entityName type of entity to query
* @param path the path to be browsed
* @param filters the request map with fields and values as filters
* @param from index of the first entity located in path
* @param size the max number of entities contained in the response
*
* @return a {@link SearchResult} containing the requested batch of search results
*/
public BrowseResult browse(
@Nonnull String entityName,
@Nonnull String path,
@Nullable Filter filters,
int from,
int size,
@Nullable SearchFlags flags) {
return getCachedBrowseResults(entityName, path, filters, from, size, flags);
}



/**
* Get search results corresponding to the input "from" and "size"
* It goes through batches, starting from the beginning, until we get enough results to return
Expand Down Expand Up @@ -129,6 +154,43 @@ public AutoCompleteResult getCachedAutoCompleteResults(
return result;
}

/**
* Returns cached browse results.
*/
public BrowseResult getCachedBrowseResults(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great

@Nonnull String entityName,
@Nonnull String path,
@Nullable Filter filters,
int from,
int size,
@Nullable SearchFlags flags) {
Cache cache = cacheManager.getCache(ENTITY_SEARCH_SERVICE_BROWSE_CACHE_NAME);
BrowseResult result;
if (enableCache(flags)) {
Object cacheKey = Quintet.with(entityName, path, filters, from, size);
result = cache.get(cacheKey, BrowseResult.class);
if (result == null) {
result = getRawBrowseResults(
entityName,
path,
filters,
from,
size
);
cache.put(cacheKey, result);
}
} else {
result = getRawBrowseResults(
entityName,
path,
filters,
from,
size
);
}
return result;
}

/**
* Executes the expensive search query using the {@link EntitySearchService}
*/
Expand Down Expand Up @@ -165,6 +227,23 @@ private AutoCompleteResult getRawAutoCompleteResults(
limit);
}

/**
* Executes the expensive autocomplete query using the {@link EntitySearchService}
*/
private BrowseResult getRawBrowseResults(
final String entityName,
final String input,
final Filter filters,
final int start,
final int count) {
return entitySearchService.browse(
entityName,
input,
filters,
start,
count);
}

/**
* Returns true if the cache should be used or skipped when fetching search results
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ public class ESBrowseDAO {
private static final String REMOVED = "removed";

private static final String GROUP_AGG = "groups";
private static final String ALL_PATHS = "allPaths";

// Set explicit max size for grouping
private static final int AGGREGATION_MAX_SIZE = 2000;
Expand Down Expand Up @@ -137,16 +136,11 @@ public BrowseResult browse(@Nonnull String entityName, @Nonnull String path, @Nu
private AggregationBuilder buildAggregations(@Nonnull String path) {
final String currentLevel = ESUtils.escapeReservedCharacters(path) + "/.*";
final String nextLevel = ESUtils.escapeReservedCharacters(path) + "/.*/.*";
final String nextNextLevel = ESUtils.escapeReservedCharacters(path) + "/.*/.*/.*";

return AggregationBuilders.terms(GROUP_AGG)
.field(BROWSE_PATH)
.size(AGGREGATION_MAX_SIZE)
.includeExclude(new IncludeExclude(currentLevel, nextLevel))
.subAggregation(AggregationBuilders.terms(ALL_PATHS)
.field(BROWSE_PATH)
.size(AGGREGATION_MAX_SIZE)
.includeExclude(new IncludeExclude(nextLevel, nextNextLevel)));
.includeExclude(new IncludeExclude(currentLevel, nextLevel));
}

/**
Expand Down