alessandrobenedetti commented on a change in pull request #1571: URL: https://github.com/apache/lucene-solr/pull/1571#discussion_r523074662
########## File path: solr/contrib/ltr/src/java/org/apache/solr/ltr/response/transform/LTRFeatureLoggerTransformerFactory.java ########## @@ -208,55 +216,116 @@ public void setContext(ResultContext context) { if (threadManager != null) { threadManager.setExecutor(context.getRequest().getCore().getCoreContainer().getUpdateShardHandler().getUpdateExecutor()); } - - // Setup LTRScoringQuery - scoringQuery = SolrQueryRequestContextUtils.getScoringQuery(req); - docsWereNotReranked = (scoringQuery == null); - String featureStoreName = SolrQueryRequestContextUtils.getFvStoreName(req); - if (docsWereNotReranked || (featureStoreName != null && (!featureStoreName.equals(scoringQuery.getScoringModel().getFeatureStoreName())))) { - // if store is set in the transformer we should overwrite the logger - final ManagedFeatureStore fr = ManagedFeatureStore.getManagedFeatureStore(req.getCore()); + LTRScoringQuery[] rerankingQueriesFromContext = SolrQueryRequestContextUtils.getScoringQueries(req); + docsWereNotReranked = (rerankingQueriesFromContext == null || rerankingQueriesFromContext.length == 0); + String transformerFeatureStore = SolrQueryRequestContextUtils.getFvStoreName(req); + Map<String, String[]> transformerExternalFeatureInfo = LTRQParserPlugin.extractEFIParams(localparams); - final FeatureStore store = fr.getFeatureStore(featureStoreName); - featureStoreName = store.getName(); // if featureStoreName was null before this gets actual name - - try { - final LoggingModel lm = new LoggingModel(loggingModelName, - featureStoreName, store.getFeatures()); + initLoggingModel(transformerFeatureStore); + setupRerankingQueriesForLogging(rerankingQueriesFromContext, transformerFeatureStore, transformerExternalFeatureInfo); + setupRerankingWeightsForLogging(context); + } + + private boolean isModelMatchingFeatureStore(String featureStoreName, LTRScoringModel model) { + return model != null && featureStoreName.equals(model.getFeatureStoreName()); + } - scoringQuery = new LTRScoringQuery(lm, - LTRQParserPlugin.extractEFIParams(localparams), - true, - threadManager); // request feature weights to be created for all features + /** + * The loggingModel is an empty model that is just used to extract the features + * and log them + * @param transformerFeatureStore the explicit transformer feature store + */ + private void initLoggingModel(String transformerFeatureStore) { + if (transformerFeatureStore == null || !isModelMatchingFeatureStore(transformerFeatureStore, loggingModel)) { + // if store is set in the transformer we should overwrite the logger + final ManagedFeatureStore fr = ManagedFeatureStore.getManagedFeatureStore(req.getCore()); - }catch (final Exception e) { - throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, - "retrieving the feature store "+featureStoreName, e); - } - } + final FeatureStore store = fr.getFeatureStore(transformerFeatureStore); + transformerFeatureStore = store.getName(); // if featureStoreName was null before this gets actual name - if (scoringQuery.getOriginalQuery() == null) { - scoringQuery.setOriginalQuery(context.getQuery()); + loggingModel = new LoggingModel(loggingModelName, + transformerFeatureStore, store.getFeatures()); } - if (scoringQuery.getFeatureLogger() == null){ - scoringQuery.setFeatureLogger( SolrQueryRequestContextUtils.getFeatureLogger(req) ); - } - scoringQuery.setRequest(req); - - featureLogger = scoringQuery.getFeatureLogger(); + } - try { - modelWeight = scoringQuery.createWeight(searcher, ScoreMode.COMPLETE, 1f); - } catch (final IOException e) { - throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, e.getMessage(), e); + /** + * When preparing the reranking queries for logging features various scenarios apply: + * + * No Reranking + * There is the need of a logger model from the default feature store/ the explicit feature store passed + * to extract the feature vector + * + * Re Ranking + * 1) If no explicit feature store is passed, the models for each reranking query can be safely re-used + * the feature vector can be fetched from the feature vector cache. + * 2) If an explicit feature store is passed, and no reranking query uses a model from that featureStore, + * There is the need of a logger model to extract the feature vector + * 3) If an explicit feature store is passed, and there is a reranking query that uses a model from that featureStore, + * It can be re-used + * + * @param rerankingQueriesFromContext reranking queries + * @param transformerFeatureStore explicit feature store for the transformer + * @param transformerExternalFeatureInfo explicit efi for the transformer + */ + private void setupRerankingQueriesForLogging(LTRScoringQuery[] rerankingQueriesFromContext, String transformerFeatureStore, Map<String, String[]> transformerExternalFeatureInfo) { + if (docsWereNotReranked) { //no reranking query + LTRScoringQuery loggingQuery = new LTRScoringQuery(loggingModel, + transformerExternalFeatureInfo, + true, + threadManager); + rerankingQueries = new LTRScoringQuery[]{loggingQuery}; + } else { + rerankingQueries = new LTRScoringQuery[rerankingQueriesFromContext.length]; + System.arraycopy(rerankingQueriesFromContext, 0, rerankingQueries, 0, rerankingQueriesFromContext.length); + + if (transformerFeatureStore != null) {// explicit feature store for the transformer + LTRScoringModel matchingRerankingModel = null; + for (LTRScoringQuery rerankingQuery : rerankingQueries) { + if (isModelMatchingFeatureStore(transformerFeatureStore, rerankingQuery.getScoringModel())) { + matchingRerankingModel = rerankingQuery.getScoringModel(); + } + } + if (matchingRerankingModel != null) {//one of the LTR query model can be re-used + for (LTRScoringQuery rerankingQuery : rerankingQueries) { + rerankingQuery.setLtrScoringModel(matchingRerankingModel); + } + } else { + for (LTRScoringQuery rerankingQuery : rerankingQueries) { + rerankingQuery.setLtrScoringModel(loggingModel); + rerankingQuery.setExtractAllFeatures(true); + rerankingQuery.setEfi(transformerExternalFeatureInfo); + } Review comment: LTRScoringQuery queries may be LTRInterleavingScoringQuery, containing the picked document Ids we don't want to lose ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: issues-unsubscr...@lucene.apache.org For additional commands, e-mail: issues-h...@lucene.apache.org