use of org.alfresco.service.cmr.search.SearchParameters in project alfresco-remote-api by Alfresco.
the class SearchMapperTests method fromSort.
@Test
public void fromSort() throws Exception {
SearchParameters searchParameters = new SearchParameters();
// Doesn't error
searchMapper.fromSort(searchParameters, null);
try {
searchMapper.fromSort(searchParameters, Arrays.asList(new SortDef("wrongenum", null, false)));
fail();
} catch (InvalidArgumentException iae) {
// wrongenum is illegal
assertNotNull(iae);
}
searchMapper.fromSort(searchParameters, Arrays.asList(new SortDef("FIELD", "my", true), new SortDef("SCORE", null, false), new SortDef("DOCUMENT", null, true)));
assertEquals(3, searchParameters.getSortDefinitions().size());
searchParameters.getSortDefinitions().forEach(sortDefinition -> {
switch(sortDefinition.getSortType()) {
case FIELD:
assertEquals("my", sortDefinition.getField());
assertEquals(true, sortDefinition.isAscending());
break;
case SCORE:
assertNull(sortDefinition.getField());
assertEquals(false, sortDefinition.isAscending());
break;
case DOCUMENT:
assertNull(sortDefinition.getField());
assertEquals(true, sortDefinition.isAscending());
break;
default:
fail("Invalid sortDefinition");
}
});
searchParameters = new SearchParameters();
searchParameters.setLanguage(SearchService.LANGUAGE_CMIS_ALFRESCO);
try {
searchMapper.fromSort(searchParameters, Arrays.asList(new SortDef("FIELD", null, false)));
fail();
} catch (InvalidArgumentException iae) {
// You can't specify SORT when using the CMIS language
assertNotNull(iae);
}
}
use of org.alfresco.service.cmr.search.SearchParameters in project alfresco-remote-api by Alfresco.
the class SearchMapperTests method fromFacetFields.
@Test
public void fromFacetFields() throws Exception {
SearchParameters searchParameters = new SearchParameters();
// Doesn't error
searchMapper.fromFacetFields(searchParameters, null);
try {
searchMapper.fromFacetFields(searchParameters, new FacetFields(null));
fail();
} catch (IllegalArgumentException iae) {
assertTrue(iae.getLocalizedMessage().contains("facetFields facets is a mandatory parameter"));
}
try {
searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField(null, null, null, null, null, null, null, null, null, null, null))));
fail();
} catch (IllegalArgumentException iae) {
assertTrue(iae.getLocalizedMessage().contains("facetFields facet field is a mandatory parameter"));
}
searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield", null, null, null, null, null, null, null, null, null, null))));
assertEquals(1, searchParameters.getFieldFacets().size());
FieldFacet ff = searchParameters.getFieldFacets().get(0);
// Check defaults
// assertEquals(true, ff.getMissing());
assertNull(ff.getLimitOrNull());
assertEquals(0, ff.getOffset());
assertEquals(1, ff.getMinCount());
assertFalse(ff.isCountDocsMissingFacetField());
assertEquals(0, ff.getEnumMethodCacheMinDF());
// assertEquals("{key='myfield'}myfield" ,ff.getField());
searchParameters = new SearchParameters();
searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield", "mylabel", "myprefix", null, null, null, null, null, null, null, null))));
ff = searchParameters.getFieldFacets().get(0);
// assertEquals("{key='mylabel'}myfield" ,ff.getField());
assertEquals("myprefix", ff.getPrefix());
try {
searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield", null, null, "badsort", null, null, null, null, null, null, null))));
fail();
} catch (InvalidArgumentException iae) {
// Sort is an enum
assertNotNull(iae);
}
try {
searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield", null, null, null, "badmethod", null, null, null, null, null, null))));
fail();
} catch (InvalidArgumentException iae) {
// Method is an enum
assertNotNull(iae);
}
searchParameters = new SearchParameters();
searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield", null, null, "INDEX", "ENUM", null, null, null, null, null, null))));
ff = searchParameters.getFieldFacets().get(0);
assertEquals("INDEX", ff.getSort().toString());
assertEquals("ENUM", ff.getMethod().toString());
}
use of org.alfresco.service.cmr.search.SearchParameters in project alfresco-remote-api by Alfresco.
the class ResultMapperTests method testToSearchContext.
@Test
public void testToSearchContext() throws Exception {
ResultSet results = mockResultset(Collections.emptyList(), Collections.emptyList());
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);
assertEquals(34l, searchContext.getConsistency().getlastTxId());
assertEquals(6, searchContext.getFacetQueries().size());
assertEquals(0, searchContext.getFacetQueries().get(0).getCount());
assertEquals("cm:created:bob", searchContext.getFacetQueries().get(0).getFilterQuery());
assertEquals("small", searchContext.getFacetQueries().get(0).getLabel());
assertEquals("searchInsteadFor", searchContext.getSpellCheck().getType());
assertEquals(1, searchContext.getSpellCheck().getSuggestions().size());
assertEquals("alfresco", searchContext.getSpellCheck().getSuggestions().get(0));
assertEquals(1, searchContext.getFacetsFields().size());
assertEquals("content.size", searchContext.getFacetsFields().get(0).getLabel());
// Facet intervals
List<GenericFacetResponse> intervalFacets = searchContext.getFacets().stream().filter(f -> f.getType().equals(FACET_TYPE.interval)).collect(Collectors.toList());
assertEquals(2, intervalFacets.size());
assertEquals("creator", intervalFacets.get(0).getLabel());
assertEquals("last", intervalFacets.get(0).getBuckets().get(0).getLabel());
assertEquals("cm:creator:<\"a\" TO \"b\"]", intervalFacets.get(0).getBuckets().get(0).getFilterQuery());
Metric[] metrics = intervalFacets.get(0).getBuckets().get(0).getMetrics().toArray(new Metric[intervalFacets.get(0).getBuckets().get(0).getMetrics().size()]);
assertEquals(METRIC_TYPE.count, metrics[0].getType());
assertEquals("4", metrics[0].getValue().get("count"));
// Requests search Query
assertNotNull(searchContext.getRequest());
assertEquals("great", searchContext.getRequest().getQuery().getUserQuery());
// Pivot
assertEquals(7, searchContext.getFacets().size());
GenericFacetResponse pivotFacet = searchContext.getFacets().get(4);
assertEquals(FACET_TYPE.pivot, pivotFacet.getType());
assertEquals("creator", pivotFacet.getLabel());
assertEquals(2, pivotFacet.getBuckets().size());
GenericBucket pivotBucket = pivotFacet.getBuckets().get(1);
assertEquals("mjackson", pivotBucket.getLabel());
assertEquals("creator:\"mjackson\"", pivotBucket.getFilterQuery());
metrics = pivotBucket.getMetrics().toArray(new Metric[pivotBucket.getMetrics().size()]);
assertEquals("{count=7}", metrics[0].getValue().toString());
assertEquals(1, pivotBucket.getFacets().size());
GenericFacetResponse nestedFacet = pivotBucket.getFacets().get(0);
assertEquals(FACET_TYPE.pivot, nestedFacet.getType());
assertEquals("mylabel", nestedFacet.getLabel());
assertEquals(2, nestedFacet.getBuckets().size());
GenericBucket nestedBucket = nestedFacet.getBuckets().get(0);
assertEquals("mjackson", nestedBucket.getLabel());
assertEquals("modifier:\"mjackson\"", nestedBucket.getFilterQuery());
metrics = nestedBucket.getMetrics().toArray(new Metric[nestedBucket.getMetrics().size()]);
assertEquals("{count=3}", metrics[0].getValue().toString());
GenericBucket nestedBucket2 = nestedFacet.getBuckets().get(1);
assertEquals("admin", nestedBucket2.getLabel());
assertEquals("modifier:\"admin\"", nestedBucket2.getFilterQuery());
metrics = nestedBucket2.getMetrics().toArray(new Metric[nestedBucket2.getMetrics().size()]);
assertEquals("{count=4}", metrics[0].getValue().toString());
// Stats
GenericFacetResponse statsFacet = searchContext.getFacets().get(5);
assertEquals(FACET_TYPE.stats, statsFacet.getType());
assertEquals("created", statsFacet.getLabel());
Set<Metric> statsMetrics = statsFacet.getBuckets().get(0).getMetrics();
assertEquals(8, statsMetrics.size());
assertTrue(statsMetrics.contains(new SimpleMetric(METRIC_TYPE.sumOfSquares, 2.1513045770343806E27)));
assertTrue(statsMetrics.contains(new SimpleMetric(METRIC_TYPE.min, "2011-02-15T20:16:27.080Z")));
assertTrue(statsMetrics.contains(new SimpleMetric(METRIC_TYPE.max, "2017-04-10T15:06:30.143Z")));
assertTrue(statsMetrics.contains(new SimpleMetric(METRIC_TYPE.mean, "2016-09-05T04:20:12.898Z")));
assertTrue(statsMetrics.contains(new SimpleMetric(METRIC_TYPE.countValues, 990)));
assertTrue(statsMetrics.contains(new SimpleMetric(METRIC_TYPE.missing, 290)));
assertTrue(statsMetrics.contains(new SimpleMetric(METRIC_TYPE.sum, 1.458318720769983E15)));
assertTrue(statsMetrics.contains(new SimpleMetric(METRIC_TYPE.stddev, 5.6250677994522545E10)));
statsFacet = searchContext.getFacets().get(6);
assertEquals("numericLabel", statsFacet.getLabel());
statsMetrics = statsFacet.getBuckets().get(0).getMetrics();
assertEquals(7, statsMetrics.size());
assertTrue(statsMetrics.contains(new SimpleMetric(METRIC_TYPE.sumOfSquares, 0)));
assertTrue(statsMetrics.contains(new SimpleMetric(METRIC_TYPE.countValues, 0)));
assertTrue(statsMetrics.contains(new SimpleMetric(METRIC_TYPE.missing, 0)));
assertTrue(statsMetrics.contains(new SimpleMetric(METRIC_TYPE.sum, 0)));
assertTrue(statsMetrics.contains(new SimpleMetric(METRIC_TYPE.stddev, 0)));
JSONArray dVals = new JSONArray(Arrays.asList(12, 13, 14, 15, 16, 17, 1));
assertTrue(statsMetrics.contains(new ListMetric(METRIC_TYPE.distinctValues, dVals)));
JSONArray pers = new JSONArray(Arrays.asList("0.99", 20.0685, "0.0", 12.0));
assertTrue(statsMetrics.contains(new PercentileMetric(METRIC_TYPE.percentiles, pers)));
assertEquals("min must be excluded because its null", 0, statsMetrics.stream().filter(metric -> METRIC_TYPE.min.equals(metric.getType())).count());
assertEquals("max must be excluded because its null", 0, statsMetrics.stream().filter(metric -> METRIC_TYPE.max.equals(metric.getType())).count());
assertEquals("mean must be excluded because its NaN", 0, statsMetrics.stream().filter(metric -> METRIC_TYPE.mean.equals(metric.getType())).count());
}
use of org.alfresco.service.cmr.search.SearchParameters in project alfresco-repository by Alfresco.
the class People method getPeopleImplSearch.
// search query
protected List<NodeRef> getPeopleImplSearch(String term, String[] tokens, ScriptPagingDetails pagingRequest, String sortBy, Boolean sortAsc) throws Throwable {
List<NodeRef> personRefs = null;
Long start = (logger.isDebugEnabled() ? System.currentTimeMillis() : null);
int propIndex = term.indexOf(':');
int maxResults = pagingRequest.getMaxItems();
int skipCount = pagingRequest.getSkipCount();
SearchParameters params = new SearchParameters();
params.addQueryTemplate("_PERSON", "|%firstName OR |%lastName OR |%userName");
params.setDefaultFieldName("_PERSON");
params.setExcludeTenantFilter(getExcludeTenantFilter());
params.setPermissionEvaluation(getPermissionEvaluationMode());
StringBuilder query = new StringBuilder(256);
query.append("TYPE:\"").append(ContentModel.TYPE_PERSON).append("\" AND (");
if (tokens.length == 1) {
// single word with no field will go against _PERSON and expand
// fts-alfresco property search i.e. location:"maidenhead"
query.append(term.substring(0, propIndex + 1)).append('"');
if (propIndex < 0) {
query.append('*');
}
query.append(term.substring(propIndex + 1));
if (propIndex > 0) {
query.append('"');
} else {
query.append("*\"");
}
} else {
// scan for non-fts-alfresco property search tokens
int nonFtsTokens = 0;
for (String token : tokens) {
if (token.indexOf(':') == -1)
nonFtsTokens++;
}
tokens = term.split("(?<!\\\\) ");
// multiple terms supplied - look for first and second name etc.
// also allow fts-alfresco property search to reduce results
params.setDefaultOperator(SearchParameters.Operator.AND);
boolean propertySearch = false;
StringBuilder multiPartNames = new StringBuilder(tokens.length);
boolean firstToken = true;
for (String token : tokens) {
if (!propertySearch && token.indexOf(':') == -1) {
if (nonFtsTokens == 1) {
// simple search: first name, last name and username
// starting with term
query.append("_PERSON:\"*");
query.append(token);
query.append("*\" ");
} else {
// firstName and lastName
if (token.endsWith("*")) {
token = token.substring(0, token.lastIndexOf("*"));
}
multiPartNames.append("\"*");
multiPartNames.append(token);
multiPartNames.append("*\"");
if (firstToken) {
multiPartNames.append(' ');
}
firstToken = false;
}
} else {
// fts-alfresco property search i.e. "location:maidenhead"
propIndex = token.lastIndexOf(':');
query.append(token.substring(0, propIndex + 1)).append('"').append(token.substring(propIndex + 1)).append('"').append(' ');
propertySearch = true;
}
}
// name and "lewis martinez" is the last name.
if (multiPartNames.length() > 0) {
query.append("firstName:");
query.append(multiPartNames);
query.append(" OR lastName:");
query.append(multiPartNames);
}
}
query.append(")");
// define the search parameters
params.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO);
params.addStore(this.storeRef);
params.setQuery(query.toString());
if (logger.isDebugEnabled()) {
if ((sortBy != null) && (!sortBy.isEmpty())) {
logger.debug("getPeopleImplSearch: ignoring sortBy (" + sortBy + ")- not yet supported by model for search");
}
}
if (maxResults > 0) {
params.setLimitBy(LimitBy.FINAL_SIZE);
params.setLimit(maxResults);
}
if (skipCount > 0) {
params.setSkipCount(skipCount);
}
ResultSet results = null;
try {
results = services.getSearchService().query(params);
personRefs = getSortedPeopleObjects(results.getNodeRefs(), sortBy, sortAsc);
if (start != null) {
logger.debug("getPeople: search - " + personRefs.size() + " items (in " + (System.currentTimeMillis() - start) + " msecs)");
}
} catch (Throwable err) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to execute people search: " + query.toString(), err);
}
throw err;
} finally {
if (results != null) {
results.close();
}
}
return personRefs;
}
use of org.alfresco.service.cmr.search.SearchParameters in project alfresco-repository by Alfresco.
the class Search method queryResultSet.
@SuppressWarnings("unchecked")
public Scriptable queryResultSet(Object search) {
Object[] results = null;
Map<String, Object> meta = null;
// convert values from JS to Java - may contain native JS object such as ConsString etc.
search = new ValueConverter().convertValueForJava(search);
if (search instanceof Serializable) {
Serializable obj = new ValueConverter().convertValueForRepo((Serializable) search);
if (obj instanceof Map) {
Map<Serializable, Serializable> def = (Map<Serializable, Serializable>) obj;
// test for mandatory values
String query = (String) def.get("query");
if (query == null || query.length() == 0) {
throw new AlfrescoRuntimeException("Failed to search: Missing mandatory 'query' value.");
}
// collect optional values
String store = (String) def.get("store");
String language = (String) def.get("language");
List<Map<Serializable, Serializable>> sort = (List<Map<Serializable, Serializable>>) def.get("sort");
Map<Serializable, Serializable> page = (Map<Serializable, Serializable>) def.get("page");
List<String> facets = (List<String>) def.get("fieldFacets");
List<String> filterQueries = (List<String>) def.get("filterQueries");
String namespace = (String) def.get("namespace");
String onerror = (String) def.get("onerror");
String defaultField = (String) def.get("defaultField");
String defaultOperator = (String) def.get("defaultOperator");
String searchTerm = (String) def.get("searchTerm");
boolean spellCheck = Boolean.TRUE.equals(def.get("spellCheck"));
// extract supplied values
// sorting columns
SortColumn[] sortColumns = null;
if (sort != null) {
sortColumns = new SortColumn[sort.size()];
int index = 0;
for (Map<Serializable, Serializable> column : sort) {
String strCol = (String) column.get("column");
if (strCol == null || strCol.length() == 0) {
throw new AlfrescoRuntimeException("Failed to search: Missing mandatory 'sort: column' value.");
}
Boolean boolAsc = (Boolean) column.get("ascending");
boolean ascending = (boolAsc != null ? boolAsc.booleanValue() : false);
sortColumns[index++] = new SortColumn(strCol, ascending);
}
}
// paging settings
int maxResults = -1;
int skipResults = 0;
if (page != null) {
if (page.get("maxItems") != null) {
Object maxItems = page.get("maxItems");
if (maxItems instanceof Number) {
maxResults = ((Number) maxItems).intValue();
} else if (maxItems instanceof String) {
// try and convert to int (which it what it should be!)
maxResults = Integer.parseInt((String) maxItems);
}
}
if (page.get("skipCount") != null) {
Object skipCount = page.get("skipCount");
if (skipCount instanceof Number) {
skipResults = ((Number) page.get("skipCount")).intValue();
} else if (skipCount instanceof String) {
skipResults = Integer.parseInt((String) skipCount);
}
}
}
// query templates
Map<String, String> queryTemplates = null;
List<Map<Serializable, Serializable>> templates = (List<Map<Serializable, Serializable>>) def.get("templates");
if (templates != null) {
queryTemplates = new HashMap<String, String>(templates.size(), 1.0f);
for (Map<Serializable, Serializable> template : templates) {
String field = (String) template.get("field");
if (field == null || field.length() == 0) {
throw new AlfrescoRuntimeException("Failed to search: Missing mandatory 'template: field' value.");
}
String t = (String) template.get("template");
if (t == null || t.length() == 0) {
throw new AlfrescoRuntimeException("Failed to search: Missing mandatory 'template: template' value.");
}
queryTemplates.put(field, t);
}
}
SearchParameters sp = new SearchParameters();
sp.addStore(store != null ? new StoreRef(store) : this.storeRef);
sp.setLanguage(language != null ? language : SearchService.LANGUAGE_LUCENE);
sp.setQuery(query);
sp.setSearchTerm(searchTerm);
sp.setSpellCheck(spellCheck);
if (defaultField != null) {
sp.setDefaultFieldName(defaultField);
}
if (defaultOperator != null && defaultOperator.length() != 0) {
try {
sp.setDefaultOperator(Operator.valueOf(defaultOperator.toUpperCase()));
} catch (IllegalArgumentException e) {
// ignore invalid Operator and the default value will be used
}
}
if (namespace != null) {
sp.setNamespace(namespace);
}
if (maxResults > 0) {
sp.setLimit(maxResults);
sp.setLimitBy(LimitBy.FINAL_SIZE);
}
if (skipResults > 0) {
sp.setSkipCount(skipResults);
}
if (sort != null) {
for (SortColumn sd : sortColumns) {
sp.addSort(sd.column, sd.asc);
}
}
if (queryTemplates != null) {
for (String field : queryTemplates.keySet()) {
sp.addQueryTemplate(field, queryTemplates.get(field));
}
}
if (facets != null) {
SolrFacetHelper solrFacetHelper = services.getSolrFacetHelper();
for (String field : facets) {
if (field.isEmpty()) {
continue;
}
final String modifiedField = "@" + field;
if (solrFacetHelper.hasFacetQueries(modifiedField)) {
List<String> facetQueries = solrFacetHelper.getFacetQueries(modifiedField);
addFacetQuery(sp, field, facetQueries, query);
} else {
final FieldFacet fieldFacet;
if (solrFacetHelper.isSpecialFacetId(field)) {
fieldFacet = new FieldFacet(field);
} else {
fieldFacet = new FieldFacet(modifiedField);
}
sp.addFieldFacet(fieldFacet);
}
}
}
if (filterQueries != null) {
for (String filter : filterQueries) {
sp.addFilterQuery(filter);
}
}
Map<Serializable, Serializable> highlighting = (Map<Serializable, Serializable>) def.get("highlight");
if (highlighting != null) {
int snippetCount = this.getIntegerValue("snippetCount", 20, highlighting);
int fragmentSize = this.getIntegerValue("fragmentSize", 50, highlighting);
// see SEARCH-284
Integer maxAnalyzedChars = null;
boolean usePhraseHighlighter = this.getBooleanValue("usePhraseHighlighter", true, highlighting);
boolean mergeContiguous = this.getBooleanValue("mergeContiguous", true, highlighting);
String prefix = (String) highlighting.get("prefix");
if (prefix == null) {
prefix = "<mark>";
}
String postfix = (String) highlighting.get("postfix");
if (postfix == null) {
postfix = "</mark>";
}
List<FieldHighlightParameters> fieldHighlightParameters = new ArrayList<FieldHighlightParameters>();
List<Map<Serializable, Serializable>> fields = (List<Map<Serializable, Serializable>>) highlighting.get("fields");
if (fields != null) {
for (Map<Serializable, Serializable> field : fields) {
String propertyName = (String) field.get("field");
if (propertyName != null) {
fieldHighlightParameters.add(new FieldHighlightParameters(propertyName, snippetCount, fragmentSize, mergeContiguous, prefix, postfix));
}
}
}
GeneralHighlightParameters ghp = new GeneralHighlightParameters(snippetCount, fragmentSize, mergeContiguous, prefix, postfix, maxAnalyzedChars, usePhraseHighlighter, fieldHighlightParameters);
sp.setHighlight(ghp);
}
// error handling opions
boolean exceptionOnError = true;
if (onerror != null) {
if (onerror.equals("exception")) {
// default value, do nothing
} else if (onerror.equals("no-results")) {
exceptionOnError = false;
} else {
throw new AlfrescoRuntimeException("Failed to search: Unknown value supplied for 'onerror': " + onerror);
}
}
// execute search based on search definition
Pair<Object[], Map<String, Object>> r = queryResultMeta(sp, exceptionOnError);
results = r.getFirst();
meta = r.getSecond();
}
}
if (results == null) {
results = new Object[0];
}
// construct a JS return object
// {
// nodes: [], // Array of ScriptNode results
// meta: {
// numberFound: long, // total number found in index, or -1 if not known or not supported by this resultset
// facets: { // facets are returned for each field as requested in the SearchParameters fieldfacets
// field: { // each field contains a map of facet to value
// facet: value,
// ...
// },
// ...
// }
// }
// }
Scriptable scope = getScope();
Scriptable res = Context.getCurrentContext().newObject(scope);
res.put("nodes", res, Context.getCurrentContext().newArray(scope, results));
res.put("meta", res, meta);
return res;
}
Aggregations