Search in sources :

Example 1 with SortInfo

use of co.cask.cdap.data2.metadata.dataset.SortInfo in project cdap by caskdata.

the class DefaultMetadataStore method search.

private MetadataSearchResponse search(Set<MetadataScope> scopes, String namespaceId, String searchQuery, Set<EntityTypeSimpleName> types, SortInfo sortInfo, int offset, int limit, int numCursors, String cursor, boolean showHidden, Set<EntityScope> entityScope) throws BadRequestException {
    if (offset < 0) {
        throw new IllegalArgumentException("offset must not be negative");
    }
    if (limit < 0) {
        throw new IllegalArgumentException("limit must not be negative");
    }
    List<MetadataEntry> results = new LinkedList<>();
    List<String> cursors = new LinkedList<>();
    for (MetadataScope scope : scopes) {
        SearchResults searchResults = getSearchResults(scope, namespaceId, searchQuery, types, sortInfo, offset, limit, numCursors, cursor, showHidden, entityScope);
        results.addAll(searchResults.getResults());
        cursors.addAll(searchResults.getCursors());
    }
    // sort if required
    Set<NamespacedEntityId> sortedEntities = getSortedEntities(results, sortInfo);
    int total = sortedEntities.size();
    // pagination is not performed at the dataset level, because:
    // 1. scoring is needed for DEFAULT sort info. So perform it here for now.
    // 2. Even when using custom sorting, we need to remove elements from the beginning to the offset and the cursors
    //    at the end
    // TODO: Figure out how all of this can be done server (HBase) side
    int startIndex = Math.min(offset, sortedEntities.size());
    // Account for overflow
    int endIndex = (int) Math.min(Integer.MAX_VALUE, (long) offset + limit);
    endIndex = Math.min(endIndex, sortedEntities.size());
    // add 1 to maxIndex because end index is exclusive
    sortedEntities = new LinkedHashSet<>(ImmutableList.copyOf(sortedEntities).subList(startIndex, endIndex));
    // Fetch metadata for entities in the result list
    // Note: since the fetch is happening in a different transaction, the metadata for entities may have been
    // removed. It is okay not to have metadata for some results in case this happens.
    Map<NamespacedEntityId, Metadata> systemMetadata = fetchMetadata(sortedEntities, MetadataScope.SYSTEM);
    Map<NamespacedEntityId, Metadata> userMetadata = fetchMetadata(sortedEntities, MetadataScope.USER);
    return new MetadataSearchResponse(sortInfo.getSortBy() + " " + sortInfo.getSortOrder(), offset, limit, numCursors, total, addMetadataToEntities(sortedEntities, systemMetadata, userMetadata), cursors, showHidden, entityScope);
}
Also used : Metadata(co.cask.cdap.data2.metadata.dataset.Metadata) MetadataSearchResponse(co.cask.cdap.proto.metadata.MetadataSearchResponse) SearchResults(co.cask.cdap.data2.metadata.dataset.SearchResults) LinkedList(java.util.LinkedList) NamespacedEntityId(co.cask.cdap.proto.id.NamespacedEntityId) MetadataEntry(co.cask.cdap.data2.metadata.dataset.MetadataEntry) MetadataScope(co.cask.cdap.proto.metadata.MetadataScope)

Example 2 with SortInfo

use of co.cask.cdap.data2.metadata.dataset.SortInfo in project cdap by caskdata.

the class DefaultMetadataStore method getSortedEntities.

private Set<NamespacedEntityId> getSortedEntities(List<MetadataEntry> results, SortInfo sortInfo) {
    // in this case, the backing storage is expected to return results in the expected order.
    if (SortInfo.SortOrder.WEIGHTED != sortInfo.getSortOrder()) {
        Set<NamespacedEntityId> entities = new LinkedHashSet<>(results.size());
        for (MetadataEntry metadataEntry : results) {
            entities.add(metadataEntry.getTargetId());
        }
        return entities;
    }
    // if sort order is weighted, score results by weight, and return in descending order of weights
    // Score results
    final Map<NamespacedEntityId, Integer> weightedResults = new HashMap<>();
    for (MetadataEntry metadataEntry : results) {
        Integer score = weightedResults.get(metadataEntry.getTargetId());
        score = (score == null) ? 0 : score;
        weightedResults.put(metadataEntry.getTargetId(), score + 1);
    }
    // Sort the results by score
    List<Map.Entry<NamespacedEntityId, Integer>> resultList = new ArrayList<>(weightedResults.entrySet());
    Collections.sort(resultList, SEARCH_RESULT_DESC_SCORE_COMPARATOR);
    Set<NamespacedEntityId> result = new LinkedHashSet<>(resultList.size());
    for (Map.Entry<NamespacedEntityId, Integer> entry : resultList) {
        result.add(entry.getKey());
    }
    return result;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) NamespacedEntityId(co.cask.cdap.proto.id.NamespacedEntityId) MetadataEntry(co.cask.cdap.data2.metadata.dataset.MetadataEntry) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) MetadataEntry(co.cask.cdap.data2.metadata.dataset.MetadataEntry) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) HashMap(java.util.HashMap)

Example 3 with SortInfo

use of co.cask.cdap.data2.metadata.dataset.SortInfo in project cdap by caskdata.

the class MetadataHttpHandler method searchMetadata.

@GET
@Path("/namespaces/{namespace-id}/metadata/search")
public void searchMetadata(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId, @QueryParam("query") String searchQuery, @QueryParam("target") List<String> targets, @QueryParam("sort") @DefaultValue("") String sort, @QueryParam("offset") @DefaultValue("0") int offset, // 2147483647 is Integer.MAX_VALUE
@QueryParam("limit") @DefaultValue("2147483647") int limit, @QueryParam("numCursors") @DefaultValue("0") int numCursors, @QueryParam("cursor") @DefaultValue("") String cursor, @QueryParam("showHidden") @DefaultValue("false") boolean showHidden, @Nullable @QueryParam("entityScope") String entityScope) throws Exception {
    if (searchQuery == null || searchQuery.isEmpty()) {
        throw new BadRequestException("query is not specified");
    }
    Set<EntityTypeSimpleName> types = Collections.emptySet();
    if (targets != null) {
        types = ImmutableSet.copyOf(Iterables.transform(targets, STRING_TO_TARGET_TYPE));
    }
    SortInfo sortInfo = SortInfo.of(URLDecoder.decode(sort, "UTF-8"));
    if (SortInfo.DEFAULT.equals(sortInfo)) {
        if (!(cursor.isEmpty()) || 0 != numCursors) {
            throw new BadRequestException("Cursors are not supported when sort info is not specified.");
        }
    }
    try {
        MetadataSearchResponse response = metadataAdmin.search(namespaceId, URLDecoder.decode(searchQuery, "UTF-8"), types, sortInfo, offset, limit, numCursors, cursor, showHidden, validateEntityScope(entityScope));
        responder.sendJson(HttpResponseStatus.OK, response, MetadataSearchResponse.class, GSON);
    } catch (Exception e) {
        // if MetadataDataset throws an exception, it gets wrapped
        if (Throwables.getRootCause(e) instanceof BadRequestException) {
            throw new BadRequestException(e.getMessage(), e);
        }
        throw e;
    }
}
Also used : EntityTypeSimpleName(co.cask.cdap.proto.element.EntityTypeSimpleName) BadRequestException(co.cask.cdap.common.BadRequestException) MetadataSearchResponse(co.cask.cdap.proto.metadata.MetadataSearchResponse) BadRequestException(co.cask.cdap.common.BadRequestException) IOException(java.io.IOException) NotFoundException(co.cask.cdap.common.NotFoundException) SortInfo(co.cask.cdap.data2.metadata.dataset.SortInfo) Path(javax.ws.rs.Path) GET(javax.ws.rs.GET)

Aggregations

MetadataEntry (co.cask.cdap.data2.metadata.dataset.MetadataEntry)2 NamespacedEntityId (co.cask.cdap.proto.id.NamespacedEntityId)2 MetadataSearchResponse (co.cask.cdap.proto.metadata.MetadataSearchResponse)2 BadRequestException (co.cask.cdap.common.BadRequestException)1 NotFoundException (co.cask.cdap.common.NotFoundException)1 Metadata (co.cask.cdap.data2.metadata.dataset.Metadata)1 SearchResults (co.cask.cdap.data2.metadata.dataset.SearchResults)1 SortInfo (co.cask.cdap.data2.metadata.dataset.SortInfo)1 EntityTypeSimpleName (co.cask.cdap.proto.element.EntityTypeSimpleName)1 MetadataScope (co.cask.cdap.proto.metadata.MetadataScope)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 LinkedHashSet (java.util.LinkedHashSet)1 LinkedList (java.util.LinkedList)1 Map (java.util.Map)1 GET (javax.ws.rs.GET)1 Path (javax.ws.rs.Path)1