Permalink
Browse files

Added function range:index-keys-for-field to retrieve keys defined on…

… a field index. The normal util:index-keys function does not support fields.
  • Loading branch information...
1 parent 03c7ff6 commit 9e94b0398e0350433b0e259de76e5a1c2d44746b @wolfgangmm wolfgangmm committed Sep 16, 2013
@@ -0,0 +1,62 @@
+package org.exist.xquery.modules.range;
+
+import org.exist.dom.QName;
+import org.exist.indexing.range.RangeIndexWorker;
+import org.exist.util.Occurrences;
+import org.exist.xquery.*;
+import org.exist.xquery.value.*;
+
+public class IndexKeys extends BasicFunction {
+
+ public final static FunctionSignature[] signatures = {
+ new FunctionSignature(
+ new QName("index-keys-for-field", RangeIndexModule.NAMESPACE_URI, RangeIndexModule.PREFIX),
+ "Retrieve all index keys contained in a range index which has been defined with a field name. Similar to" +
+ "util:index-keys, but works with fields.",
+ new SequenceType[] {
+ new FunctionParameterSequenceType("field", Type.STRING, Cardinality.EXACTLY_ONE, "The field to use"),
+ new FunctionParameterSequenceType("function-reference", Type.FUNCTION_REFERENCE, Cardinality.EXACTLY_ONE, "The function reference as created by the util:function function. " +
+ "It can be an arbitrary user-defined function, but it should take exactly 2 arguments: " +
+ "1) the current index key as found in the range index as an atomic value, 2) a sequence " +
+ "containing three int values: a) the overall frequency of the key within the node set, " +
+ "b) the number of distinct documents in the node set the key occurs in, " +
+ "c) the current position of the key in the whole list of keys returned."),
+ new FunctionParameterSequenceType("max-number-returned", Type.INT, Cardinality.ZERO_OR_ONE , "The maximum number of returned keys")
+ },
+ new FunctionReturnSequenceType(Type.ITEM, Cardinality.ZERO_OR_MORE, "the results of the eval of the $function-reference"))
+ };
+
+ public IndexKeys(XQueryContext context, FunctionSignature signature) {
+ super(context, signature);
+ }
+
+ @Override
+ public Sequence eval(final Sequence[] args, final Sequence contextSequence) throws XPathException {
+ final String field = args[0].getStringValue();
+ final FunctionReference ref = (FunctionReference) args[1].itemAt(0);
+ int max = -1;
+ if (!args[2].isEmpty()) {
+ max = ((IntegerValue)args[2].itemAt(0)).getInt();
+ }
+
+ final Sequence result = new ValueSequence();
+ final RangeIndexWorker worker = (RangeIndexWorker) context.getBroker().getIndexController().getWorkerByIndexName("range-index");
+ Occurrences[] occur = worker.scanIndexByField(field, contextSequence == null ? context.getStaticallyKnownDocuments() : contextSequence.getDocumentSet(), max);
+ final int len = (max != -1 && occur.length > max ? max : occur.length);
+ final Sequence params[] = new Sequence[2];
+ ValueSequence data = new ValueSequence();
+ for (int j = 0; j < len; j++) {
+ params[0] = new StringValue(occur[j].getTerm().toString());
+ data.add(new IntegerValue(occur[j].getOccurrences(),
+ Type.UNSIGNED_INT));
+ data.add(new IntegerValue(occur[j].getDocuments(),
+ Type.UNSIGNED_INT));
+ data.add(new IntegerValue(j + 1, Type.UNSIGNED_INT));
+ params[1] = data;
+
+ result.addAll(ref.evalFunction(Sequence.EMPTY_SEQUENCE, null, params));
+ data.clear();
+ }
+ return result;
+ }
+}
@@ -53,7 +53,8 @@
new FunctionDef(FieldLookup.signatures[6], FieldLookup.class),
new FunctionDef(FieldLookup.signatures[7], FieldLookup.class),
new FunctionDef(FieldLookup.signatures[8], FieldLookup.class),
- new FunctionDef(Optimize.signature, Optimize.class)
+ new FunctionDef(Optimize.signature, Optimize.class),
+ new FunctionDef(IndexKeys.signatures[0], IndexKeys.class)
};
public final static Map<String, RangeIndex.Operator> OPERATOR_MAP = new HashMap<String, RangeIndex.Operator>();

0 comments on commit 9e94b03

Please sign in to comment.