Support comparison of integer values
Change-Id: I5b8718165579a4606b3beb1635ea71eb5d2619f9
diff --git a/Changes b/Changes
index e101056..d0bac00 100644
--- a/Changes
+++ b/Changes
@@ -1,8 +1,10 @@
-0.63.3 2024-11-04
+0.63.3 2024-12-15
- [performance] Improve short circuit on count=0 and
cutoff=true (diewald)
- [feature] Make defaultSearchContextLength and maxCharContextSize
- customizable (margaretha)
+ customizable (margaretha)
+ - [feature] Support comparison of integer values
+ (diewald & kupietz)
0.63.2 2024-08-02
- [bugfix] Fix empty DocIdSetIterator (margaretha)
diff --git a/src/main/java/de/ids_mannheim/korap/KrillCollection.java b/src/main/java/de/ids_mannheim/korap/KrillCollection.java
index ffa99cd..dd4cb75 100644
--- a/src/main/java/de/ids_mannheim/korap/KrillCollection.java
+++ b/src/main/java/de/ids_mannheim/korap/KrillCollection.java
@@ -296,7 +296,36 @@
};
throw new QueryException(841,
- "Match relation unknown for type");
+ "Match relation `" + match+ "' unknown for type:date");
+ }
+
+ // Filter based on integer
+ else if (valtype.equals("type:integer")) {
+
+ if (!json.has("value"))
+ throw new QueryException(820, "Integers require value fields");
+
+ int value = json.get("value").asInt();
+
+ if (json.has("match")) match = json.get("match").asText();
+
+ switch (match) {
+ case "match:geq":
+ return this.cb.geq(key, value);
+ case "match:leq":
+ return this.cb.leq(key, value);
+ case "match:eq":
+ return this.cb.eq(key, value);
+ case "match:ne":
+ return this.cb.eq(key, value).not();
+ case "match:gt":
+ return this.cb.gt(key, value);
+ case "match:lt":
+ return this.cb.lt(key, value);
+ };
+
+ throw new QueryException(841,
+ "Match relation `" + match+ "' unknown for type:integer");
}
// Filter based on string
diff --git a/src/main/java/de/ids_mannheim/korap/collection/CollectionBuilder.java b/src/main/java/de/ids_mannheim/korap/collection/CollectionBuilder.java
index 166dc90..bc3c7ff 100644
--- a/src/main/java/de/ids_mannheim/korap/collection/CollectionBuilder.java
+++ b/src/main/java/de/ids_mannheim/korap/collection/CollectionBuilder.java
@@ -71,7 +71,7 @@
return new CollectionBuilder.Range(field, since, KrillDate.END);
};
-
+
public CollectionBuilder.Interface nothing () {
// Requires that a field with name "0---" does not exist
@@ -109,6 +109,38 @@
return this.andGroup().with(startObj).with(endObj);
};
+ public CollectionBuilder.Interface leq (String field, Integer end) {
+ return this.between(field, Integer.MIN_VALUE, end);
+ };
+
+ public CollectionBuilder.Interface geq (String field, Integer start) {
+ return this.between(field, start, Integer.MAX_VALUE);
+ };
+
+ public CollectionBuilder.Interface eq (String field, Integer value) {
+ return this.between(field, value, value);
+ };
+
+ public CollectionBuilder.Interface lt (String field, Integer value) {
+ return this.between(field, Integer.MIN_VALUE, value - 1);
+ };
+
+ public CollectionBuilder.Interface gt (String field, Integer value) {
+ return this.between(field, value + 1, Integer.MAX_VALUE);
+ };
+
+ // This will be optimized away in future versions
+ public CollectionBuilder.Interface between (String field, Integer start,
+ Integer end) {
+
+ try {
+ return new CollectionBuilder.NumRange(field, start, end);
+ }
+ catch (NumberFormatException e) {
+ log.warn("Parameter of between(int,int) is invalid");
+ };
+ return null;
+ };
public CollectionBuilder.Interface date (String field, String date) {
KrillDate dateDF = new KrillDate(date);
@@ -427,4 +459,41 @@
return this;
};
};
+
+ public class NumRange implements CollectionBuilder.Interface {
+ private boolean isNegative = false;
+ private String field;
+ private int start, end;
+
+ public NumRange (String field, int start, int end) {
+ this.field = field;
+ this.start = start;
+ this.end = end;
+ };
+
+
+ public boolean isNegative () {
+ return this.isNegative;
+ };
+
+
+ public String toString () {
+ Filter filter = this.toFilter();
+ if (filter == null)
+ return "";
+ return filter.toString();
+ };
+
+
+ public Filter toFilter () {
+ return NumericRangeFilter.newDoubleRange(this.field, (double) this.start,
+ (double) this.end, true, true);
+ };
+
+
+ public CollectionBuilder.Interface not () {
+ this.isNegative = true;
+ return this;
+ };
+ };
};
diff --git a/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionIndex.java b/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionIndex.java
index c5d87f9..066dc43 100644
--- a/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionIndex.java
@@ -586,6 +586,54 @@
assertEquals(1, kcn.docCount());
};
+ @Test
+ public void testIndexWithIntegers () throws IOException {
+ ki = new KrillIndex();
+
+ FieldDocument fd = ki.addDoc(createDoc1());
+ ki.addDoc(createDoc2());
+ ki.addDoc(createDoc5001());
+ ki.commit();
+
+ CollectionBuilder cb = new CollectionBuilder();
+ KrillCollection kcn = new KrillCollection(ki);
+
+ assertEquals("toks:[2000.0 TO 4000.0]", cb.between("toks", 2000, 4000).toString());
+
+ kcn.fromBuilder(cb.between("toks", 2000, 4000));
+ assertEquals(1, kcn.docCount());
+
+ kcn.fromBuilder(cb.geq("toks", 2000));
+ assertEquals(1, kcn.docCount());
+
+ kcn.fromBuilder(cb.leq("toks", 4000));
+ assertEquals(1, kcn.docCount());
+
+ kcn.fromBuilder(cb.leq("toks", 2000));
+ assertEquals(0, kcn.docCount());
+
+ kcn.fromBuilder(cb.geq("toks", 4000));
+ assertEquals(0, kcn.docCount());
+
+ kcn.fromBuilder(cb.lt("toks", 3000));
+ assertEquals(0, kcn.docCount());
+
+ kcn.fromBuilder(cb.lt("toks", 3001));
+ assertEquals(1, kcn.docCount());
+
+ kcn.fromBuilder(cb.gt("toks", 3000));
+ assertEquals(0, kcn.docCount());
+
+ kcn.fromBuilder(cb.gt("toks", 2999));
+ assertEquals(1, kcn.docCount());
+
+ kcn.fromBuilder(cb.eq("toks", 3000));
+ assertEquals(1, kcn.docCount());
+
+ kcn.fromBuilder(cb.eq("toks", 3001));
+ assertEquals(0, kcn.docCount());
+ };
+
@Test
public void testIndexWithTextStringQueries () throws IOException {
ki = new KrillIndex();
@@ -1241,6 +1289,18 @@
return fd;
};
+ public static FieldDocument createDoc5001 () {
+ FieldDocument fd = new FieldDocument();
+ fd.addString("UID", "5001");
+ fd.addString("ID", "doc-5001");
+ fd.addInt("toks", 3000);
+ fd.addDate("pubDate", 20180202);
+ fd.addText("text", "Der alte Mann ging über die Straße");
+ fd.addTV("tokens", "a b c", "[(0-1)s:a|i:a|_0$<i>0<i>1|-:t$<i>3]"
+ + "[(2-3)s:b|i:b|_1$<i>2<i>3]" + "[(4-5)s:c|i:c|_2$<i>4<i>5]");
+ return fd;
+ };
+
private String _getJSONString (String file) {
return getJsonString(getClass().getResource(path + file).getFile());
};