Search in sources :

Example 26 with NodeSet

use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.

the class FieldLookup method eval.

@Override
public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
    if (contextItem != null)
        contextSequence = contextItem.toSequence();
    if (contextSequence != null && !contextSequence.isPersistentSet())
        // in-memory docs won't have an index
        if (fallback == null) {
            return Sequence.EMPTY_SEQUENCE;
        } else {
            return fallback.eval(contextSequence, contextItem);
        }
    NodeSet result;
    if (preselectResult == null) {
        long start = System.currentTimeMillis();
        DocumentSet docs;
        if (contextSequence == null)
            docs = context.getStaticallyKnownDocuments();
        else
            docs = contextSequence.getDocumentSet();
        NodeSet contextSet = null;
        if (contextSequence != null)
            contextSet = contextSequence.toNodeSet();
        Sequence fields = getArgument(0).eval(contextSequence);
        RangeIndex.Operator[] operators = null;
        int j = 1;
        if (isCalledAs("field")) {
            Sequence operatorSeq = getArgument(1).eval(contextSequence);
            operators = new RangeIndex.Operator[operatorSeq.getItemCount()];
            int i = 0;
            for (SequenceIterator si = operatorSeq.iterate(); si.hasNext(); i++) {
                operators[i] = RangeIndexModule.OPERATOR_MAP.get(si.nextItem().getStringValue());
            }
            j++;
        } else {
            RangeIndex.Operator operator = getOperator();
            operators = new RangeIndex.Operator[fields.getItemCount()];
            Arrays.fill(operators, operator);
        }
        if (operators.length != fields.getItemCount()) {
            throw new XPathException(this, "Number of operators specified must correspond to number of fields queried");
        }
        Sequence[] keys = new Sequence[getArgumentCount() - j];
        SequenceIterator fieldIter = fields.unorderedIterator();
        for (int i = j; i < getArgumentCount(); i++) {
            keys[i - j] = getArgument(i).eval(contextSequence);
            int targetType = Type.ITEM;
            if (fieldIter.hasNext()) {
                String field = fieldIter.nextItem().getStringValue();
                targetType = getType(contextSequence, field);
            }
            if (targetType != Type.ITEM && !Type.subTypeOf(keys[i - j].getItemType(), targetType)) {
                if (keys[i - j].hasMany()) {
                    final Sequence temp = new ValueSequence(keys[i - j].getItemCount());
                    for (final SequenceIterator iterator = keys[i - j].unorderedIterator(); iterator.hasNext(); ) {
                        temp.add(iterator.nextItem().convertTo(targetType));
                    }
                    keys[i - j] = temp;
                } else {
                    keys[i - j] = keys[i - j].convertTo(targetType);
                }
            }
        }
        if (keys.length < fields.getItemCount()) {
            throw new XPathException(this, "Number of keys to look up must correspond to number of fields specified");
        }
        RangeIndexWorker index = (RangeIndexWorker) context.getBroker().getIndexController().getWorkerByIndexId(RangeIndex.ID);
        try {
            result = index.queryField(getExpressionId(), docs, contextSet, fields, keys, operators, NodeSet.DESCENDANT);
            if (contextSet != null) {
                if (fallback != null && (fallback.getPrimaryAxis() == Constants.CHILD_AXIS || fallback.getPrimaryAxis() == Constants.ATTRIBUTE_AXIS)) {
                    result = result.selectParentChild(contextSet, NodeSet.DESCENDANT, getContextId());
                } else {
                    result = result.selectAncestorDescendant(contextSet, NodeSet.DESCENDANT, true, getContextId(), true);
                }
            }
        } catch (IOException e) {
            throw new XPathException(this, e.getMessage());
        }
        if (context.getProfiler().traceFunctions()) {
            context.getProfiler().traceIndexUsage(context, "new-range", this, PerformanceStats.OPTIMIZED_INDEX, System.currentTimeMillis() - start);
        }
    // LOG.info("eval plain took " + (System.currentTimeMillis() - start));
    } else {
        result = preselectResult.selectAncestorDescendant(contextSequence.toNodeSet(), NodeSet.DESCENDANT, true, getContextId(), true);
    }
    return result;
}
Also used : NodeSet(org.exist.dom.persistent.NodeSet) IOException(java.io.IOException) RangeIndexWorker(org.exist.indexing.range.RangeIndexWorker) DocumentSet(org.exist.dom.persistent.DocumentSet) RangeIndex(org.exist.indexing.range.RangeIndex)

Example 27 with NodeSet

use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.

the class RangeIndexWorker method queryField.

public NodeSet queryField(int contextId, DocumentSet docs, NodeSet contextSet, Sequence fields, Sequence[] keys, RangeIndex.Operator[] operators, int axis) throws IOException, XPathException {
    return index.withSearcher(searcher -> {
        BooleanQuery query = new BooleanQuery();
        int j = 0;
        for (SequenceIterator i = fields.iterate(); i.hasNext(); j++) {
            String field = i.nextItem().getStringValue();
            if (keys[j].getItemCount() > 1) {
                BooleanQuery bool = new BooleanQuery();
                bool.setMinimumNumberShouldMatch(1);
                for (SequenceIterator ki = keys[j].iterate(); ki.hasNext(); ) {
                    Item key = ki.nextItem();
                    Query q = toQuery(field, null, key.atomize(), operators[j], docs);
                    bool.add(q, BooleanClause.Occur.SHOULD);
                }
                query.add(bool, BooleanClause.Occur.MUST);
            } else {
                Query q = toQuery(field, null, keys[j].itemAt(0).atomize(), operators[j], docs);
                query.add(q, BooleanClause.Occur.MUST);
            }
        }
        Query qu = query;
        BooleanClause[] clauses = query.getClauses();
        if (clauses.length == 1) {
            qu = clauses[0].getQuery();
        }
        final NodeSet resultSet = new NewArrayNodeSet();
        resultSet.addAll(doQuery(contextId, docs, contextSet, axis, searcher.searcher, Node.ELEMENT_NODE, qu, null));
        return resultSet;
    });
}
Also used : NewArrayNodeSet(org.exist.dom.persistent.NewArrayNodeSet) NodeSet(org.exist.dom.persistent.NodeSet) NewArrayNodeSet(org.exist.dom.persistent.NewArrayNodeSet)

Example 28 with NodeSet

use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.

the class RangeIndexWorker method query.

public NodeSet query(int contextId, DocumentSet docs, NodeSet contextSet, List<QName> qnames, AtomicValue[] keys, RangeIndex.Operator operator, int axis) throws IOException, XPathException {
    return index.withSearcher(searcher -> {
        List<QName> definedIndexes = getDefinedIndexes(qnames);
        NodeSet resultSet = new NewArrayNodeSet();
        for (QName qname : definedIndexes) {
            Query query;
            String field = LuceneUtil.encodeQName(qname, index.getBrokerPool().getSymbols());
            if (keys.length > 1) {
                BooleanQuery bool = new BooleanQuery();
                for (AtomicValue key : keys) {
                    bool.add(toQuery(field, qname, key, operator, docs), BooleanClause.Occur.SHOULD);
                }
                query = bool;
            } else {
                query = toQuery(field, qname, keys[0], operator, docs);
            }
            final short nodeType = qname.getNameType() == ElementValue.ATTRIBUTE ? Node.ATTRIBUTE_NODE : Node.ELEMENT_NODE;
            resultSet.addAll(doQuery(contextId, docs, contextSet, axis, searcher.searcher, nodeType, query, null));
        }
        return resultSet;
    });
}
Also used : NewArrayNodeSet(org.exist.dom.persistent.NewArrayNodeSet) NodeSet(org.exist.dom.persistent.NodeSet) NewArrayNodeSet(org.exist.dom.persistent.NewArrayNodeSet) QName(org.exist.dom.QName)

Example 29 with NodeSet

use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.

the class WildcardedExpressionTriple method eval.

@Override
public NodeSet eval(final NGramIndexWorker index, final DocumentSet docs, final List<QName> qnames, final NodeSet nodeSet, final int axis, final int expressionId) throws XPathException {
    final NodeSet headNodes = head.eval(index, docs, qnames, nodeSet, axis, expressionId);
    if (headNodes.isEmpty()) {
        return headNodes;
    }
    final NodeSet tailNodes = tail.eval(index, docs, qnames, nodeSet, axis, expressionId);
    if (tailNodes.isEmpty()) {
        return tailNodes;
    }
    final NodeSet result = NodeSets.transformNodes(headNodes, headNode -> Optional.ofNullable(tailNodes.get(headNode)).map(tailNode -> getMatchingNode(headNode, tailNode, expressionId)).orElse(null));
    return result;
}
Also used : NodeSet(org.exist.dom.persistent.NodeSet)

Example 30 with NodeSet

use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.

the class NodeSets method transformNodes.

/**
 * Builds a new NodeSet by applying a function to all NodeProxys of the supplied NodeSet and returning all non-null
 * results.
 *
 * @param nodes
 *            the NodeSet containig the NodeProys to be transformed
 * @param transform
 *            the function to be applied to all NodeProxys in nodes
 * @return a new NodeSet containing the non-null results of f applied to the NodeProxys in nodes
 *
 * @throws XPathException if an error occurs with the query.
 */
public static NodeSet transformNodes(final NodeSet nodes, final Function<NodeProxy, NodeProxy> transform) throws XPathException {
    final NodeSet result = new ExtArrayNodeSet();
    for (NodeProxy nodeProxy : nodes) {
        final NodeProxy node = transform.apply(nodeProxy);
        if (node != null) {
            result.add(node);
        }
    }
    // ensure result is ready to use
    result.iterate();
    return result;
}
Also used : ExtArrayNodeSet(org.exist.dom.persistent.ExtArrayNodeSet) NodeSet(org.exist.dom.persistent.NodeSet) ExtArrayNodeSet(org.exist.dom.persistent.ExtArrayNodeSet) NodeProxy(org.exist.dom.persistent.NodeProxy)

Aggregations

NodeSet (org.exist.dom.persistent.NodeSet)49 NodeProxy (org.exist.dom.persistent.NodeProxy)18 Sequence (org.exist.xquery.value.Sequence)18 DocumentSet (org.exist.dom.persistent.DocumentSet)14 NewArrayNodeSet (org.exist.dom.persistent.NewArrayNodeSet)12 QName (org.exist.dom.QName)11 ExtArrayNodeSet (org.exist.dom.persistent.ExtArrayNodeSet)10 VirtualNodeSet (org.exist.dom.persistent.VirtualNodeSet)9 ContextItem (org.exist.dom.persistent.ContextItem)8 IOException (java.io.IOException)7 XPathException (org.exist.xquery.XPathException)7 Collator (com.ibm.icu.text.Collator)4 EXistException (org.exist.EXistException)4 DocumentImpl (org.exist.dom.persistent.DocumentImpl)4 EmptyNodeSet (org.exist.dom.persistent.EmptyNodeSet)4 Indexable (org.exist.storage.Indexable)4 SequenceIterator (org.exist.xquery.value.SequenceIterator)4 StringValue (org.exist.xquery.value.StringValue)4 NodeImpl (org.exist.dom.memtree.NodeImpl)3 Match (org.exist.dom.persistent.Match)3