Merged searchrep (5.2.1) to 5.2.N (5.2.1)

136623 gjames: SEARCH-409: Initial solr stats api


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@137032 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Gethin James
2017-06-01 11:06:54 +00:00
parent 6f2fc20e18
commit 3445581377
7 changed files with 213 additions and 33 deletions

View File

@@ -29,11 +29,14 @@ package org.alfresco.rest.api.search.impl;
import static org.alfresco.rest.api.search.impl.StoreMapper.DELETED;
import static org.alfresco.rest.api.search.impl.StoreMapper.LIVE_NODES;
import static org.alfresco.rest.api.search.impl.StoreMapper.VERSIONS;
import com.sun.javafx.font.Metrics;
import org.alfresco.repo.search.impl.lucene.SolrJSONResultSet;
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;
import org.alfresco.repo.search.impl.solr.facet.facetsresponse.MetricCount;
import org.alfresco.repo.search.impl.solr.facet.facetsresponse.Metric;
import org.alfresco.repo.search.impl.solr.facet.facetsresponse.Metric.METRIC_TYPE;
import org.alfresco.repo.search.impl.solr.facet.facetsresponse.SimpleMetric;
import org.alfresco.repo.security.permissions.impl.acegi.FilteringResultSet;
import org.alfresco.repo.version.Version2Model;
import org.alfresco.rest.api.DeletedNodes;
@@ -318,8 +321,10 @@ public class ResultMapper
Map<String, List<Pair<String, Integer>>> facetInterval = solrResultSet.getFacetIntervals();
facets.addAll(getGenericFacetsForIntervals(facetInterval, searchQuery));
List<GenericFacetResponse> pimped = getPivots(searchRequestContext, solrResultSet.getPivotFacets());
List<GenericFacetResponse> stats = getFieldStats(searchRequestContext, solrResultSet.getStats());
List<GenericFacetResponse> pimped = getPivots(searchRequestContext, solrResultSet.getPivotFacets(), stats);
facets.addAll(pimped);
facets.addAll(stats);
//Spelling
SpellCheckResult spell = solrResultSet.getSpellCheckResult();
@@ -332,6 +337,7 @@ public class ResultMapper
context = new SearchContext(solrResultSet.getLastIndexedTxId(), facets, facetResults, ffcs, spellCheckContext, searchRequestContext.includeRequest()?searchQuery:null);
return isNullContext(context)?null:context;
}
/**
* Builds a facet field from facet queries.
* @param facetQueries
@@ -376,7 +382,23 @@ public class ResultMapper
return facetResults;
}
protected List<GenericFacetResponse> getPivots(SearchRequestContext searchRequest, List<GenericFacetResponse> pivots)
protected List<GenericFacetResponse> getFieldStats(SearchRequestContext searchRequestContext, Map<String, List<Metric>> stats)
{
if(stats != null && !stats.isEmpty())
{
return stats.entrySet().stream().map(statsFieldEntry -> {
return new GenericFacetResponse(FACET_TYPE.stats, statsFieldEntry.getKey(),
Arrays.asList(new GenericBucket(null,null, null,
statsFieldEntry.getValue(), null)) );
}
).collect(Collectors.toList());
}
return Collections.emptyList();
}
protected List<GenericFacetResponse> getPivots(SearchRequestContext searchRequest, List<GenericFacetResponse> pivots,
List<GenericFacetResponse> stats)
{
if(pivots != null && !pivots.isEmpty())
{
@@ -386,11 +408,20 @@ public class ResultMapper
String pivotLabel = pivotKeys.containsKey(aFacet.getLabel())?pivotKeys.get(aFacet.getLabel()):aFacet.getLabel();
List<GenericBucket> bucks = aFacet.getBuckets().stream().map(genericBucket -> {
//can reference, facetfield, the last one can be rangefacet, facetquery or stats
List<GenericBucket> bucks = new ArrayList<>();
Optional<GenericFacetResponse> foundStat = stats.stream().filter(
aStat -> aStat.getLabel().equals(pivotLabel)).findFirst();
if (foundStat.isPresent())
{
bucks.add(foundStat.get().getBuckets().get(0));
stats.remove(foundStat.get());
}
bucks.addAll(aFacet.getBuckets().stream().map(genericBucket -> {
Object display = propertyLookup.lookup(aFacet.getLabel(), genericBucket.getLabel());
return new GenericBucket(genericBucket.getLabel(), genericBucket.getFilterQuery(),
display,genericBucket.getMetrics(), getPivots(searchRequest, genericBucket.getFacets()));
}).collect(Collectors.toList());
display,genericBucket.getMetrics(), getPivots(searchRequest, genericBucket.getFacets(), stats));
}).collect(Collectors.toList()));
return new GenericFacetResponse(aFacet.getType(), pivotLabel, bucks);
}).collect(Collectors.toList());
@@ -476,7 +507,7 @@ public class ResultMapper
}
}
}
GenericBucket bucket = new GenericBucket(buck.getFirst(), filterQuery, null , Arrays.asList(new MetricCount(buck.getSecond())), null);
GenericBucket bucket = new GenericBucket(buck.getFirst(), filterQuery, null , Arrays.asList(new SimpleMetric(METRIC_TYPE.count,String.valueOf(buck.getSecond()))), null);
buckets.add(bucket);
}
ffcs.add(new GenericFacetResponse(FACET_TYPE.interval, facet.getKey(), buckets));

View File

@@ -58,6 +58,7 @@ import org.alfresco.service.cmr.search.SearchParameters.FieldFacetSort;
import org.alfresco.service.cmr.search.SearchParameters.Operator;
import org.alfresco.service.cmr.search.SearchParameters.SortDefinition;
import org.alfresco.service.cmr.search.SearchParameters.SortDefinition.SortType;
import org.alfresco.service.cmr.search.StatsRequestParameters;
import org.alfresco.util.ParameterCheck;
import static org.alfresco.rest.api.Nodes.PARAM_INCLUDE_ALLOWABLEOPERATIONS;
@@ -70,6 +71,7 @@ import static org.alfresco.service.cmr.search.SearchService.*;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
import java.util.Optional;
import java.util.regex.Matcher;
@@ -110,7 +112,8 @@ public class SearchMapper
fromDefault(sp, searchQuery.getDefaults());
fromFilterQuery(sp, searchQuery.getFilterQueries());
fromFacetQuery(sp, searchQuery.getFacetQueries());
fromPivot(sp, searchQuery.getFacetFields(), searchQuery.getPivots(), searchRequestContext);
fromPivot(sp, searchQuery.getStats(), searchQuery.getFacetFields(), searchQuery.getPivots(), searchRequestContext);
fromStats(sp, searchQuery.getStats());
fromFacetFields(sp, searchQuery.getFacetFields());
fromSpellCheck(sp, searchQuery.getSpellcheck());
fromHighlight(sp, searchQuery.getHighlight());
@@ -508,19 +511,21 @@ public class SearchMapper
sp.setInterval(facetIntervals);
}
public void fromPivot(SearchParameters sp, FacetFields facetFields, List<Pivot> pivots, SearchRequestContext searchRequestContext)
public void fromPivot(SearchParameters sp, List<StatsRequestParameters> stats, FacetFields facetFields, List<Pivot> pivots, SearchRequestContext searchRequestContext)
{
if (facetFields != null && pivots != null && !pivots.isEmpty())
{
ParameterCheck.mandatory("facetFields facets", facetFields.getFacets());
if (facetFields.getFacets() != null && !facetFields.getFacets().isEmpty())
{
for (Pivot pivot:pivots)
{
ParameterCheck.mandatoryString("pivot key", pivot.getKey());
ListIterator<Pivot> piterator = pivots.listIterator();
String pivotKey = pivot.getKey();
while (piterator.hasNext()) {
Pivot pivot = piterator.next();
ParameterCheck.mandatoryString("pivot key", pivot.getKey());
String pivotKey = pivot.getKey();
if (facetFields.getFacets() != null && !facetFields.getFacets().isEmpty())
{
Optional<FacetField> found = facetFields.getFacets().stream().filter(
queryable -> pivotKey.equals(queryable.getLabel()!=null?queryable.getLabel():queryable.getField())).findFirst();
@@ -532,14 +537,63 @@ public class SearchMapper
}
else
{
throw new InvalidArgumentException(InvalidArgumentException.DEFAULT_MESSAGE_ID,
new Object[] { ": Pivot parameter "+pivotKey+" is does not reference a facet Field." });
if (piterator.hasNext())
{
//Its not the last one so lets complain
throw new InvalidArgumentException(InvalidArgumentException.DEFAULT_MESSAGE_ID,
new Object[] { ": Pivot parameter " + pivotKey + " is does not reference a facet Field." });
}
else
{
//It is the last one so it can reference facetquery or stats
/**
Optional<StatsRequestParameters> foundStat = stats.stream().filter(stas -> pivotKey.equals(stas.getLabel())).findFirst();
if (foundStat.isPresent())
{
stats.remove(foundStat.get());
}
**/
sp.addPivot(pivotKey);
searchRequestContext.getPivotKeys().put(pivotKey, pivotKey);
}
}
}
}
}
}
public void fromStats(SearchParameters sp, List<StatsRequestParameters> stats)
{
if (stats != null && !stats.isEmpty())
{
for (StatsRequestParameters aStat:stats)
{
ParameterCheck.mandatory("stats field", aStat.getField());
List<Float> perc = aStat.getPercentiles();
if (perc != null && !perc.isEmpty())
{
for (Float percentile:perc)
{
if (percentile == null || percentile < 0 || percentile > 100)
{
throw new IllegalArgumentException("Invalid percentile "+percentile);
}
}
}
if (aStat.getCardinality() && (aStat.getCardinalityAccuracy() < 0 || aStat.getCardinalityAccuracy() > 1))
{
throw new IllegalArgumentException("Invalid cardinality accuracy "+aStat.getCardinalityAccuracy() + " It must be between 0 and 1.");
}
}
sp.setStats(stats);
}
}
protected void validateSets(List<IntervalSet> intervalSets, String prefix)
{
if (intervalSets != null && !intervalSets.isEmpty())

View File

@@ -29,6 +29,7 @@ package org.alfresco.rest.api.search.model;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.service.cmr.search.GeneralHighlightParameters;
import org.alfresco.service.cmr.search.IntervalParameters;
import org.alfresco.service.cmr.search.StatsRequestParameters;
import org.codehaus.jackson.annotate.JsonCreator;
import org.codehaus.jackson.annotate.JsonProperty;
@@ -58,8 +59,10 @@ public class SearchQuery
private final IntervalParameters facetIntervals;
private final boolean includeRequest;
private final List<Pivot> pivots;
private final List<StatsRequestParameters> stats;
public static final SearchQuery EMPTY = new SearchQuery(null, null, null, null, null, null,null, null, null, null,null, null, null, null, null, null, null);
public static final SearchQuery EMPTY = new SearchQuery(null, null, null, null, null, null,
null,null, null, null, null,null, null, null, null, null, null, null);
@JsonCreator
public SearchQuery(@JsonProperty("query") Query query,
@@ -78,7 +81,8 @@ public class SearchQuery
@JsonProperty("limits")Limits limits,
@JsonProperty("highlight")GeneralHighlightParameters highlight,
@JsonProperty("facetIntervals")IntervalParameters facetIntervals,
@JsonProperty("pivots") List<Pivot> pivots)
@JsonProperty("pivots") List<Pivot> pivots,
@JsonProperty("stats") List<StatsRequestParameters> stats)
{
this.query = query;
this.includeRequest = includeRequest==null?false:includeRequest;
@@ -97,6 +101,7 @@ public class SearchQuery
this.highlight = highlight;
this.facetIntervals = facetIntervals;
this.pivots = pivots;
this.stats = stats;
}
public Query getQuery()
@@ -182,4 +187,9 @@ public class SearchQuery
{
return pivots;
}
public List<StatsRequestParameters> getStats()
{
return stats;
}
}