Skip to content

Commit

Permalink
Started implementation of staged query REST endpoint.
Browse files Browse the repository at this point in the history
  • Loading branch information
Spiess committed Nov 30, 2021
1 parent 10c79ca commit c2be67b
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 50 deletions.
21 changes: 6 additions & 15 deletions cineast-api/src/main/java/org/vitrivr/cineast/api/APIEndpoint.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import org.vitrivr.cineast.api.rest.handlers.actions.metadata.FindSegmentMetadataGetHandler;
import org.vitrivr.cineast.api.rest.handlers.actions.segment.FindSegmentByIdPostHandler;
import org.vitrivr.cineast.api.rest.handlers.actions.segment.FindSegmentSimilarPostHandler;
import org.vitrivr.cineast.api.rest.handlers.actions.segment.FindSegmentSimilarStagedPostHandler;
import org.vitrivr.cineast.api.rest.handlers.actions.segment.FindSegmentsByIdGetHandler;
import org.vitrivr.cineast.api.rest.handlers.actions.segment.FindSegmentsByObjectIdGetHandler;
import org.vitrivr.cineast.api.rest.handlers.actions.session.EndExtractionHandler;
Expand Down Expand Up @@ -291,21 +292,13 @@ public Javalin dispatchService(boolean secure) {
this.webSocketApi = new WebsocketAPI();

service.ws(String.format("%s/websocket", namespace()), handler -> {
handler.onConnect(ctx -> {
webSocketApi.connected(ctx.session);
});
handler.onConnect(ctx -> webSocketApi.connected(ctx.session));

handler.onClose(ctx -> {
webSocketApi.closed(ctx.session, ctx.status(), ctx.reason());
});
handler.onClose(ctx -> webSocketApi.closed(ctx.session, ctx.status(), ctx.reason()));

handler.onError(ctx -> {
webSocketApi.onWebSocketException(ctx.session, ctx.error());
});
handler.onError(ctx -> webSocketApi.onWebSocketException(ctx.session, ctx.error()));

handler.onMessage(ctx -> {
webSocketApi.message(ctx.session, ctx.message());
});
handler.onMessage(ctx -> webSocketApi.message(ctx.session, ctx.message()));
});
}

Expand Down Expand Up @@ -413,6 +406,7 @@ private void registerRestOperations() {
new FindSegmentsByIdGetHandler(),
new FindSegmentsByObjectIdGetHandler(),
new FindSegmentSimilarPostHandler(retrievalLogic),
new FindSegmentSimilarStagedPostHandler(retrievalLogic),
new FindSegmentFeaturesGetHandler(),
new FindFeaturesByCategoryGetHandler(),
new FindFeaturesByEntityGetHandler(),
Expand All @@ -439,9 +433,6 @@ private void registerRestOperations() {

/**
* If configured, this registers two special routes that serve the media objects as media content and additionally a thumbnails endpoint for them.
*
* @param service
* @param config
*/
private void registerServingRoutes(final Javalin service, final APIConfig config) {
if (config.getServeContent()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,10 @@
import org.vitrivr.cineast.api.messages.result.SimilarityQueryResultBatch;
import org.vitrivr.cineast.api.rest.handlers.interfaces.ParsingPostRestHandler;
import org.vitrivr.cineast.api.util.QueryUtil;
import org.vitrivr.cineast.core.config.QueryConfig;
import org.vitrivr.cineast.core.config.ReadableQueryConfig;
import org.vitrivr.cineast.core.data.Pair;
import org.vitrivr.cineast.core.data.StringDoublePair;
import org.vitrivr.cineast.core.data.query.containers.AbstractQueryTermContainer;
import org.vitrivr.cineast.standalone.config.Config;
import org.vitrivr.cineast.standalone.config.ConstrainedQueryConfig;
import org.vitrivr.cineast.standalone.util.ContinuousRetrievalLogic;

Expand All @@ -31,28 +29,20 @@ public FindSegmentSimilarPostHandler(ContinuousRetrievalLogic continuousRetrieva

@Override
public SimilarityQueryResultBatch performPost(SimilarityQuery query, Context ctx) {
ConstrainedQueryConfig config = ConstrainedQueryConfig.getApplyingConfig(query.getQueryConfig());

HashMap<String, List<StringDoublePair>> returnMap = new HashMap<>();
/*
* Prepare map that maps categories to QueryTerm components.
*/
HashMap<String, ArrayList<AbstractQueryTermContainer>> categoryMap = QueryUtil.groupQueryTermsByCategory(query.getTerms());

QueryConfig config = query.getQueryConfig();
ConstrainedQueryConfig qconf = new ConstrainedQueryConfig(config);
if (config == null) {
final int max = Math.min(qconf.getMaxResults().orElse(Config.sharedConfig().getRetriever().getMaxResults()), Config.sharedConfig().getRetriever().getMaxResults());
qconf.setMaxResults(max);
final int resultsPerModule = Math.min(qconf.getRawResultsPerModule() == -1 ? Config.sharedConfig().getRetriever().getMaxResultsPerModule() : qconf.getResultsPerModule(), Config.sharedConfig().getRetriever().getMaxResultsPerModule());
qconf.setResultsPerModule(resultsPerModule);
}

for (String category : categoryMap.keySet()) {
List<Pair<AbstractQueryTermContainer, ReadableQueryConfig>> containerList = categoryMap.get(category).stream().map(x -> new Pair<>(x, (ReadableQueryConfig) qconf)).collect(Collectors.toList());
List<Pair<AbstractQueryTermContainer, ReadableQueryConfig>> containerList = categoryMap.get(category).stream().map(x -> new Pair<>(x, (ReadableQueryConfig) config)).collect(Collectors.toList());
returnMap.put(category, QueryUtil.retrieveCategory(continuousRetrievalLogic, containerList, category));
}

return new SimilarityQueryResultBatch(returnMap, qconf.getQueryId().toString());
return new SimilarityQueryResultBatch(returnMap, config.getQueryId().toString());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package org.vitrivr.cineast.api.rest.handlers.actions.segment;

import io.javalin.http.Context;
import io.javalin.plugin.openapi.dsl.OpenApiBuilder;
import io.javalin.plugin.openapi.dsl.OpenApiDocumentation;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.vitrivr.cineast.api.messages.query.QueryStage;
import org.vitrivr.cineast.api.messages.query.QueryTerm;
import org.vitrivr.cineast.api.messages.query.StagedSimilarityQuery;
import org.vitrivr.cineast.api.messages.result.SimilarityQueryResultBatch;
import org.vitrivr.cineast.api.rest.handlers.interfaces.ParsingPostRestHandler;
import org.vitrivr.cineast.standalone.config.ConstrainedQueryConfig;
import org.vitrivr.cineast.standalone.util.ContinuousRetrievalLogic;

public class FindSegmentSimilarStagedPostHandler implements ParsingPostRestHandler<StagedSimilarityQuery, SimilarityQueryResultBatch> {

public static final String ROUTE = "find/segments/similar/staged";
private final ContinuousRetrievalLogic continuousRetrievalLogic;

private static final Logger LOGGER = LogManager.getLogger();

public FindSegmentSimilarStagedPostHandler(ContinuousRetrievalLogic continuousRetrievalLogic) {
this.continuousRetrievalLogic = continuousRetrievalLogic;
}


@Override
public OpenApiDocumentation docs() {
return OpenApiBuilder.document()
.operation(op -> {
op.summary("Find similar segments based on the given staged query");
op.description("Performs a similarity search based on the formulated query stages, executing each subsequent stage on the results of the previous stage");
op.operationId("findSegmentSimilarStaged");
op.addTagsItem("Segments");
})
.body(inClass())
.json("200", outClass());
}

@Override
public SimilarityQueryResultBatch performPost(StagedSimilarityQuery query, Context ctx) {
ConstrainedQueryConfig config = ConstrainedQueryConfig.getApplyingConfig(query.getConfig());

// TODO: Could staged queries be pushed down to DB to optimize?

This comment has been minimized.

Copy link
@lucaro

lucaro Nov 30, 2021

Member

Since the modules can perform arbitrary operations, no, sorry.

for (QueryStage stage : query.getStages()) {
for (QueryTerm term : stage.terms) {
// TODO
}
}

return null;
}

@Override
public Class<StagedSimilarityQuery> inClass() {
return StagedSimilarityQuery.class;
}

@Override
public Class<SimilarityQueryResultBatch> outClass() {
return SimilarityQueryResultBatch.class;
}

@Override
public String route() {
return ROUTE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public static List<StringDoublePair> retrieveCategory(

list.sort(StringDoublePair.COMPARATOR);

// FIXME: Using an arbitrary query config to limit results is prone to errors
final int MAX_RESULTS = queryContainers.get(0).second.getMaxResults()
.orElse(Config.sharedConfig().getRetriever().getMaxResults());
List<StringDoublePair> resultList = list;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,40 @@

public class ConstrainedQueryConfig extends QueryConfig {

public ConstrainedQueryConfig(String queryId, List<Hints> hints) {
super(queryId, hints);
public ConstrainedQueryConfig(String queryId, List<Hints> hints) {
super(queryId, hints);
}

public ConstrainedQueryConfig(ReadableQueryConfig qc) {
super(qc);
}

public ConstrainedQueryConfig() {
super(null);
}

@Override
public int getResultsPerModule() {
return Math.min(Config.sharedConfig().getRetriever().getMaxResultsPerModule(), super.getResultsPerModule());
}

@Override
public Optional<Integer> getMaxResults() {
if (super.getMaxResults().isPresent()) {
return Optional.of(Math.min(Config.sharedConfig().getRetriever().getMaxResults(), super.getMaxResults().get()));
}

public ConstrainedQueryConfig(ReadableQueryConfig qc) {
super(qc);
}

public ConstrainedQueryConfig() {
super(null);
}

@Override
public int getResultsPerModule() { return Math.min(Config.sharedConfig().getRetriever().getMaxResultsPerModule(), super.getResultsPerModule()); }

@Override
public Optional<Integer> getMaxResults() {
if (super.getMaxResults().isPresent()) {
return Optional.of(Math.min(Config.sharedConfig().getRetriever().getMaxResults(), super.getMaxResults().get()));
}
return Optional.of(Config.sharedConfig().getRetriever().getMaxResults());
return Optional.of(Config.sharedConfig().getRetriever().getMaxResults());
}

public static ConstrainedQueryConfig getApplyingConfig(QueryConfig config) {
ConstrainedQueryConfig queryConfig = new ConstrainedQueryConfig(config);
if (config == null) {
final int max = Math.min(queryConfig.getMaxResults().orElse(Config.sharedConfig().getRetriever().getMaxResults()), Config.sharedConfig().getRetriever().getMaxResults());
queryConfig.setMaxResults(max);
final int resultsPerModule = Math.min(queryConfig.getRawResultsPerModule() == -1 ? Config.sharedConfig().getRetriever().getMaxResultsPerModule() : queryConfig.getResultsPerModule(), Config.sharedConfig().getRetriever().getMaxResultsPerModule());
queryConfig.setResultsPerModule(resultsPerModule);
}



return queryConfig;
}
}

0 comments on commit c2be67b

Please sign in to comment.