Search in sources :

Example 1 with QueryModelException

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;
}
Also used : NodeParameters(org.alfresco.repo.solr.NodeParameters) Node(org.alfresco.repo.domain.node.Node) QueryModelException(org.alfresco.repo.search.impl.querymodel.QueryModelException) ArrayList(java.util.ArrayList) SolrJSONResultSet(org.alfresco.repo.search.impl.lucene.SolrJSONResultSet) ChildAssociationRef(org.alfresco.service.cmr.repository.ChildAssociationRef) StopWatch(org.springframework.util.StopWatch) NodeRef(org.alfresco.service.cmr.repository.NodeRef) ResultSet(org.alfresco.service.cmr.search.ResultSet) ChildAssocRefResultSet(org.alfresco.repo.search.results.ChildAssocRefResultSet) SolrJSONResultSet(org.alfresco.repo.search.impl.lucene.SolrJSONResultSet) ChildAssocRefResultSet(org.alfresco.repo.search.results.ChildAssocRefResultSet) HashSet(java.util.HashSet)

Example 2 with QueryModelException

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);
    }
}
Also used : QName(org.alfresco.service.namespace.QName) QueryModelException(org.alfresco.repo.search.impl.querymodel.QueryModelException) TypeDefinition(org.alfresco.service.cmr.dictionary.TypeDefinition) DataTypeDefinition(org.alfresco.service.cmr.dictionary.DataTypeDefinition)

Example 3 with QueryModelException

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;
}
Also used : QName(org.alfresco.service.namespace.QName) ArrayList(java.util.ArrayList) QueryModelException(org.alfresco.repo.search.impl.querymodel.QueryModelException) AspectDefinition(org.alfresco.service.cmr.dictionary.AspectDefinition)

Example 4 with QueryModelException

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);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) QueryEngineResults(org.alfresco.repo.search.impl.querymodel.QueryEngineResults) HashSet(java.util.HashSet) PagingLuceneResultSet(org.alfresco.repo.search.impl.lucene.PagingLuceneResultSet) LinkedHashSet(java.util.LinkedHashSet) ResultSet(org.alfresco.service.cmr.search.ResultSet) Set(java.util.Set) HashMap(java.util.HashMap) Node(org.alfresco.repo.domain.node.Node) QueryModelException(org.alfresco.repo.search.impl.querymodel.QueryModelException) ArrayList(java.util.ArrayList) PagingLuceneResultSet(org.alfresco.repo.search.impl.lucene.PagingLuceneResultSet) ResultSet(org.alfresco.service.cmr.search.ResultSet) PagingLuceneResultSet(org.alfresco.repo.search.impl.lucene.PagingLuceneResultSet) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) StoreRef(org.alfresco.service.cmr.repository.StoreRef) QName(org.alfresco.service.namespace.QName)

Example 5 with QueryModelException

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;
    }
}
Also used : AspectSupport(org.alfresco.repo.search.impl.querymodel.impl.db.AspectSupport) Argument(org.alfresco.repo.search.impl.querymodel.Argument) PropertyArgument(org.alfresco.repo.search.impl.querymodel.PropertyArgument) TypeSupport(org.alfresco.repo.search.impl.querymodel.impl.db.TypeSupport) QName(org.alfresco.service.namespace.QName) QueryModelException(org.alfresco.repo.search.impl.querymodel.QueryModelException) ParentSupport(org.alfresco.repo.search.impl.querymodel.impl.db.ParentSupport) AnalysisMode(org.alfresco.repo.search.adaptor.lucene.AnalysisMode) PropertyArgument(org.alfresco.repo.search.impl.querymodel.PropertyArgument) PropertySupport(org.alfresco.repo.search.impl.querymodel.impl.db.PropertySupport)

Aggregations

QueryModelException (org.alfresco.repo.search.impl.querymodel.QueryModelException)16 QName (org.alfresco.service.namespace.QName)9 ArrayList (java.util.ArrayList)4 Argument (org.alfresco.repo.search.impl.querymodel.Argument)4 PropertyArgument (org.alfresco.repo.search.impl.querymodel.PropertyArgument)4 AnalysisMode (org.alfresco.repo.search.adaptor.lucene.AnalysisMode)3 ParentSupport (org.alfresco.repo.search.impl.querymodel.impl.db.ParentSupport)3 PropertySupport (org.alfresco.repo.search.impl.querymodel.impl.db.PropertySupport)3 ResultSet (org.alfresco.service.cmr.search.ResultSet)3 Serializable (java.io.Serializable)2 HashSet (java.util.HashSet)2 Node (org.alfresco.repo.domain.node.Node)2 SolrJSONResultSet (org.alfresco.repo.search.impl.lucene.SolrJSONResultSet)2 FTSQueryException (org.alfresco.repo.search.impl.parsers.FTSQueryException)2 AspectSupport (org.alfresco.repo.search.impl.querymodel.impl.db.AspectSupport)2 TypeSupport (org.alfresco.repo.search.impl.querymodel.impl.db.TypeSupport)2 ChildAssocRefResultSet (org.alfresco.repo.search.results.ChildAssocRefResultSet)2 AspectDefinition (org.alfresco.service.cmr.dictionary.AspectDefinition)2 DataTypeDefinition (org.alfresco.service.cmr.dictionary.DataTypeDefinition)2 TypeDefinition (org.alfresco.service.cmr.dictionary.TypeDefinition)2