Support fields parameter in getFields() and fields order in metadata responses (fixes #46)
Change-Id: Ie479a60bd247c1989c89dcffb5383271a8ba4a15
diff --git a/Changes b/Changes
index 8c82163..e9c6eec 100644
--- a/Changes
+++ b/Changes
@@ -1,4 +1,4 @@
-0.58.4 2019-01-17
+0.58.4 2019-01-18
- [cleanup] Remove deprecated methods setLicense/getLicense,
setTokenization/getTokenization, setLayerInfo/getLayerInfo,
setField/getField (including json serialization)
@@ -9,6 +9,10 @@
fields (diewald)
- [feature] Support for arbitrary metadata fields (fixes #47)
(diewald)
+ - [feature] Support for fields parameter in getFields() method
+ (fixes #46) (diewald)
+ - [feature] Respect fields order for fields responses (fixes #46)
+ (diewald)
0.58.3 2018-12-17
- [feature] Introduced attachements as meta data fields
diff --git a/src/main/java/de/ids_mannheim/korap/Krill.java b/src/main/java/de/ids_mannheim/korap/Krill.java
index d395fec..6bee230 100644
--- a/src/main/java/de/ids_mannheim/korap/Krill.java
+++ b/src/main/java/de/ids_mannheim/korap/Krill.java
@@ -61,10 +61,6 @@
private final ObjectMapper mapper = new ObjectMapper();
- // Logger
- private final static Logger log = LoggerFactory.getLogger(Krill.class);
-
-
/**
* Construct a new Krill object.
*/
@@ -305,7 +301,6 @@
// Apply search
else {
-
// This contains meta and matches
kr = this.index.search(this);
// this.getCollection().setIndex(this.index);
@@ -313,6 +308,7 @@
};
kr.setQuery(this.getQuery());
+
kr.setCollection(this.getCollection());
kr.setMeta(this.getMeta());
diff --git a/src/main/java/de/ids_mannheim/korap/KrillIndex.java b/src/main/java/de/ids_mannheim/korap/KrillIndex.java
index 6a7e495..a365045 100644
--- a/src/main/java/de/ids_mannheim/korap/KrillIndex.java
+++ b/src/main/java/de/ids_mannheim/korap/KrillIndex.java
@@ -4,13 +4,7 @@
import java.io.InputStream;
import java.nio.ByteBuffer;
// Java core classes
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
+import java.util.*;
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;
@@ -818,7 +812,7 @@
uid = new Integer(Integer.parseInt(uid)).toString();
Filter filter = (Filter) new QueryWrapperFilter(
- new TermQuery(new Term("UID", uid)));
+ new TermQuery(new Term("UID", uid)));
try {
@@ -1110,24 +1104,28 @@
field);
// The following fields should be lifted for the match
- HashSet<String> fields = (HashSet<String>) new Krill().getMeta()
- .getFields().clone();
-
- // Lift primary field
- fields.add(field);
+ List<String> fields = (ArrayList<String>) new Krill().getMeta()
+ .getFields().clone();
// Lift all fields
if (fields.contains("@all"))
fields = null;
+ HashSet<String> fieldsSet = new HashSet<String>(fields);
+
+ // Lift primary field
+ fieldsSet.add(field);
+
// Load the necessary fields of the document
- Document doc = atomic.reader().document(localDocID, fields);
+ Document doc = (fields != null)
+ ? atomic.reader().document(localDocID, fieldsSet)
+ : atomic.reader().document(localDocID);
// Put some more information to the match
PositionsToOffset pto = new PositionsToOffset(atomic, field);
match.setPositionsToOffset(pto);
match.setLocalDocID(localDocID);
- match.populateDocument(doc, field, fields);
+ match.populateDocument(doc, field, (List<String>) fields);
if (DEBUG)
log.trace("The document has the id '{}' or the sigle '{}'",
match.getDocID(), match.getTextSigle());
@@ -1346,15 +1344,18 @@
kr.setVersion(this.getVersion());
// The following fields should be lifted for matches
- HashSet<String> fields = (HashSet<String>) meta.getFields().clone();
-
- // Lift primary field
- fields.add(field);
+ List<String> fields = (ArrayList<String>) meta.getFields().clone();
+ HashSet<String> fieldsSet = new HashSet<String>(fields);
// Lift all fields
- if (fields.contains("@all"))
+ if (fields.contains("@all")) {
fields = null;
-
+ }
+ else {
+ // Lift primary field
+ fieldsSet.add(field);
+ };
+
// Some initializations ...
int i = 0;
int startIndex = kr.getStartIndex();
@@ -1479,7 +1480,7 @@
// Do not load all of this, in case the doc is the same!
final Document doc = (fields != null)
- ? lreader.document(localDocID, fields)
+ ? lreader.document(localDocID, fieldsSet)
: lreader.document(localDocID);
// Create new Match
@@ -1593,20 +1594,24 @@
return kr;
};
+ public MetaFields getFields (String textSigle) {
+
+ List hs = new ArrayList<String>();
+ hs.add("@all");
+ return this.getFields(textSigle, hs);
+ };
+
// Return field values
- public MetaFields getFields (String textSigle) {
- // , HashSet<String> fields) {
+ public MetaFields getFields (String textSigle, List<String> fields) {
// Create TermQuery for document
TermQuery textSigleQuery = new TermQuery(new Term("textSigle", textSigle));
Filter filter = (Filter) new QueryWrapperFilter(textSigleQuery);
- /*
- if (fields.contain("@all"))
+ if (fields.contains("@all"))
fields = null;
- */
MetaFields metaFields = new MetaFields(textSigle);
@@ -1632,7 +1637,10 @@
continue;
Document doc = atomic.reader().document(localDocID);
- metaFields.populateFields(doc);
+ if (fields == null)
+ metaFields.populateFields(doc);
+ else
+ metaFields.populateFields(doc, fields);
return metaFields;
};
diff --git a/src/main/java/de/ids_mannheim/korap/KrillMeta.java b/src/main/java/de/ids_mannheim/korap/KrillMeta.java
index 330cbdb..a3db457 100644
--- a/src/main/java/de/ids_mannheim/korap/KrillMeta.java
+++ b/src/main/java/de/ids_mannheim/korap/KrillMeta.java
@@ -26,7 +26,7 @@
private short itemsPerResource = 0;
private SearchContext context;
- private HashSet<String> fields;
+ private ArrayList<String> fields;
HashSet<Integer> highlights;
// Timeout search after milliseconds
@@ -37,9 +37,7 @@
private final static Logger log = LoggerFactory.getLogger(Krill.class);
{
- fields = new HashSet<String>(16);
-
- // TODO: Support @all
+ fields = new ArrayList<String>(16);
// Lift following fields per default
// These fields are chosen for <legacy /> reasons
@@ -171,8 +169,9 @@
this.addField(field.asText());
};
}
- else
+ else {
this.addField(json.get("fields").asText());
+ };
};
return this;
@@ -265,7 +264,7 @@
/**
* Get the fields as a set
*/
- public HashSet<String> getFields () {
+ public ArrayList<String> getFields () {
return this.fields;
};
diff --git a/src/main/java/de/ids_mannheim/korap/index/AbstractDocument.java b/src/main/java/de/ids_mannheim/korap/index/AbstractDocument.java
index 8856d98..8de0f35 100644
--- a/src/main/java/de/ids_mannheim/korap/index/AbstractDocument.java
+++ b/src/main/java/de/ids_mannheim/korap/index/AbstractDocument.java
@@ -115,7 +115,7 @@
* Primary data field.
*/
public void populateDocument (Document doc, String field) {
- HashSet<String> fieldList = new HashSet<>(32);
+ List<String> fieldList = new ArrayList<>(32);
Iterator<IndexableField> fieldIterator = doc.getFields().iterator();
while (fieldIterator.hasNext())
fieldList.add(fieldIterator.next().name());
@@ -135,23 +135,26 @@
* Hash object with all supported fields.
*/
public void populateDocument (Document doc, String field,
- Collection<String> fields) {
+ List<String> fields) {
this.setPrimaryData(doc.get(field));
this.populateFields(doc, fields);
};
public void populateFields (Document doc) {
- HashSet<String> fieldList = new HashSet<>(32);
+ ArrayList<String> fieldList = new ArrayList<>(32);
Iterator<IndexableField> fieldIterator = doc.getFields().iterator();
- while (fieldIterator.hasNext())
+ while (fieldIterator.hasNext()) {
fieldList.add(fieldIterator.next().name());
+ };
+ // TODO: Sort alphabetically!
+
this.populateFields(doc, fieldList);
};
- public void populateFields (Document doc, Collection<String> fields) {
+ public void populateFields (Document doc, List<String> fields) {
// Remove all fields already set
Iterator<String> fieldsIter = fields.iterator();
while (fieldsIter.hasNext()) {
@@ -160,10 +163,13 @@
};
};
- if (fields.contains("UID"))
+
+ if (fields.contains("UID")) {
this.setUID(doc.get("UID"));
+ };
fieldsIter = fields.iterator();
+ mFields.fieldsOrder = new ArrayList<>(16);
while (fieldsIter.hasNext()) {
String name = fieldsIter.next();
@@ -172,11 +178,12 @@
if (name == "tokens" || name == "UID")
continue;
+ mFields.fieldsOrder.add(name);
+
IndexableField iField = doc.getField(name);
if (iField == null)
continue;
-
MetaField mf = mFields.add(iField);
@@ -352,17 +359,21 @@
HashMap<String, JsonNode> map = new HashMap<>();
while (mfIterator.hasNext()) {
- String mfs = mfIterator.next().key;
- if (legacyDateFields.contains(mfs) ||
- legacyStoredFields.contains(mfs) ||
- legacyTextFields.contains(mfs) ||
- legacyStringFields.contains(mfs) ||
- legacyKeywordsFields.contains(mfs)
+ MetaField mf = mfIterator.next();
+ if (mf == null)
+ continue;
+ String mfs = mf.key;
+ String value = this.getFieldValue(mfs);
+ if (value != null && (
+ legacyDateFields.contains(mfs) ||
+ legacyStoredFields.contains(mfs) ||
+ legacyTextFields.contains(mfs) ||
+ legacyStringFields.contains(mfs) ||
+ legacyKeywordsFields.contains(mfs) ||
+ legacyDateFields.contains(mfs)
+ )
) {
- map.put(mfs, new TextNode(this.getFieldValue(mfs)));
- }
- else if (legacyDateFields.contains(mfs)) {
- map.put(mfs, new TextNode(this.getFieldValue(mfs)));
+ map.put(mfs, new TextNode(value));
}
};
diff --git a/src/main/java/de/ids_mannheim/korap/response/MetaField.java b/src/main/java/de/ids_mannheim/korap/response/MetaField.java
index 94052d7..e6b330e 100644
--- a/src/main/java/de/ids_mannheim/korap/response/MetaField.java
+++ b/src/main/java/de/ids_mannheim/korap/response/MetaField.java
@@ -17,11 +17,10 @@
// Mapper for JSON serialization
ObjectMapper mapper = new ObjectMapper();
- public String type = "type:string";
+ public String type;
public String key;
public List<String> values = new ArrayList<>();
-
public MetaField (String key) {
this.key = key;
};
@@ -52,9 +51,13 @@
public JsonNode toJsonNode () {
ObjectNode json = mapper.createObjectNode();
json.put("@type", "koral:field");
- json.put("type", this.type);
json.put("key", this.key);
+ if (this.type == null)
+ return json;
+
+ json.put("type", this.type);
+
// Value is numerical
if (this.type.equals("type:integer")) {
diff --git a/src/main/java/de/ids_mannheim/korap/response/MetaFieldsObj.java b/src/main/java/de/ids_mannheim/korap/response/MetaFieldsObj.java
index ea992b2..c6ba70e 100644
--- a/src/main/java/de/ids_mannheim/korap/response/MetaFieldsObj.java
+++ b/src/main/java/de/ids_mannheim/korap/response/MetaFieldsObj.java
@@ -40,6 +40,8 @@
// Mapper for JSON serialization
ObjectMapper mapper = new ObjectMapper();
+ public List<String> fieldsOrder;
+
private Map<String, MetaField> fieldsMap = new HashMap<>();
@@ -53,7 +55,7 @@
return this.add(
metaFieldFromIndexableField(
iField,
- new MetaField(iField.name())
+ new MetaField(iField.name(), "type:string")
)
);
};
@@ -76,7 +78,7 @@
return mf;
};
-
+
// Field type needs to be restored heuristically
// - though that's not very elegant
public static MetaField metaFieldFromIndexableField (IndexableField iField, MetaField mf) {
@@ -206,14 +208,20 @@
return fieldsMap.containsKey(key);
};
+ private Iterator<String> getIterator () {
+ if (this.fieldsOrder == null) {
+ return fieldsMap.keySet().iterator();
+ };
+ return this.fieldsOrder.iterator();
+ };
@Override
public Iterator<MetaField> iterator() {
return new Iterator<MetaField>() {
- private Iterator it = fieldsMap.keySet().iterator();
-
+ private Iterator<String> it = getIterator();
+
private int currentIndex = 0;
@Override
@@ -223,7 +231,11 @@
@Override
public MetaField next() {
- return fieldsMap.get(it.next());
+ String key = it.next();
+ MetaField mf = fieldsMap.get(key);
+ if (mf == null)
+ return new MetaField(key);
+ return mf;
};
@Override
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestFieldDocument.java b/src/test/java/de/ids_mannheim/korap/index/TestFieldDocument.java
index 141e60b..ea49bb5 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestFieldDocument.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestFieldDocument.java
@@ -1,6 +1,7 @@
package de.ids_mannheim.korap.index;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.*;
@@ -11,6 +12,7 @@
import org.apache.lucene.search.spans.SpanQuery;
import org.junit.Test;
+import org.junit.Ignore;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -26,7 +28,6 @@
import de.ids_mannheim.korap.response.Match;
import de.ids_mannheim.korap.response.Result;
import de.ids_mannheim.korap.util.QueryException;
-import static de.ids_mannheim.korap.response.MetaFieldsObj.*;
import org.apache.lucene.document.Document;
@@ -441,92 +442,10 @@
};
};
+
@Test
public void indexArbitraryMetaData () throws Exception {
- String json = new String(
- "{"
- + " \"fields\" : ["
- + " { "
- + " \"primaryData\" : \"abc\""
- + " },"
- + " {"
- + " \"name\" : \"tokens\","
- + " \"data\" : ["
- + " [ \"s:a\", \"i:a\", \"_0$<i>0<i>1\", \"-:t$<i>3\"],"
- + " [ \"s:b\", \"i:b\", \"_1$<i>1<i>2\" ],"
- + " [ \"s:c\", \"i:c\", \"_2$<i>2<i>3\" ]"
- + " ]"
- + " }"
- + " ],"
- + " \"metaFields\" : ["
- + " {"
- + " \"@type\" : \"koral:field\","
- + " \"type\" : \"type:string\","
- + " \"key\" : \"textSigle\","
- + " \"value\" : \"aa/bb/cc\""
- + " },"
- + " {"
- + " \"@type\" : \"koral:field\","
- + " \"type\" : \"type:integer\","
- + " \"key\" : \"alter\","
- + " \"value\" : 40"
- + " },"
- + " {"
- + " \"@type\" : \"koral:field\","
- + " \"type\" : \"type:string\","
- + " \"key\" : \"name\","
- + " \"value\" : \"Frank\""
- + " },"
- + " {"
- + " \"@type\" : \"koral:field\","
- + " \"type\" : \"type:string\","
- + " \"key\" : \"name\","
- + " \"value\" : \"Julian\""
- + " },"
- + " {"
- + " \"@type\" : \"koral:field\","
- + " \"type\" : \"type:string\","
- + " \"key\" : \"schluesselwoerter\","
- + " \"value\" : [\"musik\",\"unterhaltung\"]"
- + " },"
- + " {"
- + " \"@type\" : \"koral:field\","
- + " \"type\" : \"type:keywords\","
- + " \"key\" : \"tags\","
- + " \"value\" : \"nachrichten feuilleton\""
- + " },"
- + " {"
- + " \"@type\" : \"koral:field\","
- + " \"type\" : \"type:keywords\","
- + " \"key\" : \"tags\","
- + " \"value\" : [\"sport\",\"raetsel\"]"
- + " },"
- + " {"
- + " \"@type\" : \"koral:field\","
- + " \"type\" : \"type:text\","
- + " \"key\" : \"titel\","
- + " \"value\" : \"Der alte Baum\""
- + " },"
- + " {"
- + " \"@type\" : \"koral:field\","
- + " \"type\" : \"type:attachement\","
- + " \"key\" : \"anhang\","
- + " \"value\" : \"data:application/x.korap-link,http://spiegel.de/\""
- + " },"
- + " {"
- + " \"@type\" : \"koral:field\","
- + " \"type\" : \"type:store\","
- + " \"key\" : \"referenz\","
- + " \"value\" : \"So war das\""
- + " },"
- + " {"
- + " \"@type\" : \"koral:field\","
- + " \"type\" : \"type:date\","
- + " \"key\" : \"datum\","
- + " \"value\" : \"2018-04-03\""
- + " }"
- + " ]"
- + "}");
+ String json = createDocString1();
KrillIndex ki = new KrillIndex();
FieldDocument fd = ki.addDoc(json);
@@ -623,4 +542,160 @@
};
};
};
+
+ @Test
+ public void indexArbitraryMetaDataPartial () throws Exception {
+ String json = createDocString1();
+
+ KrillIndex ki = new KrillIndex();
+ FieldDocument fd = ki.addDoc(json);
+
+ ki.commit();
+
+ ArrayList hs = new ArrayList<String>();
+ hs.add("datum");
+ hs.add("titel");
+ JsonNode res = ki.getFields("aa/bb/cc", hs).toJsonNode();
+ assertEquals("type:date", res.at("/document/fields/0/type").asText());
+ assertEquals("datum", res.at("/document/fields/0/key").asText());
+ assertEquals("2018-04-03", res.at("/document/fields/0/value").asText());
+ assertEquals("type:text", res.at("/document/fields/1/type").asText());
+ assertEquals("titel", res.at("/document/fields/1/key").asText());
+ assertEquals("Der alte Baum", res.at("/document/fields/1/value").asText());
+ assertTrue(res.at("/document/fields/2").isMissingNode());
+ };
+
+ @Test
+ public void indexArbitraryMetaDataSorted () throws Exception {
+ String json = createDocString1();
+
+ KrillIndex ki = new KrillIndex();
+ FieldDocument fd = ki.addDoc(json);
+
+ ki.commit();
+
+ ArrayList hs = new ArrayList<String>();
+ hs.add("titel");
+ hs.add("datum");
+ JsonNode res = ki.getFields("aa/bb/cc", hs).toJsonNode();
+ assertEquals("type:text", res.at("/document/fields/0/type").asText());
+ assertEquals("titel", res.at("/document/fields/0/key").asText());
+ assertEquals("Der alte Baum", res.at("/document/fields/0/value").asText());
+ assertEquals("type:date", res.at("/document/fields/1/type").asText());
+ assertEquals("datum", res.at("/document/fields/1/key").asText());
+ assertEquals("2018-04-03", res.at("/document/fields/1/value").asText());
+ assertTrue(res.at("/document/fields/2").isMissingNode());
+ };
+
+ @Test
+ public void indexArbitraryMetaDataEmpty () throws Exception {
+ String json = createDocString1();
+
+ KrillIndex ki = new KrillIndex();
+ FieldDocument fd = ki.addDoc(json);
+
+ ki.commit();
+
+ ArrayList hs = new ArrayList<String>();
+ hs.add("titel");
+ hs.add("frage");
+ hs.add("datum");
+ JsonNode res = ki.getFields("aa/bb/cc", hs).toJsonNode();
+ assertEquals("type:text", res.at("/document/fields/0/type").asText());
+ assertEquals("titel", res.at("/document/fields/0/key").asText());
+ assertEquals("Der alte Baum", res.at("/document/fields/0/value").asText());
+ assertEquals("frage", res.at("/document/fields/1/key").asText());
+ assertTrue(res.at("/document/fields/1/type").isMissingNode());
+ assertEquals("type:date", res.at("/document/fields/2/type").asText());
+ assertEquals("datum", res.at("/document/fields/2/key").asText());
+ assertEquals("2018-04-03", res.at("/document/fields/2/value").asText());
+ assertTrue(res.at("/document/fields/3").isMissingNode());
+ };
+
+ private static String createDocString1 () {
+ return new String(
+ "{"
+ + " \"fields\" : ["
+ + " { "
+ + " \"primaryData\" : \"abc\""
+ + " },"
+ + " {"
+ + " \"name\" : \"tokens\","
+ + " \"data\" : ["
+ + " [ \"s:a\", \"i:a\", \"_0$<i>0<i>1\", \"-:t$<i>3\"],"
+ + " [ \"s:b\", \"i:b\", \"_1$<i>1<i>2\" ],"
+ + " [ \"s:c\", \"i:c\", \"_2$<i>2<i>3\" ]"
+ + " ]"
+ + " }"
+ + " ],"
+ + " \"metaFields\" : ["
+ + " {"
+ + " \"@type\" : \"koral:field\","
+ + " \"type\" : \"type:string\","
+ + " \"key\" : \"textSigle\","
+ + " \"value\" : \"aa/bb/cc\""
+ + " },"
+ + " {"
+ + " \"@type\" : \"koral:field\","
+ + " \"type\" : \"type:integer\","
+ + " \"key\" : \"alter\","
+ + " \"value\" : 40"
+ + " },"
+ + " {"
+ + " \"@type\" : \"koral:field\","
+ + " \"type\" : \"type:string\","
+ + " \"key\" : \"name\","
+ + " \"value\" : \"Frank\""
+ + " },"
+ + " {"
+ + " \"@type\" : \"koral:field\","
+ + " \"type\" : \"type:string\","
+ + " \"key\" : \"name\","
+ + " \"value\" : \"Julian\""
+ + " },"
+ + " {"
+ + " \"@type\" : \"koral:field\","
+ + " \"type\" : \"type:string\","
+ + " \"key\" : \"schluesselwoerter\","
+ + " \"value\" : [\"musik\",\"unterhaltung\"]"
+ + " },"
+ + " {"
+ + " \"@type\" : \"koral:field\","
+ + " \"type\" : \"type:keywords\","
+ + " \"key\" : \"tags\","
+ + " \"value\" : \"nachrichten feuilleton\""
+ + " },"
+ + " {"
+ + " \"@type\" : \"koral:field\","
+ + " \"type\" : \"type:keywords\","
+ + " \"key\" : \"tags\","
+ + " \"value\" : [\"sport\",\"raetsel\"]"
+ + " },"
+ + " {"
+ + " \"@type\" : \"koral:field\","
+ + " \"type\" : \"type:text\","
+ + " \"key\" : \"titel\","
+ + " \"value\" : \"Der alte Baum\""
+ + " },"
+ + " {"
+ + " \"@type\" : \"koral:field\","
+ + " \"type\" : \"type:attachement\","
+ + " \"key\" : \"anhang\","
+ + " \"value\" : \"data:application/x.korap-link,http://spiegel.de/\""
+ + " },"
+ + " {"
+ + " \"@type\" : \"koral:field\","
+ + " \"type\" : \"type:store\","
+ + " \"key\" : \"referenz\","
+ + " \"value\" : \"So war das\""
+ + " },"
+ + " {"
+ + " \"@type\" : \"koral:field\","
+ + " \"type\" : \"type:date\","
+ + " \"key\" : \"datum\","
+ + " \"value\" : \"2018-04-03\""
+ + " }"
+ + " ]"
+ + "}");
+ };
};
diff --git a/src/test/java/de/ids_mannheim/korap/search/TestMetaFields.java b/src/test/java/de/ids_mannheim/korap/search/TestMetaFields.java
index c61a1f2..3f6ba6d 100644
--- a/src/test/java/de/ids_mannheim/korap/search/TestMetaFields.java
+++ b/src/test/java/de/ids_mannheim/korap/search/TestMetaFields.java
@@ -131,6 +131,7 @@
Result kr = ks.apply(ki);
ObjectMapper mapper = new ObjectMapper();
JsonNode res = mapper.readTree(kr.toJsonString());
+
assertEquals(0, res.at("/matches/0/UID").asInt());
assertEquals("GOE_AGX.00002", res.at("/matches/0/textSigle").asText());
assertEquals("Maximen und Reflexionen",