use of org.alfresco.service.cmr.search.ResultSet in project alfresco-repository by Alfresco.
the class DBQueryTest method testAftsPagination.
/**
* Test that when a query is performed with a limit parameter, the number of results in the resultset
* is influenced by limit while the numberOfFound value is not.
*/
@Test
public void testAftsPagination() {
String query = "=TYPE:\"cm:folder\" ";
// this value is equals to the numer of folders inserted in createTestData method.
int numFolders = 6;
int count = 4;
ResultSet results = query(SearchService.LANGUAGE_FTS_ALFRESCO, query, count);
assertEquals("The number of results should be equal to count", results.length(), count);
assertEquals("The number of founds should be equal to the number of folders, and not influenced" + "by the limit set to the query.", results.getNumberFound(), numFolders);
}
use of org.alfresco.service.cmr.search.ResultSet in project alfresco-repository by Alfresco.
the class SolrQueryHTTPClient method executeQuery.
public ResultSet executeQuery(final SearchParameters searchParameters, String language) {
if (repositoryState.isBootstrapping()) {
throw new AlfrescoRuntimeException("SOLR queries can not be executed while the repository is bootstrapping");
}
try {
StoreRef store = SolrClientUtil.extractStoreRef(searchParameters);
SolrStoreMappingWrapper mapping = SolrClientUtil.extractMapping(store, mappingLookup, shardRegistry, useDynamicShardRegistration, beanFactory);
Pair<HttpClient, String> httpClientAndBaseUrl = mapping.getHttpClientAndBaseUrl();
HttpClient httpClient = httpClientAndBaseUrl.getFirst();
URLCodec encoder = new URLCodec();
StringBuilder url = new StringBuilder();
url.append(httpClientAndBaseUrl.getSecond());
String languageUrlFragment = SolrClientUtil.extractLanguageFragment(languageMappings, language);
if (!url.toString().endsWith("/")) {
url.append("/");
}
url.append(languageUrlFragment);
// Send the query in JSON only
// url.append("?q=");
// url.append(encoder.encode(searchParameters.getQuery(), "UTF-8"));
url.append("?wt=").append(encoder.encode("json", "UTF-8"));
url.append("&fl=").append(encoder.encode("DBID,score", "UTF-8"));
// Emulate old limiting behaviour and metadata
final LimitBy limitBy;
int maxResults = -1;
if (searchParameters.getMaxItems() >= 0) {
maxResults = searchParameters.getMaxItems();
limitBy = LimitBy.FINAL_SIZE;
} else if (searchParameters.getLimitBy() == LimitBy.FINAL_SIZE && searchParameters.getLimit() >= 0) {
maxResults = searchParameters.getLimit();
limitBy = LimitBy.FINAL_SIZE;
} else {
maxResults = searchParameters.getMaxPermissionChecks();
if (maxResults < 0) {
maxResults = maximumResultsFromUnlimitedQuery;
}
limitBy = LimitBy.NUMBER_OF_PERMISSION_EVALUATIONS;
}
url.append("&rows=").append(String.valueOf(maxResults));
if ((searchParameters.getStores().size() > 1) || (mapping.isSharded())) {
boolean requiresSeparator = false;
url.append("&shards=");
for (StoreRef storeRef : searchParameters.getStores()) {
SolrStoreMappingWrapper storeMapping = SolrClientUtil.extractMapping(storeRef, mappingLookup, shardRegistry, useDynamicShardRegistration, beanFactory);
if (requiresSeparator) {
url.append(',');
} else {
requiresSeparator = true;
}
url.append(storeMapping.getShards());
}
}
buildUrlParameters(searchParameters, mapping.isSharded(), encoder, url);
final String searchTerm = searchParameters.getSearchTerm();
String spellCheckQueryStr = null;
if (searchTerm != null && searchParameters.isSpellCheck()) {
StringBuilder builder = new StringBuilder();
builder.append("&spellcheck.q=").append(encoder.encode(searchTerm, "UTF-8"));
builder.append("&spellcheck=").append(encoder.encode("true", "UTF-8"));
spellCheckQueryStr = builder.toString();
url.append(spellCheckQueryStr);
}
JSONObject body = new JSONObject();
body.put("query", searchParameters.getQuery());
// Authorities go over as is - and tenant mangling and query building takes place on the SOLR side
Set<String> allAuthorisations = permissionService.getAuthorisations();
boolean includeGroups = includeGroupsForRoleAdmin ? true : !allAuthorisations.contains(PermissionService.ADMINISTRATOR_AUTHORITY);
JSONArray authorities = new JSONArray();
for (String authority : allAuthorisations) {
if (includeGroups) {
authorities.put(authority);
} else {
if (AuthorityType.getAuthorityType(authority) != AuthorityType.GROUP) {
authorities.put(authority);
}
}
}
body.put("authorities", authorities);
body.put("anyDenyDenies", anyDenyDenies);
JSONArray tenants = new JSONArray();
tenants.put(tenantService.getCurrentUserDomain());
body.put("tenants", tenants);
JSONArray locales = new JSONArray();
for (Locale currentLocale : searchParameters.getLocales()) {
locales.put(DefaultTypeConverter.INSTANCE.convert(String.class, currentLocale));
}
if (locales.length() == 0) {
locales.put(I18NUtil.getLocale());
}
body.put("locales", locales);
JSONArray templates = new JSONArray();
for (String templateName : searchParameters.getQueryTemplates().keySet()) {
JSONObject template = new JSONObject();
template.put("name", templateName);
template.put("template", searchParameters.getQueryTemplates().get(templateName));
templates.put(template);
}
body.put("templates", templates);
JSONArray allAttributes = new JSONArray();
for (String attribute : searchParameters.getAllAttributes()) {
allAttributes.put(attribute);
}
body.put("allAttributes", allAttributes);
body.put("defaultFTSOperator", searchParameters.getDefaultFTSOperator());
body.put("defaultFTSFieldOperator", searchParameters.getDefaultFTSFieldOperator());
body.put("queryConsistency", searchParameters.getQueryConsistency());
if (searchParameters.getMlAnalaysisMode() != null) {
body.put("mlAnalaysisMode", searchParameters.getMlAnalaysisMode().toString());
}
body.put("defaultNamespace", searchParameters.getNamespace());
JSONArray textAttributes = new JSONArray();
for (String attribute : searchParameters.getTextAttributes()) {
textAttributes.put(attribute);
}
body.put("textAttributes", textAttributes);
// just needed for the final parameter
final int maximumResults = maxResults;
return (ResultSet) postSolrQuery(httpClient, url.toString(), body, json -> {
return new SolrJSONResultSet(json, searchParameters, nodeService, nodeDAO, limitBy, maximumResults);
}, spellCheckQueryStr);
} catch (UnsupportedEncodingException e) {
throw new LuceneQueryParserException("", e);
} catch (HttpException e) {
throw new LuceneQueryParserException("", e);
} catch (IOException e) {
throw new LuceneQueryParserException("", e);
} catch (JSONException e) {
throw new LuceneQueryParserException("", e);
}
}
use of org.alfresco.service.cmr.search.ResultSet in project alfresco-repository by Alfresco.
the class DbOrIndexSwitchingQueryLanguage method executeHybridQuery.
private ResultSet executeHybridQuery(SearchParameters searchParameters) {
if (indexQueryLanguage == null || dbQueryLanguage == null) {
throw new QueryModelException("Both index and DB query language required for hybrid search [index=" + indexQueryLanguage + ", DB=" + dbQueryLanguage + "]");
}
StopWatch stopWatch = new StopWatch("hybrid search");
if (logger.isDebugEnabled()) {
logger.debug("Hybrid search, using SOLR query: " + dbQueryLanguage.getName() + " for " + searchParameters);
}
stopWatch.start("index query");
ResultSet indexResults = indexQueryLanguage.executeQuery(searchParameters);
stopWatch.stop();
if (logger.isDebugEnabled()) {
logger.debug("SOLR query returned " + indexResults.length() + " results in " + stopWatch.getLastTaskTimeMillis() + "ms");
}
if (!(indexResults instanceof SolrJSONResultSet)) {
if (logger.isWarnEnabled()) {
logger.warn("Hybrid search can only use database when SOLR is also in use. " + "Skipping DB search, returning results from index.");
}
return indexResults;
}
long lastTxId = ((SolrJSONResultSet) indexResults).getLastIndexedTxId();
searchParameters.setSinceTxId(lastTxId);
if (logger.isDebugEnabled()) {
logger.debug("Hybrid search, using DB query: " + dbQueryLanguage.getName() + " for " + searchParameters);
}
stopWatch.start("database query");
ResultSet dbResults = dbQueryLanguage.executeQuery(searchParameters);
stopWatch.stop();
if (logger.isDebugEnabled()) {
logger.debug("DB query returned " + dbResults.length() + " results in " + stopWatch.getLastTaskTimeMillis() + "ms");
}
// Merge result sets
List<ChildAssociationRef> childAssocs = new ArrayList<>();
NodeParameters nodeParameters = new NodeParameters();
nodeParameters.setFromTxnId(lastTxId + 1);
// TODO: setToTxnId(null) when SolrDAO behaviour is fixed.
nodeParameters.setToTxnId(Long.MAX_VALUE);
stopWatch.start("get changed nodes");
List<Node> changedNodeList = solrDao.getNodes(nodeParameters, null, null);
stopWatch.stop();
if (logger.isDebugEnabled()) {
logger.debug("Nodes changed since last indexed transaction (ID " + lastTxId + ") = " + changedNodeList.size() + " (took " + stopWatch.getLastTaskTimeMillis() + "ms)");
}
stopWatch.start("merge result sets");
Set<NodeRef> nodeRefs = new HashSet<>(changedNodeList.size());
for (Node n : changedNodeList) {
nodeRefs.add(n.getNodeRef());
}
// Only use the SOLR results for nodes that haven't changed since indexing.
for (ChildAssociationRef car : indexResults.getChildAssocRefs()) {
if (!nodeRefs.contains(car.getChildRef())) {
childAssocs.add(car);
}
}
// Merge in all the database results.
childAssocs.addAll(dbResults.getChildAssocRefs());
ResultSet results = new ChildAssocRefResultSet(nodeService, childAssocs);
// merge result sets
stopWatch.stop();
if (logger.isDebugEnabled()) {
String stats = String.format("SOLR=%d, DB=%d, total=%d", indexResults.length(), dbResults.length(), results.length());
logger.debug("Hybrid search returning combined results with counts: " + stats);
logger.debug(stopWatch.prettyPrint());
}
return results;
}
use of org.alfresco.service.cmr.search.ResultSet in project alfresco-repository by Alfresco.
the class LuceneQueryEngine method executeQuery.
public QueryEngineResults executeQuery(Query query, QueryOptions options, FunctionEvaluationContext functionContext) {
Set<String> selectorGroup = null;
if (query.getSource() != null) {
List<Set<String>> selectorGroups = query.getSource().getSelectorGroups(functionContext);
if (selectorGroups.size() == 0) {
throw new UnsupportedOperationException("No selectors");
}
if (selectorGroups.size() > 1) {
throw new UnsupportedOperationException("Advanced join is not supported");
}
selectorGroup = selectorGroups.get(0);
}
SearchParameters searchParameters = new SearchParameters();
if (options.getLocales().size() > 0) {
for (Locale locale : options.getLocales()) {
searchParameters.addLocale(locale);
}
}
searchParameters.excludeDataInTheCurrentTransaction(!options.isIncludeInTransactionData());
searchParameters.setSkipCount(options.getSkipCount());
searchParameters.setMaxPermissionChecks(options.getMaxPermissionChecks());
searchParameters.setMaxPermissionCheckTimeMillis(options.getMaxPermissionCheckTimeMillis());
searchParameters.setDefaultFieldName(options.getDefaultFieldName());
searchParameters.setMlAnalaysisMode(options.getMlAnalaysisMode());
if (options.getMaxItems() >= 0) {
searchParameters.setLimitBy(LimitBy.FINAL_SIZE);
searchParameters.setLimit(options.getMaxItems());
searchParameters.setMaxItems(options.getMaxItems());
} else {
searchParameters.setLimitBy(LimitBy.UNLIMITED);
}
searchParameters.setUseInMemorySort(options.getUseInMemorySort());
searchParameters.setMaxRawResultSetSizeForInMemorySort(options.getMaxRawResultSetSizeForInMemorySort());
searchParameters.setBulkFetchEnabled(options.isBulkFetchEnabled());
searchParameters.setQueryConsistency(options.getQueryConsistency());
try {
StoreRef storeRef = options.getStores().get(0);
searchParameters.addStore(storeRef);
if (query instanceof LuceneQueryBuilder) {
SearchService searchService = indexAndSearcher.getSearcher(storeRef, options.isIncludeInTransactionData());
if (searchService instanceof LuceneSearcher) {
LuceneSearcher luceneSearcher = (LuceneSearcher) searchService;
ClosingIndexSearcher searcher = luceneSearcher.getClosingIndexSearcher();
LuceneQueryBuilderContext<org.apache.lucene.search.Query, Sort, ParseException> luceneContext = new LuceneQueryBuilderContextImpl(dictionaryService, namespaceService, tenantService, searchParameters, indexAndSearcher.getDefaultMLSearchAnalysisMode(), searcher.getIndexReader());
@SuppressWarnings("unchecked") LuceneQueryBuilder<org.apache.lucene.search.Query, Sort, ParseException> builder = (LuceneQueryBuilder<org.apache.lucene.search.Query, Sort, ParseException>) query;
org.apache.lucene.search.Query luceneQuery = builder.buildQuery(selectorGroup, luceneContext, functionContext);
if (logger.isDebugEnabled()) {
logger.debug("Executing lucene query: " + luceneQuery);
}
Sort sort = builder.buildSort(selectorGroup, luceneContext, functionContext);
Hits hits = searcher.search(luceneQuery);
boolean postSort = false;
;
if (sort != null) {
postSort = searchParameters.usePostSort(hits.length(), useInMemorySort, maxRawResultSetSizeForInMemorySort);
if (postSort == false) {
hits = searcher.search(luceneQuery, sort);
}
}
ResultSet answer;
ResultSet result = new LuceneResultSet(hits, searcher, nodeService, tenantService, searchParameters, indexAndSearcher);
if (postSort) {
if (sort != null) {
for (SortField sf : sort.getSort()) {
searchParameters.addSort(sf.getField(), !sf.getReverse());
}
}
ResultSet sorted = new SortedResultSet(result, nodeService, builder.buildSortDefinitions(selectorGroup, luceneContext, functionContext), namespaceService, dictionaryService, searchParameters.getSortLocale());
answer = sorted;
} else {
answer = result;
}
ResultSet rs = new PagingLuceneResultSet(answer, searchParameters, nodeService);
Map<Set<String>, ResultSet> map = new HashMap<Set<String>, ResultSet>(1);
map.put(selectorGroup, rs);
return new QueryEngineResults(map);
} else {
throw new UnsupportedOperationException();
}
} else {
throw new UnsupportedOperationException();
}
} catch (ParseException e) {
throw new SearcherException("Failed to parse query: " + e);
} catch (IOException e) {
throw new SearcherException("IO exception during search", e);
}
}
use of org.alfresco.service.cmr.search.ResultSet in project alfresco-repository by Alfresco.
the class SolrCategoryServiceImpl method getTopCategories.
@Override
public List<Pair<NodeRef, Integer>> getTopCategories(StoreRef storeRef, QName aspectName, int count) {
AspectDefinition definition = dictionaryService.getAspect(aspectName);
if (definition == null) {
throw new IllegalStateException("Unknown aspect");
}
QName catProperty = null;
Map<QName, PropertyDefinition> properties = definition.getProperties();
for (QName pName : properties.keySet()) {
if (pName.getNamespaceURI().equals(aspectName.getNamespaceURI())) {
if (pName.getLocalName().equalsIgnoreCase(aspectName.getLocalName())) {
PropertyDefinition def = properties.get(pName);
if (def.getDataType().getName().equals(DataTypeDefinition.CATEGORY)) {
catProperty = pName;
}
}
}
}
if (catProperty == null) {
throw new IllegalStateException("Aspect does not have category property mirroring the aspect name");
}
String field = "@" + catProperty;
SearchParameters sp = new SearchParameters();
sp.setLanguage(SearchService.LANGUAGE_SOLR_FTS_ALFRESCO);
sp.addStore(storeRef);
sp.setQuery(catProperty + ":*");
FieldFacet ff = new FieldFacet(field);
ff.setLimitOrNull(count);
sp.addFieldFacet(ff);
ResultSet resultSet = null;
try {
resultSet = indexerAndSearcher.getSearcher(storeRef, false).query(sp);
List<Pair<String, Integer>> facetCounts = resultSet.getFieldFacet(field);
List<Pair<NodeRef, Integer>> answer = new LinkedList<Pair<NodeRef, Integer>>();
for (Pair<String, Integer> term : facetCounts) {
Pair<NodeRef, Integer> toAdd;
NodeRef nodeRef = new NodeRef(term.getFirst());
if (nodeService.exists(nodeRef)) {
toAdd = new Pair<NodeRef, Integer>(nodeRef, term.getSecond());
} else {
toAdd = new Pair<NodeRef, Integer>(null, term.getSecond());
}
answer.add(toAdd);
}
return answer;
} finally {
if (resultSet != null) {
resultSet.close();
}
}
}
Aggregations