use of org.exist.dom.persistent.DocumentSet in project exist by eXist-db.
the class LuceneIndexTest method configuration.
@Test
public void configuration() throws EXistException, CollectionConfigurationException, PermissionDeniedException, SAXException, LockException, IOException, XPathException, QName.IllegalQNameException {
final DocumentSet docs = configureAndStore(COLLECTION_CONFIG4, XML4, "test.xml");
final BrokerPool pool = existEmbeddedServer.getBrokerPool();
try (final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()))) {
checkIndex(docs, broker, new QName[] { new QName("a") }, "x", 1);
checkIndex(docs, broker, new QName[] { new QName("c") }, "x", 1);
final XQuery xquery = pool.getXQueryService();
assertNotNull(xquery);
Sequence seq = xquery.execute(broker, "/test[ft:query(a, 'x')]", null);
assertNotNull(seq);
assertEquals(1, seq.getItemCount());
seq = xquery.execute(broker, "/test[ft:query(.//c, 'x')]", null);
assertNotNull(seq);
assertEquals(1, seq.getItemCount());
seq = xquery.execute(broker, "/test[ft:query(b, 'x')]", null);
assertNotNull(seq);
assertEquals(0, seq.getItemCount());
}
}
use of org.exist.dom.persistent.DocumentSet in project exist by eXist-db.
the class LuceneIndexTest method attributeMatch.
@Test
public void attributeMatch() throws EXistException, CollectionConfigurationException, PermissionDeniedException, SAXException, TriggerException, LockException, IOException, XPathException, ParserConfigurationException {
final DocumentSet docs = configureAndStore(COLLECTION_CONFIG7, XML8, "test.xml");
final BrokerPool pool = existEmbeddedServer.getBrokerPool();
final TransactionManager transact = pool.getTransactionManager();
try (final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()));
final Txn transaction = transact.beginTransaction()) {
final XQuery xquery = pool.getXQueryService();
assertNotNull(xquery);
Sequence seq = xquery.execute(broker, "for $a in ft:query((//b|//c), 'AAA') order by ft:score($a) descending return xs:string($a)", null);
assertNotNull(seq);
assertEquals(5, seq.getItemCount());
assertEquals("AAA on b2", seq.itemAt(0).getStringValue());
assertEquals("AAA on c1", seq.itemAt(1).getStringValue());
assertEquals("AAA on b3", seq.itemAt(2).getStringValue());
assertEquals("AAA on b1", seq.itemAt(3).getStringValue());
assertEquals("AAA on c2", seq.itemAt(4).getStringValue());
// path: /a/b
seq = xquery.execute(broker, "for $a in ft:query(/a/b, 'AAA') order by ft:score($a) descending return xs:string($a)", null);
assertNotNull(seq);
assertEquals(2, seq.getItemCount());
assertEquals("AAA on b2", seq.itemAt(0).getStringValue());
assertEquals("AAA on b1", seq.itemAt(1).getStringValue());
seq = xquery.execute(broker, "for $a in ft:query(//@att, 'att') order by ft:score($a) descending return xs:string($a)", null);
assertNotNull(seq);
assertEquals(4, seq.getItemCount());
assertEquals("att on b2", seq.itemAt(0).getStringValue());
assertEquals("att on b3", seq.itemAt(1).getStringValue());
assertEquals("att on b1", seq.itemAt(2).getStringValue());
assertEquals("att on c1", seq.itemAt(3).getStringValue());
// modify with xupdate and check if boosts are updated accordingly
final XUpdateProcessor proc = new XUpdateProcessor(broker, docs);
assertNotNull(proc);
proc.setBroker(broker);
proc.setDocumentSet(docs);
// remove 'att' attribute from first c element: it gets no boost
// also append an 'att' attribute on second c element which will
// make the two switch order in the result sequence.
String xupdate = XUPDATE_START + " <xu:remove select=\"//c[1]/@att\"/>" + " <xu:append select=\"//c[2]\"><xu:attribute name=\"att\">att on c2</xu:attribute></xu:append>" + XUPDATE_END;
final Modification[] modifications = proc.parse(new InputSource(new StringReader(xupdate)));
assertNotNull(modifications);
modifications[0].process(transaction);
modifications[1].process(transaction);
proc.reset();
transact.commit(transaction);
seq = xquery.execute(broker, "for $a in ft:query((//b|//c), 'AAA') order by ft:score($a) descending return xs:string($a)", null);
assertNotNull(seq);
assertEquals(5, seq.getItemCount());
assertEquals("AAA on b2", seq.itemAt(0).getStringValue());
assertEquals("AAA on c2", seq.itemAt(1).getStringValue());
assertEquals("AAA on b3", seq.itemAt(2).getStringValue());
assertEquals("AAA on b1", seq.itemAt(3).getStringValue());
assertEquals("AAA on c1", seq.itemAt(4).getStringValue());
}
}
use of org.exist.dom.persistent.DocumentSet in project exist by eXist-db.
the class Query method eval.
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
return Sequence.EMPTY_SEQUENCE;
NodeSet result;
if (preselectResult == null) {
long start = System.currentTimeMillis();
Sequence input = getArgument(0).eval(contextSequence);
if (!(input instanceof VirtualNodeSet) && input.isEmpty())
result = NodeSet.EMPTY_SET;
else {
NodeSet inNodes = input.toNodeSet();
DocumentSet docs = inNodes.getDocumentSet();
LuceneIndexWorker index = (LuceneIndexWorker) context.getBroker().getIndexController().getWorkerByIndexId(LuceneIndex.ID);
Item key = getKey(contextSequence, contextItem);
List<QName> qnames = null;
if (contextQName != null) {
qnames = new ArrayList<>(1);
qnames.add(contextQName);
}
QueryOptions options = parseOptions(this, contextSequence, contextItem, 3);
try {
if (key != null && Type.subTypeOf(key.getType(), Type.ELEMENT)) {
final Element queryXML = (Element) ((NodeValue) key).getNode();
result = index.query(getExpressionId(), docs, inNodes, qnames, queryXML, NodeSet.ANCESTOR, options);
} else {
final String query = key == null ? null : key.getStringValue();
result = index.query(getExpressionId(), docs, inNodes, qnames, query, NodeSet.ANCESTOR, options);
}
} catch (IOException | org.apache.lucene.queryparser.classic.ParseException e) {
throw new XPathException(this, e.getMessage());
}
}
if (context.getProfiler().traceFunctions()) {
context.getProfiler().traceIndexUsage(context, "lucene", this, PerformanceStats.BASIC_INDEX, System.currentTimeMillis() - start);
}
} else {
// DW: contextSequence can be null
contextStep.setPreloadedData(contextSequence.getDocumentSet(), preselectResult);
result = getArgument(0).eval(contextSequence).toNodeSet();
}
return result;
}
use of org.exist.dom.persistent.DocumentSet 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;
}
use of org.exist.dom.persistent.DocumentSet in project exist by eXist-db.
the class LuceneIndexTest method xupdateRemove.
/**
* Remove nodes from different levels of the tree and check if the index is
* correctly updated.
*/
@Test
public void xupdateRemove() throws EXistException, CollectionConfigurationException, PermissionDeniedException, SAXException, LockException, IOException, XPathException, ParserConfigurationException, QName.IllegalQNameException {
final DocumentSet docs = configureAndStore(COLLECTION_CONFIG2, XML2, "xupdate.xml");
final BrokerPool pool = existEmbeddedServer.getBrokerPool();
final TransactionManager transact = pool.getTransactionManager();
try (final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()));
final Txn transaction = transact.beginTransaction()) {
checkIndex(docs, broker, new QName[] { new QName("description") }, "chair", 1);
checkIndex(docs, broker, new QName[] { new QName("item") }, null, 5);
checkIndex(docs, broker, new QName[] { new QName("condition") }, null, 2);
final XQuery xquery = pool.getXQueryService();
assertNotNull(xquery);
Sequence seq = xquery.execute(broker, "//item[ft:query(description, 'chair')]", null);
assertNotNull(seq);
assertEquals(1, seq.getItemCount());
final XUpdateProcessor proc = new XUpdateProcessor(broker, docs);
assertNotNull(proc);
proc.setBroker(broker);
proc.setDocumentSet(docs);
String xupdate = XUPDATE_START + " <xu:remove select=\"//item[@id='2']/condition\"/>" + XUPDATE_END;
Modification[] modifications = proc.parse(new InputSource(new StringReader(xupdate)));
assertNotNull(modifications);
modifications[0].process(transaction);
proc.reset();
checkIndex(docs, broker, new QName[] { new QName("condition") }, null, 1);
checkIndex(docs, broker, new QName[] { new QName("item") }, null, 4);
checkIndex(docs, broker, new QName[] { new QName("condition") }, "good", 0);
checkIndex(docs, broker, new QName[] { new QName("item") }, "good", 0);
Occurrences[] o = checkIndex(docs, broker, new QName[] { new QName("description") }, "table", 1);
assertEquals("table", o[0].getTerm());
o = checkIndex(docs, broker, new QName[] { new QName("description") }, "cabinet", 1);
assertEquals("cabinet", o[0].getTerm());
o = checkIndex(docs, broker, new QName[] { new QName("item") }, "table", 1);
assertEquals("table", o[0].getTerm());
o = checkIndex(docs, broker, new QName[] { new QName("item") }, "cabinet", 1);
assertEquals("cabinet", o[0].getTerm());
proc.setBroker(broker);
proc.setDocumentSet(docs);
xupdate = XUPDATE_START + " <xu:remove select=\"//item[@id='3']/description/text()\"/>" + XUPDATE_END;
modifications = proc.parse(new InputSource(new StringReader(xupdate)));
assertNotNull(modifications);
modifications[0].process(transaction);
proc.reset();
proc.setBroker(broker);
proc.setDocumentSet(docs);
xupdate = XUPDATE_START + " <xu:remove select=\"//item[@id='1']\"/>" + XUPDATE_END;
modifications = proc.parse(new InputSource(new StringReader(xupdate)));
assertNotNull(modifications);
modifications[0].process(transaction);
proc.reset();
o = checkIndex(docs, broker, new QName[] { new QName("description") }, null, 1);
assertEquals("table", o[0].getTerm());
checkIndex(docs, broker, new QName[] { new QName("description") }, "chair", 0);
checkIndex(docs, broker, new QName[] { new QName("item") }, "chair", 0);
transact.commit(transaction);
}
}
Aggregations