diff --git a/docs/03-apis/api-v2/reading-and-searching-resources.md b/docs/03-apis/api-v2/reading-and-searching-resources.md index acc49ef174..9c48a40bb7 100644 --- a/docs/03-apis/api-v2/reading-and-searching-resources.md +++ b/docs/03-apis/api-v2/reading-and-searching-resources.md @@ -509,6 +509,9 @@ in `app/v2` in `application.conf`. If the parameter `limitToStandoffClass` is provided, Knora will look for search terms that are marked up with the indicated standoff class. +If the parameter `returnFiles=true` is provided, Knora will return any +file value attached to each matching resource. + To request the number of results rather than the results themselves, you can do a count query: diff --git a/test_data/searchR2RV2/FulltextSearchWithImage.jsonld b/test_data/searchR2RV2/FulltextSearchWithImage.jsonld new file mode 100644 index 0000000000..e826fd245a --- /dev/null +++ b/test_data/searchR2RV2/FulltextSearchWithImage.jsonld @@ -0,0 +1,579 @@ + +{ + "@graph": [ + { + "knora-api:arkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/00505cf0a803D", + "@type": "xsd:anyURI" + }, + "rdfs:label": "p7v", + "knora-api:hasStillImageFileValue": { + "knora-api:arkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/00505cf0a803D/00000000009e73f9ac230w5", + "@type": "xsd:anyURI" + }, + "knora-api:versionArkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/00505cf0a803D/00000000009e73f9ac230w5.20121121T165056Z", + "@type": "xsd:anyURI" + }, + "knora-api:userHasPermission": "RV", + "knora-api:valueCreationDate": { + "@value": "2012-11-21T16:50:56Z", + "@type": "xsd:dateTimeStamp" + }, + "knora-api:stillImageFileValueHasDimX": 1954, + "knora-api:attachedToUser": { + "@id": "http://rdfh.ch/users/91e19f1e01" + }, + "knora-api:valueHasUUID": "00000000009e73f9ac230w", + "knora-api:fileValueAsUrl": { + "@value": "IIIF_BASE_URL/0803/incunabula_0000004096.jp2/full/1954,2630/0/default.jpg", + "@type": "xsd:anyURI" + }, + "knora-api:hasPermissions": "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser", + "@type": "knora-api:StillImageFileValue", + "knora-api:fileValueHasFilename": "incunabula_0000004096.jp2", + "knora-api:stillImageFileValueHasDimY": 2630, + "knora-api:stillImageFileValueHasIIIFBaseUrl": { + "@value": "IIIF_BASE_URL/0803", + "@type": "xsd:anyURI" + }, + "@id": "http://rdfh.ch/0803/00505cf0a803/values/9e73f9ac2307" + }, + "knora-api:versionArkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/00505cf0a803D.20160302T150546Z", + "@type": "xsd:anyURI" + }, + "knora-api:attachedToProject": { + "@id": "http://rdfh.ch/projects/0803" + }, + "knora-api:userHasPermission": "RV", + "incunabula:pagenum": { + "knora-api:valueAsString": "p7v", + "knora-api:arkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/00505cf0a803D/0000000000fe5c3f85970Qs", + "@type": "xsd:anyURI" + }, + "knora-api:versionArkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/00505cf0a803D/0000000000fe5c3f85970Qs.20160302T150546Z", + "@type": "xsd:anyURI" + }, + "knora-api:userHasPermission": "V", + "knora-api:valueCreationDate": { + "@value": "2016-03-02T15:05:46Z", + "@type": "xsd:dateTimeStamp" + }, + "knora-api:attachedToUser": { + "@id": "http://rdfh.ch/users/91e19f1e01" + }, + "knora-api:valueHasUUID": "0000000000fe5c3f85970Q", + "knora-api:hasPermissions": "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:UnknownUser,knora-admin:KnownUser", + "@type": "knora-api:TextValue", + "@id": "http://rdfh.ch/0803/00505cf0a803/values/fe5c3f85970e" + }, + "knora-api:creationDate": { + "@value": "2016-03-02T15:05:46Z", + "@type": "xsd:dateTimeStamp" + }, + "knora-api:attachedToUser": { + "@id": "http://rdfh.ch/users/91e19f1e01" + }, + "knora-api:hasPermissions": "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser", + "@type": "incunabula:page", + "@id": "http://rdfh.ch/0803/00505cf0a803" + }, + { + "knora-api:arkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/0ee0fe735d03Z", + "@type": "xsd:anyURI" + }, + "rdfs:label": "p7v", + "knora-api:hasStillImageFileValue": { + "knora-api:arkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/0ee0fe735d03Z/0000000000b06e4255900wp", + "@type": "xsd:anyURI" + }, + "knora-api:versionArkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/0ee0fe735d03Z/0000000000b06e4255900wp.20121121T165048Z", + "@type": "xsd:anyURI" + }, + "knora-api:userHasPermission": "RV", + "knora-api:valueCreationDate": { + "@value": "2012-11-21T16:50:48Z", + "@type": "xsd:dateTimeStamp" + }, + "knora-api:stillImageFileValueHasDimX": 3182, + "knora-api:attachedToUser": { + "@id": "http://rdfh.ch/users/91e19f1e01" + }, + "knora-api:valueHasUUID": "0000000000b06e4255900w", + "knora-api:fileValueAsUrl": { + "@value": "IIIF_BASE_URL/0803/incunabula_0000003766.jp2/full/3182,5127/0/default.jpg", + "@type": "xsd:anyURI" + }, + "knora-api:hasPermissions": "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser", + "@type": "knora-api:StillImageFileValue", + "knora-api:fileValueHasFilename": "incunabula_0000003766.jp2", + "knora-api:stillImageFileValueHasDimY": 5127, + "knora-api:stillImageFileValueHasIIIFBaseUrl": { + "@value": "IIIF_BASE_URL/0803", + "@type": "xsd:anyURI" + }, + "@id": "http://rdfh.ch/0803/0ee0fe735d03/values/b06e42559006" + }, + "knora-api:versionArkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/0ee0fe735d03Z.20160302T150542Z", + "@type": "xsd:anyURI" + }, + "knora-api:attachedToProject": { + "@id": "http://rdfh.ch/projects/0803" + }, + "knora-api:userHasPermission": "RV", + "incunabula:pagenum": { + "knora-api:valueAsString": "p7v", + "knora-api:arkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/0ee0fe735d03Z/00000000001a28bee0670Qi", + "@type": "xsd:anyURI" + }, + "knora-api:versionArkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/0ee0fe735d03Z/00000000001a28bee0670Qi.20160302T150542Z", + "@type": "xsd:anyURI" + }, + "knora-api:userHasPermission": "V", + "knora-api:valueCreationDate": { + "@value": "2016-03-02T15:05:42Z", + "@type": "xsd:dateTimeStamp" + }, + "knora-api:attachedToUser": { + "@id": "http://rdfh.ch/users/91e19f1e01" + }, + "knora-api:valueHasUUID": "00000000001a28bee0670Q", + "knora-api:hasPermissions": "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:UnknownUser,knora-admin:KnownUser", + "@type": "knora-api:TextValue", + "@id": "http://rdfh.ch/0803/0ee0fe735d03/values/1a28bee0670d" + }, + "knora-api:creationDate": { + "@value": "2016-03-02T15:05:42Z", + "@type": "xsd:dateTimeStamp" + }, + "knora-api:attachedToUser": { + "@id": "http://rdfh.ch/users/91e19f1e01" + }, + "knora-api:hasPermissions": "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser", + "@type": "incunabula:page", + "@id": "http://rdfh.ch/0803/0ee0fe735d03" + }, + { + "knora-api:arkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/6157683636F", + "@type": "xsd:anyURI" + }, + "rdfs:label": "p7v", + "knora-api:hasStillImageFileValue": { + "knora-api:arkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/6157683636F/00000000000028984db16wK", + "@type": "xsd:anyURI" + }, + "knora-api:versionArkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/6157683636F/00000000000028984db16wK.20121121T164940Z", + "@type": "xsd:anyURI" + }, + "knora-api:userHasPermission": "RV", + "knora-api:valueCreationDate": { + "@value": "2012-11-21T16:49:40Z", + "@type": "xsd:dateTimeStamp" + }, + "knora-api:stillImageFileValueHasDimX": 1962, + "knora-api:attachedToUser": { + "@id": "http://rdfh.ch/users/91e19f1e01" + }, + "knora-api:valueHasUUID": "00000000000028984db16w", + "knora-api:fileValueAsUrl": { + "@value": "IIIF_BASE_URL/0803/incunabula_0000000237.jp2/full/1962,2833/0/default.jpg", + "@type": "xsd:anyURI" + }, + "knora-api:hasPermissions": "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser", + "@type": "knora-api:StillImageFileValue", + "knora-api:fileValueHasFilename": "incunabula_0000000237.jp2", + "knora-api:stillImageFileValueHasDimY": 2833, + "knora-api:stillImageFileValueHasIIIFBaseUrl": { + "@value": "IIIF_BASE_URL/0803", + "@type": "xsd:anyURI" + }, + "@id": "http://rdfh.ch/0803/6157683636/values/28984db169" + }, + "knora-api:versionArkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/6157683636F.20160302T150512Z", + "@type": "xsd:anyURI" + }, + "knora-api:attachedToProject": { + "@id": "http://rdfh.ch/projects/0803" + }, + "knora-api:userHasPermission": "RV", + "incunabula:pagenum": { + "knora-api:valueAsString": "p7v", + "knora-api:arkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/6157683636F/0000000000006523f0f3dwD", + "@type": "xsd:anyURI" + }, + "knora-api:versionArkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/6157683636F/0000000000006523f0f3dwD.20160302T150512Z", + "@type": "xsd:anyURI" + }, + "knora-api:userHasPermission": "V", + "knora-api:valueCreationDate": { + "@value": "2016-03-02T15:05:12Z", + "@type": "xsd:dateTimeStamp" + }, + "knora-api:attachedToUser": { + "@id": "http://rdfh.ch/users/91e19f1e01" + }, + "knora-api:valueHasUUID": "0000000000006523f0f3dw", + "knora-api:hasPermissions": "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:UnknownUser,knora-admin:KnownUser", + "@type": "knora-api:TextValue", + "@id": "http://rdfh.ch/0803/6157683636/values/6523f0f3d4" + }, + "knora-api:creationDate": { + "@value": "2016-03-02T15:05:12Z", + "@type": "xsd:dateTimeStamp" + }, + "knora-api:attachedToUser": { + "@id": "http://rdfh.ch/users/91e19f1e01" + }, + "knora-api:hasPermissions": "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser", + "@type": "incunabula:page", + "@id": "http://rdfh.ch/0803/6157683636" + }, + { + "knora-api:arkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/661e1505ee03k", + "@type": "xsd:anyURI" + }, + "rdfs:label": "p7v", + "knora-api:hasStillImageFileValue": { + "knora-api:arkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/661e1505ee03k/0000000000c436807aaa0wk", + "@type": "xsd:anyURI" + }, + "knora-api:versionArkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/661e1505ee03k/0000000000c436807aaa0wk.20121121T165104Z", + "@type": "xsd:anyURI" + }, + "knora-api:userHasPermission": "RV", + "knora-api:valueCreationDate": { + "@value": "2012-11-21T16:51:04Z", + "@type": "xsd:dateTimeStamp" + }, + "knora-api:stillImageFileValueHasDimX": 3617, + "knora-api:attachedToUser": { + "@id": "http://rdfh.ch/users/91e19f1e01" + }, + "knora-api:valueHasUUID": "0000000000c436807aaa0w", + "knora-api:fileValueAsUrl": { + "@value": "IIIF_BASE_URL/0803/incunabula_0000004398.jp2/full/3617,5202/0/default.jpg", + "@type": "xsd:anyURI" + }, + "knora-api:hasPermissions": "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser", + "@type": "knora-api:StillImageFileValue", + "knora-api:fileValueHasFilename": "incunabula_0000004398.jp2", + "knora-api:stillImageFileValueHasDimY": 5202, + "knora-api:stillImageFileValueHasIIIFBaseUrl": { + "@value": "IIIF_BASE_URL/0803", + "@type": "xsd:anyURI" + }, + "@id": "http://rdfh.ch/0803/661e1505ee03/values/c436807aaa07" + }, + "knora-api:versionArkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/661e1505ee03k.20160302T150550Z", + "@type": "xsd:anyURI" + }, + "knora-api:attachedToProject": { + "@id": "http://rdfh.ch/projects/0803" + }, + "knora-api:userHasPermission": "RV", + "incunabula:pagenum": { + "knora-api:valueAsString": "p7v", + "knora-api:arkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/661e1505ee03k/000000000030ee9d52b00QI", + "@type": "xsd:anyURI" + }, + "knora-api:versionArkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/661e1505ee03k/000000000030ee9d52b00QI.20160302T150550Z", + "@type": "xsd:anyURI" + }, + "knora-api:userHasPermission": "V", + "knora-api:valueCreationDate": { + "@value": "2016-03-02T15:05:50Z", + "@type": "xsd:dateTimeStamp" + }, + "knora-api:attachedToUser": { + "@id": "http://rdfh.ch/users/91e19f1e01" + }, + "knora-api:valueHasUUID": "000000000030ee9d52b00Q", + "knora-api:hasPermissions": "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:UnknownUser,knora-admin:KnownUser", + "@type": "knora-api:TextValue", + "@id": "http://rdfh.ch/0803/661e1505ee03/values/30ee9d52b00f" + }, + "knora-api:creationDate": { + "@value": "2016-03-02T15:05:50Z", + "@type": "xsd:dateTimeStamp" + }, + "knora-api:attachedToUser": { + "@id": "http://rdfh.ch/users/91e19f1e01" + }, + "knora-api:hasPermissions": "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser", + "@type": "incunabula:page", + "@id": "http://rdfh.ch/0803/661e1505ee03" + }, + { + "knora-api:arkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/672d134a3201s", + "@type": "xsd:anyURI" + }, + "rdfs:label": "p7v", + "knora-api:hasStillImageFileValue": { + "knora-api:arkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/672d134a3201s/00000000001617e7fb540wU", + "@type": "xsd:anyURI" + }, + "knora-api:versionArkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/672d134a3201s/00000000001617e7fb540wU.20121121T164954Z", + "@type": "xsd:anyURI" + }, + "knora-api:userHasPermission": "RV", + "knora-api:valueCreationDate": { + "@value": "2012-11-21T16:49:54Z", + "@type": "xsd:dateTimeStamp" + }, + "knora-api:stillImageFileValueHasDimX": 1297, + "knora-api:attachedToUser": { + "@id": "http://rdfh.ch/users/91e19f1e01" + }, + "knora-api:valueHasUUID": "00000000001617e7fb540w", + "knora-api:fileValueAsUrl": { + "@value": "IIIF_BASE_URL/0803/incunabula_0000001339.jp2/full/1297,1837/0/default.jpg", + "@type": "xsd:anyURI" + }, + "knora-api:hasPermissions": "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser", + "@type": "knora-api:StillImageFileValue", + "knora-api:fileValueHasFilename": "incunabula_0000001339.jp2", + "knora-api:stillImageFileValueHasDimY": 1837, + "knora-api:stillImageFileValueHasIIIFBaseUrl": { + "@value": "IIIF_BASE_URL/0803", + "@type": "xsd:anyURI" + }, + "@id": "http://rdfh.ch/0803/672d134a3201/values/1617e7fb5402" + }, + "knora-api:versionArkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/672d134a3201s.20160302T150518Z", + "@type": "xsd:anyURI" + }, + "knora-api:attachedToProject": { + "@id": "http://rdfh.ch/projects/0803" + }, + "knora-api:userHasPermission": "RV", + "incunabula:pagenum": { + "knora-api:valueAsString": "p7v", + "knora-api:arkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/672d134a3201s/0000000000cda9b158be0wX", + "@type": "xsd:anyURI" + }, + "knora-api:versionArkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/672d134a3201s/0000000000cda9b158be0wX.20160302T150518Z", + "@type": "xsd:anyURI" + }, + "knora-api:userHasPermission": "V", + "knora-api:valueCreationDate": { + "@value": "2016-03-02T15:05:18Z", + "@type": "xsd:dateTimeStamp" + }, + "knora-api:attachedToUser": { + "@id": "http://rdfh.ch/users/91e19f1e01" + }, + "knora-api:valueHasUUID": "0000000000cda9b158be0w", + "knora-api:hasPermissions": "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:UnknownUser,knora-admin:KnownUser", + "@type": "knora-api:TextValue", + "@id": "http://rdfh.ch/0803/672d134a3201/values/cda9b158be04" + }, + "knora-api:creationDate": { + "@value": "2016-03-02T15:05:18Z", + "@type": "xsd:dateTimeStamp" + }, + "knora-api:attachedToUser": { + "@id": "http://rdfh.ch/users/91e19f1e01" + }, + "knora-api:hasPermissions": "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser", + "@type": "incunabula:page", + "@id": "http://rdfh.ch/0803/672d134a3201" + }, + { + "knora-api:arkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/b96e9b92eb01n", + "@type": "xsd:anyURI" + }, + "rdfs:label": "p7v", + "knora-api:hasStillImageFileValue": { + "knora-api:arkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/b96e9b92eb01n/0000000000cac578f3bd0wN", + "@type": "xsd:anyURI" + }, + "knora-api:versionArkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/b96e9b92eb01n/0000000000cac578f3bd0wN.20121121T165014Z", + "@type": "xsd:anyURI" + }, + "knora-api:userHasPermission": "RV", + "knora-api:valueCreationDate": { + "@value": "2012-11-21T16:50:14Z", + "@type": "xsd:dateTimeStamp" + }, + "knora-api:stillImageFileValueHasDimX": 1360, + "knora-api:attachedToUser": { + "@id": "http://rdfh.ch/users/91e19f1e01" + }, + "knora-api:valueHasUUID": "0000000000cac578f3bd0w", + "knora-api:fileValueAsUrl": { + "@value": "IIIF_BASE_URL/0803/incunabula_0000002149.jp2/full/1360,2028/0/default.jpg", + "@type": "xsd:anyURI" + }, + "knora-api:hasPermissions": "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser", + "@type": "knora-api:StillImageFileValue", + "knora-api:fileValueHasFilename": "incunabula_0000002149.jp2", + "knora-api:stillImageFileValueHasDimY": 2028, + "knora-api:stillImageFileValueHasIIIFBaseUrl": { + "@value": "IIIF_BASE_URL/0803", + "@type": "xsd:anyURI" + }, + "@id": "http://rdfh.ch/0803/b96e9b92eb01/values/cac578f3bd03" + }, + "knora-api:versionArkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/b96e9b92eb01n.20160302T150527Z", + "@type": "xsd:anyURI" + }, + "knora-api:attachedToProject": { + "@id": "http://rdfh.ch/projects/0803" + }, + "knora-api:userHasPermission": "RV", + "incunabula:pagenum": { + "knora-api:valueAsString": "p7v", + "knora-api:arkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/b96e9b92eb01n/00000000008413d7e5a60wo", + "@type": "xsd:anyURI" + }, + "knora-api:versionArkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/b96e9b92eb01n/00000000008413d7e5a60wo.20160302T150527Z", + "@type": "xsd:anyURI" + }, + "knora-api:userHasPermission": "V", + "knora-api:valueCreationDate": { + "@value": "2016-03-02T15:05:27Z", + "@type": "xsd:dateTimeStamp" + }, + "knora-api:attachedToUser": { + "@id": "http://rdfh.ch/users/91e19f1e01" + }, + "knora-api:valueHasUUID": "00000000008413d7e5a60w", + "knora-api:hasPermissions": "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:UnknownUser,knora-admin:KnownUser", + "@type": "knora-api:TextValue", + "@id": "http://rdfh.ch/0803/b96e9b92eb01/values/8413d7e5a607" + }, + "knora-api:creationDate": { + "@value": "2016-03-02T15:05:27Z", + "@type": "xsd:dateTimeStamp" + }, + "knora-api:attachedToUser": { + "@id": "http://rdfh.ch/users/91e19f1e01" + }, + "knora-api:hasPermissions": "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser", + "@type": "incunabula:page", + "@id": "http://rdfh.ch/0803/b96e9b92eb01" + }, + { + "knora-api:arkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/fb89fa64ea02g", + "@type": "xsd:anyURI" + }, + "rdfs:label": "p7v", + "knora-api:hasStillImageFileValue": { + "knora-api:arkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/fb89fa64ea02g/00000000001ab1d0f5af0w6", + "@type": "xsd:anyURI" + }, + "knora-api:versionArkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/fb89fa64ea02g/00000000001ab1d0f5af0w6.20121121T165036Z", + "@type": "xsd:anyURI" + }, + "knora-api:userHasPermission": "RV", + "knora-api:valueCreationDate": { + "@value": "2012-11-21T16:50:36Z", + "@type": "xsd:dateTimeStamp" + }, + "knora-api:stillImageFileValueHasDimX": 1389, + "knora-api:attachedToUser": { + "@id": "http://rdfh.ch/users/91e19f1e01" + }, + "knora-api:valueHasUUID": "00000000001ab1d0f5af0w", + "knora-api:fileValueAsUrl": { + "@value": "IIIF_BASE_URL/0803/incunabula_0000003263.jp2/full/1389,1843/0/default.jpg", + "@type": "xsd:anyURI" + }, + "knora-api:hasPermissions": "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser", + "@type": "knora-api:StillImageFileValue", + "knora-api:fileValueHasFilename": "incunabula_0000003263.jp2", + "knora-api:stillImageFileValueHasDimY": 1843, + "knora-api:stillImageFileValueHasIIIFBaseUrl": { + "@value": "IIIF_BASE_URL/0803", + "@type": "xsd:anyURI" + }, + "@id": "http://rdfh.ch/0803/fb89fa64ea02/values/1ab1d0f5af05" + }, + "knora-api:versionArkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/fb89fa64ea02g.20160302T150536Z", + "@type": "xsd:anyURI" + }, + "knora-api:attachedToProject": { + "@id": "http://rdfh.ch/projects/0803" + }, + "knora-api:userHasPermission": "RV", + "incunabula:pagenum": { + "knora-api:valueAsString": "p7v", + "knora-api:arkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/fb89fa64ea02g/0000000000c5eb29b69b0Q8", + "@type": "xsd:anyURI" + }, + "knora-api:versionArkUrl": { + "@value": "http://0.0.0.0:3336/ark:/72163/1/0803/fb89fa64ea02g/0000000000c5eb29b69b0Q8.20160302T150536Z", + "@type": "xsd:anyURI" + }, + "knora-api:userHasPermission": "V", + "knora-api:valueCreationDate": { + "@value": "2016-03-02T15:05:36Z", + "@type": "xsd:dateTimeStamp" + }, + "knora-api:attachedToUser": { + "@id": "http://rdfh.ch/users/91e19f1e01" + }, + "knora-api:valueHasUUID": "0000000000c5eb29b69b0Q", + "knora-api:hasPermissions": "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:UnknownUser,knora-admin:KnownUser", + "@type": "knora-api:TextValue", + "@id": "http://rdfh.ch/0803/fb89fa64ea02/values/c5eb29b69b0b" + }, + "knora-api:creationDate": { + "@value": "2016-03-02T15:05:36Z", + "@type": "xsd:dateTimeStamp" + }, + "knora-api:attachedToUser": { + "@id": "http://rdfh.ch/users/91e19f1e01" + }, + "knora-api:hasPermissions": "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser", + "@type": "incunabula:page", + "@id": "http://rdfh.ch/0803/fb89fa64ea02" + } + ], + "@context": { + "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "knora-api": "http://api.knora.org/ontology/knora-api/v2#", + "rdfs": "http://www.w3.org/2000/01/rdf-schema#", + "incunabula": "http://0.0.0.0:3333/ontology/0803/incunabula/v2#", + "xsd": "http://www.w3.org/2001/XMLSchema#" + } +} \ No newline at end of file diff --git a/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/searchmessages/SearchMessagesV2.scala b/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/searchmessages/SearchMessagesV2.scala index 43108c186f..8ddd7323b4 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/searchmessages/SearchMessagesV2.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/searchmessages/SearchMessagesV2.scala @@ -60,6 +60,7 @@ case class FullTextSearchCountRequestV2(searchValue: String, * @param offset the offset to be used for paging. * @param limitToProject limit search to given project. * @param limitToResourceClass limit search to given resource class. + * @param returnFiles if true, return any file value value attached to each matching resource. * @param targetSchema the target API schema. * @param schemaOptions the schema options submitted with the request. * @param featureFactoryConfig the feature factory configuration. @@ -70,6 +71,7 @@ case class FulltextSearchRequestV2(searchValue: String, limitToProject: Option[IRI], limitToResourceClass: Option[SmartIri], limitToStandoffClass: Option[SmartIri], + returnFiles: Boolean, targetSchema: ApiV2Schema, schemaOptions: Set[SchemaOption], featureFactoryConfig: FeatureFactoryConfig, diff --git a/webapi/src/main/scala/org/knora/webapi/responders/v2/SearchResponderV2.scala b/webapi/src/main/scala/org/knora/webapi/responders/v2/SearchResponderV2.scala index 96195619be..8c33af103a 100644 --- a/webapi/src/main/scala/org/knora/webapi/responders/v2/SearchResponderV2.scala +++ b/webapi/src/main/scala/org/knora/webapi/responders/v2/SearchResponderV2.scala @@ -80,34 +80,42 @@ class SearchResponderV2(responderData: ResponderData) extends ResponderWithStand limitToStandoffClass, featureFactoryConfig, requestingUser) + case FulltextSearchRequestV2(searchValue, offset, limitToProject, limitToResourceClass, limitToStandoffClass, + returnFiles, targetSchema, schemaOptions, featureFactoryConfig, requestingUser) => - fulltextSearchV2(searchValue, - offset, - limitToProject, - limitToResourceClass, - limitToStandoffClass, - targetSchema, - schemaOptions, - featureFactoryConfig, - requestingUser) + fulltextSearchV2( + searchValue, + offset, + limitToProject, + limitToResourceClass, + limitToStandoffClass, + returnFiles, + targetSchema, + schemaOptions, + featureFactoryConfig, + requestingUser + ) + case GravsearchCountRequestV2(query, featureFactoryConfig, requestingUser) => gravsearchCountV2(inputQuery = query, featureFactoryConfig = featureFactoryConfig, requestingUser = requestingUser) + case GravsearchRequestV2(query, targetSchema, schemaOptions, featureFactoryConfig, requestingUser) => gravsearchV2(inputQuery = query, targetSchema = targetSchema, schemaOptions = schemaOptions, featureFactoryConfig = featureFactoryConfig, requestingUser = requestingUser) + case SearchResourceByLabelCountRequestV2(searchValue, limitToProject, limitToResourceClass, @@ -118,6 +126,7 @@ class SearchResponderV2(responderData: ResponderData) extends ResponderWithStand limitToResourceClass, featureFactoryConfig, requestingUser) + case SearchResourceByLabelRequestV2(searchValue, offset, limitToProject, @@ -132,8 +141,10 @@ class SearchResponderV2(responderData: ResponderData) extends ResponderWithStand targetSchema, featureFactoryConfig, requestingUser) + case resourcesInProjectGetRequestV2: SearchResourcesByProjectAndClassRequestV2 => searchResourcesByProjectAndClassV2(resourcesInProjectGetRequestV2) + case other => handleUnexpectedMessage(other, log, this.getClass.getName) } @@ -167,7 +178,8 @@ class SearchResponderV2(responderData: ResponderData) extends ResponderWithStand searchTerms = searchTerms, limitToProject = limitToProject, limitToResourceClass = limitToResourceClass.map(_.toString), - limitToStandoffClass.map(_.toString), + limitToStandoffClass = limitToStandoffClass.map(_.toString), + returnFiles = false, // not relevant for a count query separator = None, // no separator needed for count query limit = 1, offset = 0, @@ -197,6 +209,7 @@ class SearchResponderV2(responderData: ResponderData) extends ResponderWithStand * @param offset the offset to be used for paging. * @param limitToProject limit search to given project. * @param limitToResourceClass limit search to given resource class. + * @param returnFiles if true, return any file value attached to each matching resource. * @param targetSchema the target API schema. * @param schemaOptions the schema options submitted with the request. * @param featureFactoryConfig the feature factory configuration. @@ -208,6 +221,7 @@ class SearchResponderV2(responderData: ResponderData) extends ResponderWithStand limitToProject: Option[IRI], limitToResourceClass: Option[SmartIri], limitToStandoffClass: Option[SmartIri], + returnFiles: Boolean, targetSchema: ApiV2Schema, schemaOptions: Set[SchemaOption], featureFactoryConfig: FeatureFactoryConfig, @@ -227,6 +241,7 @@ class SearchResponderV2(responderData: ResponderData) extends ResponderWithStand limitToProject = limitToProject, limitToResourceClass = limitToResourceClass.map(_.toString), limitToStandoffClass = limitToStandoffClass.map(_.toString), + returnFiles = returnFiles, separator = Some(groupConcatSeparator), limit = settings.v2ResultsPerPage, offset = offset * settings.v2ResultsPerPage, // determine the actual offset @@ -364,7 +379,6 @@ class SearchResponderV2(responderData: ResponderData) extends ResponderWithStand * @return a [[ResourceCountV2]] representing the number of resources that have been found. */ private def gravsearchCountV2(inputQuery: ConstructQuery, - apiSchema: ApiV2Schema = ApiV2Simple, featureFactoryConfig: FeatureFactoryConfig, requestingUser: UserADM): Future[ResourceCountV2] = { diff --git a/webapi/src/main/scala/org/knora/webapi/routing/v2/SearchRouteV2.scala b/webapi/src/main/scala/org/knora/webapi/routing/v2/SearchRouteV2.scala index c9d622b473..d10e10c8d7 100644 --- a/webapi/src/main/scala/org/knora/webapi/routing/v2/SearchRouteV2.scala +++ b/webapi/src/main/scala/org/knora/webapi/routing/v2/SearchRouteV2.scala @@ -41,6 +41,7 @@ class SearchRouteV2(routeData: KnoraRouteData) extends KnoraRoute(routeData) wit private val LIMIT_TO_RESOURCE_CLASS = "limitToResourceClass" private val OFFSET = "offset" private val LIMIT_TO_STANDOFF_CLASS = "limitToStandoffClass" + private val RETURN_FILES = "returnFiles" /** * Returns the route. @@ -236,6 +237,11 @@ class SearchRouteV2(routeData: KnoraRouteData) extends KnoraRoute(routeData) wit val limitToStandoffClass: Option[SmartIri] = getStandoffClass(params) + val returnFiles: Boolean = stringFormatter.optionStringToBoolean( + params.get(RETURN_FILES), + throw BadRequestException(s"Invalid boolean value for '$RETURN_FILES'") + ) + val targetSchema: ApiV2Schema = RouteUtilV2.getOntologySchema(requestContext) val schemaOptions: Set[SchemaOption] = RouteUtilV2.getSchemaOptions(requestContext) @@ -250,7 +256,8 @@ class SearchRouteV2(routeData: KnoraRouteData) extends KnoraRoute(routeData) wit offset = offset, limitToProject = limitToProject, limitToResourceClass = limitToResourceClass, - limitToStandoffClass, + limitToStandoffClass = limitToStandoffClass, + returnFiles = returnFiles, featureFactoryConfig = featureFactoryConfig, requestingUser = requestingUser, targetSchema = targetSchema, diff --git a/webapi/src/main/twirl/org/knora/webapi/messages/twirl/queries/sparql/v1/searchFulltextStandard.scala.txt b/webapi/src/main/twirl/org/knora/webapi/messages/twirl/queries/sparql/v1/searchFulltextStandard.scala.txt index 74f83fff95..c31dc7526c 100644 --- a/webapi/src/main/twirl/org/knora/webapi/messages/twirl/queries/sparql/v1/searchFulltextStandard.scala.txt +++ b/webapi/src/main/twirl/org/knora/webapi/messages/twirl/queries/sparql/v1/searchFulltextStandard.scala.txt @@ -147,7 +147,6 @@ WHERE { OPTIONAL { ?resource knora-base:hasStillImageFileValue ?fileValue . ?fileValue a knora-base:StillImageFileValue . - ?fileValue knora-base:isPreview true . ?fileValue knora-base:internalFilename ?previewPath . OPTIONAL { diff --git a/webapi/src/main/twirl/org/knora/webapi/messages/twirl/queries/sparql/v2/searchFulltext.scala.txt b/webapi/src/main/twirl/org/knora/webapi/messages/twirl/queries/sparql/v2/searchFulltext.scala.txt index 673ac0e963..9cc6491ded 100644 --- a/webapi/src/main/twirl/org/knora/webapi/messages/twirl/queries/sparql/v2/searchFulltext.scala.txt +++ b/webapi/src/main/twirl/org/knora/webapi/messages/twirl/queries/sparql/v2/searchFulltext.scala.txt @@ -32,6 +32,7 @@ * @param limitToProject limit search to the given project. * @param limitToResourceClass limit search to given resource class. * @param limitToStandoffClass limit the search to given standoff class. + * @param returnFiles if true, return any file value attached to each matching resource. * @param separator the separator to be used in aggregation functions. * @param limit maximal amount of rows to be returned * @param offset offset for paging (starts with 0) @@ -42,6 +43,7 @@ limitToProject: Option[IRI], limitToResourceClass: Option[IRI], limitToStandoffClass: Option[IRI], + returnFiles: Boolean, separator: Option[Char], limit: Int, offset: Int, @@ -53,6 +55,7 @@ limitToProject = limitToProject, limitToResourceClass = limitToResourceClass, limitToStandoffClass = limitToStandoffClass, + returnFiles = returnFiles, separator = separator, limit = limit, offset = offset, @@ -65,6 +68,7 @@ limitToProject = limitToProject, limitToResourceClass = limitToResourceClass, limitToStandoffClass = limitToStandoffClass, + returnFiles = returnFiles, separator = separator, limit = limit, offset = offset, diff --git a/webapi/src/main/twirl/org/knora/webapi/messages/twirl/queries/sparql/v2/searchFulltextGraphDB.scala.txt b/webapi/src/main/twirl/org/knora/webapi/messages/twirl/queries/sparql/v2/searchFulltextGraphDB.scala.txt index b3ce81fc32..dd8a49e5fe 100644 --- a/webapi/src/main/twirl/org/knora/webapi/messages/twirl/queries/sparql/v2/searchFulltextGraphDB.scala.txt +++ b/webapi/src/main/twirl/org/knora/webapi/messages/twirl/queries/sparql/v2/searchFulltextGraphDB.scala.txt @@ -36,6 +36,7 @@ * @param limitToProject limit search to the given project. * @param limitToResourceClass limit search to given resource class. * @param limitToStandoffClass limit the search to given standoff class. + * @param returnFiles if true, return any file value attached to each matching resource. * @param limit maximal amount of rows to be returned * @param offset offset for paging (starts with 0) * @param countQuery indicates whether it is a count query or the actual resources should be returned. @@ -44,6 +45,7 @@ limitToProject: Option[IRI], limitToResourceClass: Option[IRI], limitToStandoffClass: Option[IRI], + returnFiles: Boolean, separator: Option[Char], limit: Int, offset: Int, @@ -53,7 +55,10 @@ PREFIX knora-base: PREFIX rdfs: @if(!countQuery) { -SELECT DISTINCT ?resource (GROUP_CONCAT(IF(BOUND(?valueObject), STR(?valueObject), ""); separator="@separator.getOrElse(throw SparqlGenerationException("Separator expected for non count query, but none given"))") AS ?valueObjectConcat) +SELECT DISTINCT ?resource + (GROUP_CONCAT(IF(BOUND(?valueObject), STR(?valueObject), ""); + separator="@separator.getOrElse(throw SparqlGenerationException("Separator expected for non count query, but none given"))") + AS ?valueObjectConcat) } else { SELECT (count(distinct ?resource) as ?count) } @@ -133,6 +138,11 @@ WHERE { case None => {} } + @if(returnFiles) { + OPTIONAL { + ?resource knora-base:hasFileValue ?valueObject . + } + } } @if(!countQuery) { GROUP BY ?resource diff --git a/webapi/src/main/twirl/org/knora/webapi/messages/twirl/queries/sparql/v2/searchFulltextStandard.scala.txt b/webapi/src/main/twirl/org/knora/webapi/messages/twirl/queries/sparql/v2/searchFulltextStandard.scala.txt index 034198c26b..be824e19b0 100644 --- a/webapi/src/main/twirl/org/knora/webapi/messages/twirl/queries/sparql/v2/searchFulltextStandard.scala.txt +++ b/webapi/src/main/twirl/org/knora/webapi/messages/twirl/queries/sparql/v2/searchFulltextStandard.scala.txt @@ -36,6 +36,7 @@ * @param limitToProject limit search to the given project. * @param limitToResourceClass limit search to given resource class. * @param limitToStandoffClass limit the search to given standoff class. + * @param returnFiles if true, return any file value attached to each matching resource. * @param separator the separator to be used in aggregation functions. * @param limit maximal amount of rows to be returned * @param offset offset for paging (starts with 0) @@ -46,6 +47,7 @@ limitToProject: Option[IRI], limitToResourceClass: Option[IRI], limitToStandoffClass: Option[IRI], + returnFiles: Boolean, separator: Option[Char], limit: Int, offset: Int, @@ -55,7 +57,10 @@ PREFIX knora-base: PREFIX rdfs: @if(!countQuery) { -SELECT DISTINCT ?resource (GROUP_CONCAT(IF(BOUND(?valueObject), STR(?valueObject), ""); separator="@separator.getOrElse(throw SparqlGenerationException("Separator expected for non count query, but none given"))") AS ?valueObjectConcat) +SELECT DISTINCT ?resource + (GROUP_CONCAT(IF(BOUND(?valueObject), STR(?valueObject), ""); + separator="@separator.getOrElse(throw SparqlGenerationException("Separator expected for non count query, but none given"))") + AS ?valueObjectConcat) } else { SELECT (count(distinct ?resource) as ?count) } @@ -135,6 +140,13 @@ WHERE { case None => {} } + @if(returnFiles) { + OPTIONAL { + ?fileValueProp rdfs:subPropertyOf* knora-base:hasFileValue . + ?resource ?fileValueProp ?valueObject . + } + } + FILTER NOT EXISTS { ?resource knora-base:isDeleted true . } diff --git a/webapi/src/test/scala/org/knora/webapi/e2e/v2/SearchRouteV2R2RSpec.scala b/webapi/src/test/scala/org/knora/webapi/e2e/v2/SearchRouteV2R2RSpec.scala index 6f75bf8a82..f6a0223c96 100644 --- a/webapi/src/test/scala/org/knora/webapi/e2e/v2/SearchRouteV2R2RSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/e2e/v2/SearchRouteV2R2RSpec.scala @@ -216,6 +216,22 @@ class SearchRouteV2R2RSpec extends R2RSpec { } } + "return files attached to full-text search results" in { + + Get("/v2/search/p7v?returnFiles=true") ~> searchPath ~> check { + + assert(status == StatusCodes.OK, response.toString) + + val expectedAnswerJSONLD = + readOrWriteTextFile(responseAs[String], + Paths.get("test_data/searchR2RV2/FulltextSearchWithImage.jsonld"), + writeTestDataFiles) + + compareJSONLDForResourcesResponse(expectedJSONLD = expectedAnswerJSONLD, receivedJSONLD = responseAs[String]) + + } + } + "not accept a fulltext query containing http://api.knora.org" in { val invalidSearchString: String = URLEncoder.encode("PREFIX knora-api: ", "UTF-8") diff --git a/webapi/src/test/scala/org/knora/webapi/responders/v2/SearchResponderV2Spec.scala b/webapi/src/test/scala/org/knora/webapi/responders/v2/SearchResponderV2Spec.scala index c1a92c19f8..e669cdf487 100644 --- a/webapi/src/test/scala/org/knora/webapi/responders/v2/SearchResponderV2Spec.scala +++ b/webapi/src/test/scala/org/knora/webapi/responders/v2/SearchResponderV2Spec.scala @@ -3,7 +3,7 @@ * * This file is part of Knora. * - * Knora is free software: you can redistribute it and/or modify + * Knora is free software: you can redistribute it and/or modifySearchResponderV2 * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. @@ -25,6 +25,7 @@ import org.knora.webapi.messages.StringFormatter import org.knora.webapi.messages.store.triplestoremessages.RdfDataObject import org.knora.webapi.messages.v2.responder.resourcemessages._ import org.knora.webapi.messages.v2.responder.searchmessages._ +import org.knora.webapi.messages.v2.responder.valuemessages.{ReadValueV2, StillImageFileValueContentV2} import org.knora.webapi.responders.v2.ResourcesResponseCheckerV2.compareReadResourcesSequenceV2Response import org.knora.webapi.sharedtestdata.SharedTestDataADM import org.knora.webapi.{ApiV2Complex, CoreSpec, SchemaOptions} @@ -58,6 +59,7 @@ class SearchResponderV2Spec extends CoreSpec() with ImplicitSender { limitToProject = None, limitToResourceClass = None, limitToStandoffClass = None, + returnFiles = false, targetSchema = ApiV2Complex, schemaOptions = SchemaOptions.ForStandoffWithTextValues, featureFactoryConfig = defaultFeatureFactoryConfig, @@ -81,6 +83,7 @@ class SearchResponderV2Spec extends CoreSpec() with ImplicitSender { limitToProject = None, limitToResourceClass = None, limitToStandoffClass = None, + returnFiles = false, targetSchema = ApiV2Complex, schemaOptions = SchemaOptions.ForStandoffWithTextValues, featureFactoryConfig = defaultFeatureFactoryConfig, @@ -95,6 +98,36 @@ class SearchResponderV2Spec extends CoreSpec() with ImplicitSender { } + "return files attached to full-text search results" in { + + responderManager ! FulltextSearchRequestV2( + searchValue = "p7v", + offset = 0, + limitToProject = None, + limitToResourceClass = None, + limitToStandoffClass = None, + returnFiles = true, + targetSchema = ApiV2Complex, + schemaOptions = SchemaOptions.ForStandoffWithTextValues, + featureFactoryConfig = defaultFeatureFactoryConfig, + requestingUser = SharedTestDataADM.anythingUser1 + ) + + expectMsgPF(timeout) { + case response: ReadResourcesSequenceV2 => + val hasImageFileValues: Boolean = + response.resources.flatMap(_.values.values.flatten).exists { readValueV2: ReadValueV2 => + readValueV2.valueContent match { + case _: StillImageFileValueContentV2 => true + case _ => false + } + } + + assert(hasImageFileValues) + } + + } + "perform an extended search for books that have the title 'Zeitglöcklein des Lebens'" in { responderManager ! GravsearchRequestV2( diff --git a/webapi/src/test/scala/org/knora/webapi/responders/v2/SearchResponderV2SpecFullData.scala b/webapi/src/test/scala/org/knora/webapi/responders/v2/SearchResponderV2SpecFullData.scala index 21f745ad0c..267702fcbc 100644 --- a/webapi/src/test/scala/org/knora/webapi/responders/v2/SearchResponderV2SpecFullData.scala +++ b/webapi/src/test/scala/org/knora/webapi/responders/v2/SearchResponderV2SpecFullData.scala @@ -1566,7 +1566,6 @@ class SearchResponderV2SpecFullData(implicit stringFormatter: StringFormatter) { )) ) - // Dear Ben: I am aware of the fact that this code is not formatted properly and I know that this deeply disturbs you. But please leave it like this since otherwise I cannot possibly read and understand this query. val constructQueryForBooksWithTitleZeitgloecklein: ConstructQuery = ConstructQuery( constructClause = ConstructClause( statements = Vector( @@ -1708,7 +1707,6 @@ class SearchResponderV2SpecFullData(implicit stringFormatter: StringFormatter) { ) ) - // Dear Ben: please see my comment above val constructQueryForBooksWithoutTitleZeitgloecklein: ConstructQuery = ConstructQuery( constructClause = ConstructClause( statements = Vector(