use of org.alfresco.repo.search.impl.querymodel.QueryModelException 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.repo.search.impl.querymodel.QueryModelException in project alfresco-repository by Alfresco.
the class DBQuery method matchTypeDefinition.
public static TypeDefinition matchTypeDefinition(String string, NamespacePrefixResolver namespacePrefixResolver, DictionaryService dictionaryService) {
QName search = QName.createQName(expandQName(string, namespacePrefixResolver));
TypeDefinition typeDefinition = dictionaryService.getType(search);
QName match = null;
if (typeDefinition == null) {
for (QName definition : dictionaryService.getAllTypes()) {
if (definition.getNamespaceURI().equalsIgnoreCase(search.getNamespaceURI())) {
if (definition.getLocalName().equalsIgnoreCase(search.getLocalName())) {
if (match == null) {
match = definition;
} else {
throw new QueryModelException("Ambiguous data datype " + string);
}
}
}
}
} else {
return typeDefinition;
}
if (match == null) {
return null;
} else {
return dictionaryService.getType(match);
}
}
use of org.alfresco.repo.search.impl.querymodel.QueryModelException in project alfresco-repository by Alfresco.
the class DBQuery method findAspectIds.
public static List<Long> findAspectIds(String aspect, NamespaceService namespaceService, DictionaryService dictionaryService, QNameDAO qnameDAO, boolean exact) {
ArrayList<Long> qnameIds = new ArrayList<Long>();
AspectDefinition target = matchAspectDefinition(aspect, namespaceService, dictionaryService);
if (target == null) {
throw new QueryModelException("Invalid aspect: " + aspect);
}
if (exact) {
Pair<Long, QName> pair = qnameDAO.getQName(target.getName());
if (pair != null) {
Long qnameId = pair.getFirst();
qnameIds.add(qnameId);
}
} else {
Collection<QName> subaspects = dictionaryService.getSubAspects(target.getName(), true);
for (QName qname : subaspects) {
AspectDefinition current = dictionaryService.getAspect(qname);
if (target.getName().equals(current.getName()) || current.getIncludedInSuperTypeQuery()) {
Pair<Long, QName> pair = qnameDAO.getQName(qname);
if (pair != null) {
Long qnameId = pair.getFirst();
qnameIds.add(qnameId);
}
}
}
}
return qnameIds;
}
use of org.alfresco.repo.search.impl.querymodel.QueryModelException in project alfresco-repository by Alfresco.
the class DBQueryEngine method executeQuery.
/*
* (non-Javadoc)
* @see
* org.alfresco.repo.search.impl.querymodel.QueryEngine#executeQuery(org.alfresco.repo.search.impl.querymodel.Query,
* org.alfresco.repo.search.impl.querymodel.QueryOptions,
* org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext)
*/
@Override
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 QueryModelException("No selectors");
}
if (selectorGroups.size() > 1) {
throw new QueryModelException("Advanced join is not supported");
}
selectorGroup = selectorGroups.get(0);
}
HashSet<String> key = new HashSet<String>();
key.add("");
Map<Set<String>, ResultSet> answer = new HashMap<Set<String>, ResultSet>();
DBQuery dbQuery = (DBQuery) query;
if (options.getStores().size() > 1) {
throw new QueryModelException("Multi-store queries are not supported");
}
// MT
StoreRef storeRef = options.getStores().get(0);
storeRef = storeRef != null ? tenantService.getName(storeRef) : null;
Pair<Long, StoreRef> store = nodeDAO.getStore(storeRef);
if (store == null) {
throw new QueryModelException("Unknown store: " + storeRef);
}
dbQuery.setStoreId(store.getFirst());
Pair<Long, QName> sysDeletedType = qnameDAO.getQName(ContentModel.TYPE_DELETED);
if (sysDeletedType == null) {
dbQuery.setSysDeletedType(-1L);
} else {
dbQuery.setSysDeletedType(sysDeletedType.getFirst());
}
Long sinceTxId = options.getSinceTxId();
if (sinceTxId == null) {
// By default, return search results for all transactions.
sinceTxId = -1L;
}
dbQuery.setSinceTxId(sinceTxId);
dbQuery.prepare(namespaceService, dictionaryService, qnameDAO, nodeDAO, tenantService, selectorGroup, null, functionContext, metadataIndexCheck2.getPatchApplied());
List<Node> nodes = template.selectList(SELECT_BY_DYNAMIC_QUERY, dbQuery);
LinkedHashSet<Long> set = new LinkedHashSet<Long>(nodes.size());
for (Node node : nodes) {
set.add(node.getId());
}
List<Long> nodeIds = new ArrayList<Long>(set);
ResultSet rs = new DBResultSet(options.getAsSearchParmeters(), nodeIds, nodeDAO, nodeService, tenantService, Integer.MAX_VALUE);
ResultSet paged = new PagingLuceneResultSet(rs, options.getAsSearchParmeters(), nodeService);
answer.put(key, paged);
return new QueryEngineResults(answer);
}
use of org.alfresco.repo.search.impl.querymodel.QueryModelException in project alfresco-repository by Alfresco.
the class DBFTSPhrase method prepare.
/*
* (non-Javadoc)
* @see
* org.alfresco.repo.search.impl.querymodel.impl.db.DBQueryBuilderComponent#prepare(org.alfresco.service.namespace
* .NamespaceService, org.alfresco.service.cmr.dictionary.DictionaryService,
* org.alfresco.repo.domain.qname.QNameDAO, org.alfresco.repo.domain.node.NodeDAO, java.util.Set, java.util.Map,
* org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext)
*/
@Override
public void prepare(NamespaceService namespaceService, DictionaryService dictionaryService, QNameDAO qnameDAO, NodeDAO nodeDAO, TenantService tenantService, Set<String> selectors, Map<String, Argument> functionArgs, FunctionEvaluationContext functionContext, boolean supportBooleanFloatAndDouble) {
Argument argument = functionArgs.get(ARG_PHRASE);
String term = (String) argument.getValue(functionContext);
PropertyArgument propArg = (PropertyArgument) functionArgs.get(ARG_PROPERTY);
if ((propArg == null) || (propArg.getPropertyName() == null)) {
throw new QueryModelException("Default field not supported");
} else if (propArg.getPropertyName().equals(QueryConstants.FIELD_PARENT)) {
ParentSupport parentSupport = new ParentSupport();
String id = (String) term;
parentSupport.setDbid(DBQuery.getDbid(id, nodeDAO, tenantService));
parentSupport.setCommandType(DBQueryBuilderPredicatePartCommandType.EQUALS);
builderSupport = parentSupport;
} else if (propArg.getPropertyName().equals(QueryConstants.FIELD_TYPE)) {
TypeSupport typeSupport = new TypeSupport();
typeSupport.setQnameIds(DBQuery.findTypeIds(term, namespaceService, dictionaryService, qnameDAO, false));
typeSupport.setCommandType(DBQueryBuilderPredicatePartCommandType.IN);
builderSupport = typeSupport;
} else if (propArg.getPropertyName().equals(QueryConstants.FIELD_ASPECT)) {
AspectSupport aspectSupport = new AspectSupport();
aspectSupport.setQnameIds(DBQuery.findAspectIds(term, namespaceService, dictionaryService, qnameDAO, false));
builderSupport = aspectSupport;
} else if (propArg.getPropertyName().equals(QueryConstants.FIELD_EXACTTYPE)) {
TypeSupport typeSupport = new TypeSupport();
typeSupport.setQnameIds(DBQuery.findTypeIds(term, namespaceService, dictionaryService, qnameDAO, true));
typeSupport.setCommandType(DBQueryBuilderPredicatePartCommandType.IN);
builderSupport = typeSupport;
} else if (propArg.getPropertyName().equals(QueryConstants.FIELD_EXACTASPECT)) {
AspectSupport aspectSupport = new AspectSupport();
aspectSupport.setQnameIds(DBQuery.findAspectIds(term, namespaceService, dictionaryService, qnameDAO, true));
builderSupport = aspectSupport;
} else {
argument = functionArgs.get(ARG_TOKENISATION_MODE);
AnalysisMode mode = (AnalysisMode) argument.getValue(functionContext);
if (mode != AnalysisMode.IDENTIFIER) {
throw new QueryModelException("Analysis mode not supported for DB " + mode);
}
PropertySupport propertySupport = new PropertySupport();
propertySupport.setValue(term);
QName propertyQName = QName.createQName(DBQuery.expandQName(functionContext.getAlfrescoPropertyName(propArg.getPropertyName()), namespaceService));
propertySupport.setPropertyQName(propertyQName);
propertySupport.setPropertyDataType(DBQuery.getDataTypeDefinition(dictionaryService, propertyQName));
propertySupport.setPair(qnameDAO.getQName(propertyQName));
propertySupport.setJoinCommandType(DBQuery.getJoinCommandType(propertyQName));
propertySupport.setFieldName(DBQuery.getFieldName(dictionaryService, propertyQName, supportBooleanFloatAndDouble));
propertySupport.setCommandType(DBQueryBuilderPredicatePartCommandType.EQUALS);
builderSupport = propertySupport;
}
}
Aggregations