mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
[SEARCH-2677] Extract SearchEngineResultSet and SearchEngineResultMetadata interfaces (#286)
* [SEARCH-2677] Extract SearchEngineResultSet and SearchEngineResultMetadata interfaces * [SEARCH-2677] Scan the ResultSet decorator chain for a maximum of 3 nested levels
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
package org.alfresco.rest.api.search.impl;
|
||||
|
||||
import static java.util.Optional.empty;
|
||||
import static java.util.Optional.of;
|
||||
import static org.alfresco.rest.api.search.impl.StoreMapper.DELETED;
|
||||
import static org.alfresco.rest.api.search.impl.StoreMapper.HISTORY;
|
||||
import static org.alfresco.rest.api.search.impl.StoreMapper.LIVE_NODES;
|
||||
@@ -42,9 +44,10 @@ import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.alfresco.repo.search.impl.solr.SolrJSONResultSet;
|
||||
import org.alfresco.repo.search.SearchEngineResultSet;
|
||||
import org.alfresco.repo.search.impl.solr.facet.facetsresponse.GenericBucket;
|
||||
import org.alfresco.repo.search.impl.solr.facet.facetsresponse.GenericFacetResponse;
|
||||
import org.alfresco.repo.search.impl.solr.facet.facetsresponse.GenericFacetResponse.FACET_TYPE;
|
||||
@@ -153,12 +156,10 @@ public class ResultMapper
|
||||
*/
|
||||
public CollectionWithPagingInfo<Node> toCollectionWithPagingInfo(Params params, SearchRequestContext searchRequestContext, SearchQuery searchQuery, ResultSet results)
|
||||
{
|
||||
SearchContext context = null;
|
||||
Integer total = null;
|
||||
List<Node> noderesults = new ArrayList<Node>();
|
||||
List<Node> noderesults = new ArrayList<>();
|
||||
Map<String, UserInfo> mapUserInfo = new HashMap<>(10);
|
||||
Map<NodeRef, List<Pair<String, List<String>>>> hightLighting = results.getHighlighting();
|
||||
int notFound = 0;
|
||||
Map<NodeRef, List<Pair<String, List<String>>>> highLighting = results.getHighlighting();
|
||||
final AtomicInteger unknownNodeRefsCount = new AtomicInteger();
|
||||
boolean isHistory = searchRequestContext.getStores().contains(StoreMapper.HISTORY);
|
||||
|
||||
for (ResultSetRow row:results)
|
||||
@@ -169,7 +170,7 @@ public class ResultMapper
|
||||
{
|
||||
float f = row.getScore();
|
||||
List<HighlightEntry> highlightEntries = null;
|
||||
List<Pair<String, List<String>>> high = hightLighting.get(row.getNodeRef());
|
||||
List<Pair<String, List<String>>> high = highLighting.get(row.getNodeRef());
|
||||
|
||||
if (high != null && !high.isEmpty())
|
||||
{
|
||||
@@ -185,26 +186,21 @@ public class ResultMapper
|
||||
else
|
||||
{
|
||||
logger.debug("Unknown noderef returned from search results "+row.getNodeRef());
|
||||
notFound++;
|
||||
unknownNodeRefsCount.incrementAndGet();
|
||||
}
|
||||
}
|
||||
|
||||
SolrJSONResultSet solrResultSet = findSolrResultSet(results);
|
||||
SearchContext context =
|
||||
toSearchEngineResultSet(results)
|
||||
.map(resultSet -> toSearchContext(resultSet, searchRequestContext, searchQuery))
|
||||
.orElse(null);
|
||||
|
||||
if (solrResultSet != null)
|
||||
{
|
||||
//We used Solr for this query
|
||||
context = toSearchContext(solrResultSet, searchRequestContext, searchQuery, notFound);
|
||||
}
|
||||
|
||||
total = setTotal(results);
|
||||
|
||||
return CollectionWithPagingInfo.asPaged(params.getPaging(), noderesults, results.hasMore(), total, null, context);
|
||||
return CollectionWithPagingInfo.asPaged(params.getPaging(), noderesults, results.hasMore(), setTotal(results), null, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a node representation based on a ResultSetRow;
|
||||
* @param searchRequestContext
|
||||
*
|
||||
* @param aRow
|
||||
* @param params
|
||||
* @param mapUserInfo
|
||||
@@ -285,14 +281,14 @@ public class ResultMapper
|
||||
|
||||
/**
|
||||
* Uses the results from Solr to set the Search Context
|
||||
* @param SolrJSONResultSet
|
||||
*
|
||||
* @param searchQuery
|
||||
* @return SearchContext
|
||||
*/
|
||||
public SearchContext toSearchContext(SolrJSONResultSet solrResultSet, SearchRequestContext searchRequestContext, SearchQuery searchQuery, int notFound)
|
||||
public SearchContext toSearchContext(SearchEngineResultSet resultSet, SearchRequestContext searchRequestContext, SearchQuery searchQuery)
|
||||
{
|
||||
SearchContext context = null;
|
||||
Map<String, Integer> facetQueries = solrResultSet.getFacetQueries();
|
||||
Map<String, Integer> facetQueries = resultSet.getFacetQueries();
|
||||
List<GenericFacetResponse> facets = new ArrayList<>();
|
||||
List<FacetQueryContext> facetResults = null;
|
||||
SpellCheckContext spellCheckContext = null;
|
||||
@@ -330,7 +326,7 @@ public class ResultMapper
|
||||
}
|
||||
|
||||
//Field Facets
|
||||
Map<String, List<Pair<String, Integer>>> facetFields = solrResultSet.getFieldFacets();
|
||||
Map<String, List<Pair<String, Integer>>> facetFields = resultSet.getFieldFacets();
|
||||
if(FacetFormat.V2 == searchQuery.getFacetFormat())
|
||||
{
|
||||
facets.addAll(getFacetBucketsForFacetFieldsAsFacets(facetFields, searchQuery));
|
||||
@@ -340,28 +336,29 @@ public class ResultMapper
|
||||
ffcs.addAll(getFacetBucketsForFacetFields(facetFields, searchQuery));
|
||||
}
|
||||
|
||||
Map<String, List<Pair<String, Integer>>> facetInterval = solrResultSet.getFacetIntervals();
|
||||
Map<String, List<Pair<String, Integer>>> facetInterval = resultSet.getFacetIntervals();
|
||||
facets.addAll(getGenericFacetsForIntervals(facetInterval, searchQuery));
|
||||
|
||||
Map<String,List<Map<String,String>>> facetRanges = solrResultSet.getFacetRanges();
|
||||
Map<String,List<Map<String,String>>> facetRanges = resultSet.getFacetRanges();
|
||||
facets.addAll(RangeResultMapper.getGenericFacetsForRanges(facetRanges, searchQuery.getFacetRanges()));
|
||||
|
||||
List<GenericFacetResponse> stats = getFieldStats(searchRequestContext, solrResultSet.getStats());
|
||||
List<GenericFacetResponse> pimped = getPivots(searchRequestContext, solrResultSet.getPivotFacets(), stats);
|
||||
List<GenericFacetResponse> stats = getFieldStats(searchRequestContext, resultSet.getStats());
|
||||
List<GenericFacetResponse> pimped = getPivots(searchRequestContext, resultSet.getPivotFacets(), stats);
|
||||
facets.addAll(pimped);
|
||||
facets.addAll(stats);
|
||||
|
||||
//Spelling
|
||||
SpellCheckResult spell = solrResultSet.getSpellCheckResult();
|
||||
SpellCheckResult spell = resultSet.getSpellCheckResult();
|
||||
if (spell != null && spell.getResultName() != null && !spell.getResults().isEmpty())
|
||||
{
|
||||
spellCheckContext = new SpellCheckContext(spell.getResultName(),spell.getResults());
|
||||
}
|
||||
|
||||
//Put it all together
|
||||
context = new SearchContext(solrResultSet.getLastIndexedTxId(), facets, facetResults, ffcs, spellCheckContext, searchRequestContext.includeRequest()?searchQuery:null);
|
||||
context = new SearchContext(resultSet.getLastIndexedTxId(), facets, facetResults, ffcs, spellCheckContext, searchRequestContext.includeRequest()?searchQuery:null);
|
||||
return isNullContext(context)?null:context;
|
||||
}
|
||||
|
||||
public static boolean hasGroup(SearchQuery searchQuery)
|
||||
{
|
||||
if(searchQuery != null && searchQuery.getFacetQueries() != null)
|
||||
@@ -618,26 +615,32 @@ public class ResultMapper
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets SolrJSONResultSet class if there is one.
|
||||
* @param results
|
||||
* @return
|
||||
* Tries to see if the input {@link ResultSet} or one of the wrapped {@link ResultSet}
|
||||
* is an instance of {@link SearchEngineResultSet}.
|
||||
* Since some concrete ResultSet implements the decorator patterns, the code
|
||||
* assumes (in those cases) a nested structure with a maximum of 3 levels.
|
||||
* Probably the code could be generalised better in order to scan a decorator
|
||||
* chain with an unlimited depth, but that would require a change in the ResultSet interface.
|
||||
*/
|
||||
protected SolrJSONResultSet findSolrResultSet(ResultSet results)
|
||||
protected Optional<SearchEngineResultSet> toSearchEngineResultSet(ResultSet results)
|
||||
{
|
||||
ResultSet theResultSet = results;
|
||||
|
||||
if (results instanceof FilteringResultSet)
|
||||
{
|
||||
theResultSet = ((FilteringResultSet) results).getUnFilteredResultSet();
|
||||
// 1st level
|
||||
results = ((FilteringResultSet) results).getUnFilteredResultSet();
|
||||
|
||||
// 2nd level
|
||||
if (results instanceof FilteringResultSet)
|
||||
{
|
||||
results = ((FilteringResultSet) results).getUnFilteredResultSet();
|
||||
}
|
||||
}
|
||||
|
||||
if (theResultSet instanceof SolrJSONResultSet)
|
||||
{
|
||||
return (SolrJSONResultSet) theResultSet;
|
||||
}
|
||||
|
||||
return null;
|
||||
return results instanceof SearchEngineResultSet
|
||||
? of(results).map(SearchEngineResultSet.class::cast)
|
||||
: empty();
|
||||
}
|
||||
|
||||
public CollectionWithPagingInfo<TupleList> toCollectionWithPagingInfo(JSONArray docs, SearchSQLQuery searchQuery) throws JSONException
|
||||
{
|
||||
if(docs == null )
|
||||
|
@@ -52,6 +52,7 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.alfresco.repo.search.EmptyResultSet;
|
||||
import org.alfresco.repo.search.SearchEngineResultSet;
|
||||
import org.alfresco.repo.search.impl.solr.SolrJSONResultSet;
|
||||
import org.alfresco.repo.search.impl.solr.facet.facetsresponse.GenericBucket;
|
||||
import org.alfresco.repo.search.impl.solr.facet.facetsresponse.GenericFacetResponse;
|
||||
@@ -303,7 +304,7 @@ public class ResultMapperTests
|
||||
SearchQuery searchQuery = helper.searchQueryFromJson();
|
||||
SearchRequestContext searchRequest = SearchRequestContext.from(searchQuery);
|
||||
SearchParameters searchParams = searchMapper.toSearchParameters(EMPTY_PARAMS, searchQuery, searchRequest);
|
||||
SearchContext searchContext = mapper.toSearchContext((SolrJSONResultSet) results, searchRequest, searchQuery, 0);
|
||||
SearchContext searchContext = mapper.toSearchContext((SearchEngineResultSet) results, searchRequest, searchQuery);
|
||||
assertEquals(34l, searchContext.getConsistency().getlastTxId());
|
||||
assertEquals(6, searchContext.getFacetQueries().size());
|
||||
assertEquals(0,searchContext.getFacetQueries().get(0).getCount());
|
||||
@@ -437,7 +438,7 @@ public class ResultMapperTests
|
||||
SearchQuery searchQuery = helper.searchQueryFromJson();
|
||||
SearchRequestContext searchRequest = SearchRequestContext.from(searchQuery);
|
||||
SearchParameters searchParams = searchMapper.toSearchParameters(EMPTY_PARAMS, searchQuery, searchRequest);
|
||||
SearchContext searchContext = mapper.toSearchContext((SolrJSONResultSet) results, searchRequest, searchQuery, 0);
|
||||
SearchContext searchContext = mapper.toSearchContext((SearchEngineResultSet) results, searchRequest, searchQuery);
|
||||
|
||||
//Facet intervals
|
||||
List<GenericFacetResponse> intervalFacets = searchContext.getFacets().stream()
|
||||
@@ -477,7 +478,7 @@ public class ResultMapperTests
|
||||
SearchQuery searchQuery = helper.searchQueryFromJson();
|
||||
SearchRequestContext searchRequest = SearchRequestContext.from(searchQuery);
|
||||
SearchParameters searchParams = searchMapper.toSearchParameters(EMPTY_PARAMS, searchQuery, searchRequest);
|
||||
SearchContext searchContext = mapper.toSearchContext((SolrJSONResultSet) results, searchRequest, searchQuery, 0);
|
||||
SearchContext searchContext = mapper.toSearchContext((SearchEngineResultSet) results, searchRequest, searchQuery);
|
||||
|
||||
//Numeric facet range
|
||||
List<GenericFacetResponse> rangeFacets = searchContext.getFacets().stream()
|
||||
@@ -531,7 +532,7 @@ public class ResultMapperTests
|
||||
SearchQuery searchQuery = helper.extractFromJson(updatedJSON);
|
||||
SearchRequestContext searchRequest = SearchRequestContext.from(searchQuery);
|
||||
SearchParameters searchParams = searchMapper.toSearchParameters(EMPTY_PARAMS, searchQuery, searchRequest);
|
||||
SearchContext searchContext = mapper.toSearchContext((SolrJSONResultSet) results, searchRequest, searchQuery, 0);
|
||||
SearchContext searchContext = mapper.toSearchContext((SearchEngineResultSet) results, searchRequest, searchQuery);
|
||||
|
||||
//Numeric facet range
|
||||
List<GenericFacetResponse> rangeFacets = searchContext.getFacets().stream()
|
||||
@@ -575,7 +576,7 @@ public class ResultMapperTests
|
||||
ResultSet results = mockResultset(expectedResponse);
|
||||
SearchQuery searchQuery = helper.extractFromJson(jsonQuery);
|
||||
SearchRequestContext searchRequest = SearchRequestContext.from(searchQuery);
|
||||
SearchContext searchContext = mapper.toSearchContext((SolrJSONResultSet) results, searchRequest, searchQuery, 0);
|
||||
SearchContext searchContext = mapper.toSearchContext((SearchEngineResultSet) results, searchRequest, searchQuery);
|
||||
assertEquals(34l, searchContext.getConsistency().getlastTxId());
|
||||
assertEquals(null, searchContext.getFacetQueries());
|
||||
assertEquals(1, searchContext.getFacets().size());
|
||||
@@ -610,7 +611,7 @@ public class ResultMapperTests
|
||||
ResultSet results = mockResultset(expectedResponse);
|
||||
SearchQuery searchQuery = helper.extractFromJson(jsonQuery);
|
||||
SearchRequestContext searchRequest = SearchRequestContext.from(searchQuery);
|
||||
SearchContext searchContext = mapper.toSearchContext((SolrJSONResultSet) results, searchRequest, searchQuery, 0);
|
||||
SearchContext searchContext = mapper.toSearchContext((SearchEngineResultSet) results, searchRequest, searchQuery);
|
||||
assertEquals(34l, searchContext.getConsistency().getlastTxId());
|
||||
assertEquals(null, searchContext.getFacetQueries());
|
||||
assertEquals(2, searchContext.getFacets().size());
|
||||
@@ -648,7 +649,7 @@ public class ResultMapperTests
|
||||
ResultSet results = mockResultset(expectedResponse);
|
||||
SearchQuery searchQuery = helper.extractFromJson(jsonQuery);
|
||||
SearchRequestContext searchRequest = SearchRequestContext.from(searchQuery);
|
||||
SearchContext searchContext = mapper.toSearchContext((SolrJSONResultSet) results, searchRequest, searchQuery, 0);
|
||||
SearchContext searchContext = mapper.toSearchContext((SearchEngineResultSet) results, searchRequest, searchQuery);
|
||||
assertEquals(34l, searchContext.getConsistency().getlastTxId());
|
||||
assertTrue(searchContext.getFacets().isEmpty());
|
||||
assertEquals(3,searchContext.getFacetQueries().size());
|
||||
@@ -722,7 +723,7 @@ public class ResultMapperTests
|
||||
ResultSet results = mockResultset(expectedResponse);
|
||||
SearchQuery searchQuery = helper.extractFromJson(jsonQuery);
|
||||
SearchRequestContext searchRequest = SearchRequestContext.from(searchQuery);
|
||||
SearchContext searchContext = mapper.toSearchContext((SolrJSONResultSet) results, searchRequest, searchQuery, 0);
|
||||
SearchContext searchContext = mapper.toSearchContext((SearchEngineResultSet) results, searchRequest, searchQuery);
|
||||
assertEquals(34l, searchContext.getConsistency().getlastTxId());
|
||||
assertEquals(null, searchContext.getFacetQueries());
|
||||
assertEquals(1, searchContext.getFacets().size());
|
||||
@@ -738,7 +739,7 @@ public class ResultMapperTests
|
||||
searchQuery = helper.extractFromJson(jsonQuery);
|
||||
results = mockResultset(expectedResponse);
|
||||
searchRequest = SearchRequestContext.from(searchQuery);
|
||||
searchContext = mapper.toSearchContext((SolrJSONResultSet) results, searchRequest, searchQuery, 0);
|
||||
searchContext = mapper.toSearchContext((SearchEngineResultSet) results, searchRequest, searchQuery);
|
||||
assertEquals(34l, searchContext.getConsistency().getlastTxId());
|
||||
assertEquals(3,searchContext.getFacetQueries().size());
|
||||
assertEquals("small",searchContext.getFacetQueries().get(0).getLabel());
|
||||
@@ -759,7 +760,7 @@ public class ResultMapperTests
|
||||
+ "\"processedDenies\":true, \"lastIndexedTx\":34}";
|
||||
results = mockResultset(expectedResponse);
|
||||
searchQuery = helper.extractFromJson(jsonQuery);
|
||||
searchContext = mapper.toSearchContext((SolrJSONResultSet) results, searchRequest, searchQuery, 0);
|
||||
searchContext = mapper.toSearchContext((SearchEngineResultSet) results, searchRequest, searchQuery);
|
||||
assertFalse(searchContext.getFacetsFields().isEmpty());
|
||||
assertTrue(searchContext.getFacets().isEmpty());
|
||||
assertEquals("creator",searchContext.getFacetsFields().get(0).getLabel());
|
||||
@@ -770,7 +771,7 @@ public class ResultMapperTests
|
||||
assertEquals("modifier",searchContext.getFacetsFields().get(1).getLabel());
|
||||
jsonQuery = jsonQuery.replace("V1", "V2");
|
||||
searchQuery = helper.extractFromJson(jsonQuery);
|
||||
searchContext = mapper.toSearchContext((SolrJSONResultSet) results, searchRequest, searchQuery, 0);
|
||||
searchContext = mapper.toSearchContext((SearchEngineResultSet) results, searchRequest, searchQuery);
|
||||
assertTrue(searchContext.getFacetsFields().isEmpty());
|
||||
assertFalse(searchContext.getFacets().isEmpty());
|
||||
assertEquals("creator",searchContext.getFacets().get(0).getLabel());
|
||||
@@ -835,7 +836,7 @@ public class ResultMapperTests
|
||||
ResultSet results = mockResultset(expectedResponse);
|
||||
SearchQuery searchQuery = helper.extractFromJson(jsonQuery);
|
||||
SearchRequestContext searchRequest = SearchRequestContext.from(searchQuery);
|
||||
SearchContext searchContext = mapper.toSearchContext((SolrJSONResultSet) results, searchRequest, searchQuery, 0);
|
||||
SearchContext searchContext = mapper.toSearchContext((SearchEngineResultSet) results, searchRequest, searchQuery);
|
||||
assertEquals(34l, searchContext.getConsistency().getlastTxId());
|
||||
assertEquals(null, searchContext.getFacetQueries());
|
||||
assertEquals(3, searchContext.getFacets().size());
|
||||
|
Reference in New Issue
Block a user