Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gravsearch enhancements and fixes #870

Merged
merged 27 commits into from
Jun 5, 2018
Merged

Conversation

benjamingeer
Copy link

@benjamingeer benjamingeer commented May 31, 2018

For a subsequent PR:

Fixes #846.
Resolves #650.
Fixes #878.
Fixes #879.
Resolves #871.

- Require the match function to be the top-level expression in a FILTER.
- Rename things to use the name Gravsearch.
@benjamingeer benjamingeer added the enhancement improve existing code or new feature label May 31, 2018
@benjamingeer benjamingeer added this to the v1.6.0 milestone May 31, 2018
@benjamingeer benjamingeer self-assigned this May 31, 2018
@benjamingeer
Copy link
Author

@tobiasschweizer I made some changes to SearchResponderV2 to support Gravsearch queries in which the main resource is an IRI. Everything seems to work except the processing of the response to the main query.

If you run SearchRouteV2R2RSpec, the test "run a Gravsearch query that searches for a resource specified by its IRI" submits this Gravsearch query:

PREFIX knora-api: <http://api.knora.org/ontology/knora-api/simple/v2#>
PREFIX anything: <http://0.0.0.0:3333/ontology/0001/anything/simple/v2#>

CONSTRUCT {
     <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw> knora-api:isMainResource true .

     <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw> a anything:Thing .

     <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw> anything:hasText ?text .

     <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw> anything:hasInteger ?integer .

} WHERE {
     <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw> a knora-api:Resource .

     <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw> a anything:Thing .

     <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw> anything:hasText ?text .

     anything:hasText knora-api:objectType xsd:string .

     ?text a xsd:string .

     <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw> anything:hasInteger ?integer .

     anything:hasInteger knora-api:objectType xsd:integer .

     ?integer a xsd:integer.
}

This is the prequery:

SELECT DISTINCT (GROUP_CONCAT(?integer; SEPARATOR='') AS ?integerConcat) (GROUP_CONCAT(?text; SEPARATOR='') AS ?textConcat)
WHERE {
<http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/knora-base#Resource> .
GRAPH <http://www.ontotext.com/explicit> {
    <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw> <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
<http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/0001/anything#Thing> .
<http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw> <http://www.knora.org/ontology/0001/anything#hasText> ?text .
GRAPH <http://www.ontotext.com/explicit> {
    ?text <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
<http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw> <http://www.knora.org/ontology/0001/anything#hasInteger> ?integer .
GRAPH <http://www.ontotext.com/explicit> {
    ?integer <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
}


OFFSET 0
LIMIT 25

This is the prequery result:

{
  "head":{
    "vars":[
      "integerConcat",
      "textConcat"
    ]
  },
  "results":{
    "bindings":[
      {
        "integerConcat":{
          "type":"literal",
          "value":"http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/dJ1ES8QTQNepFKF5-EAqdg"
        },
        "textConcat":{
          "type":"literal",
          "value":"http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/SZyeLLmOTcCCuS3B0VksHQ"
        }
      }
    ]
  }
}

This is the main query:

CONSTRUCT {
?mainResourceVar <http://www.knora.org/ontology/knora-base#isMainResource> "true"^^<http://www.w3.org/2001/XMLSchema#boolean> .
?mainAndDependentResource <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/knora-base#Resource> .
?mainAndDependentResource ?mainAndDependentResourceProp ?mainAndDependentResourceObj .
?mainAndDependentResource <http://www.knora.org/ontology/knora-base#hasValue> ?mainAndDependentResourceValueObject .
?mainAndDependentResource ?mainAndDependentResourceValueProp ?mainAndDependentResourceValueObject .
?mainAndDependentResourceValueObject ?mainAndDependentResourceValueObjectProp ?mainAndDependentResourceValueObjectObj .
?mainAndDependentResourceValueObject <http://www.knora.org/ontology/knora-base#valueHasStandoff> ?standoffNode .
?standoffNode ?standoffProp ?standoffValue .
?mainAndDependentResourceValueObject <http://www.knora.org/ontology/knora-base#valueHasListNode> ?listNode .
?listNode <http://www.w3.org/2000/01/rdf-schema#label> ?listNodeLabel .
} WHERE {
{
VALUES ?mainResourceVar { <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw> }
?mainResourceVar <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/knora-base#Resource> .
GRAPH <http://www.ontotext.com/explicit> {
    ?mainResourceVar <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
} UNION {
VALUES ?mainAndDependentResource { <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw> }
?mainAndDependentResource <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/knora-base#Resource> .
GRAPH <http://www.ontotext.com/explicit> {
    ?mainAndDependentResource <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
GRAPH <http://www.ontotext.com/explicit> {
    ?mainAndDependentResource ?mainAndDependentResourceProp ?mainAndDependentResourceObj .
}
} UNION {
VALUES ?mainAndDependentResourceValueObject { <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/dJ1ES8QTQNepFKF5-EAqdg> <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/SZyeLLmOTcCCuS3B0VksHQ> }
?mainAndDependentResource <http://www.knora.org/ontology/knora-base#hasValue> ?mainAndDependentResourceValueObject .
GRAPH <http://www.ontotext.com/explicit> {
    ?mainAndDependentResource ?mainAndDependentResourceValueProp ?mainAndDependentResourceValueObject .
}
GRAPH <http://www.ontotext.com/explicit> {
    ?mainAndDependentResourceValueObject <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
GRAPH <http://www.ontotext.com/explicit> {
    ?mainAndDependentResourceValueObject ?mainAndDependentResourceValueObjectProp ?mainAndDependentResourceValueObjectObj .
}
} UNION {
VALUES ?mainAndDependentResourceValueObject { <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/dJ1ES8QTQNepFKF5-EAqdg> <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/SZyeLLmOTcCCuS3B0VksHQ> }
GRAPH <http://www.ontotext.com/explicit> {
    ?mainAndDependentResourceValueObject <http://www.knora.org/ontology/knora-base#valueHasStandoff> ?standoffNode .
}
GRAPH <http://www.ontotext.com/explicit> {
    ?standoffNode ?standoffProp ?standoffValue .
}
} UNION {
VALUES ?mainAndDependentResourceValueObject { <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/dJ1ES8QTQNepFKF5-EAqdg> <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/SZyeLLmOTcCCuS3B0VksHQ> }
GRAPH <http://www.ontotext.com/explicit> {
    ?mainAndDependentResourceValueObject <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/knora-base#ListValue> .
}
GRAPH <http://www.ontotext.com/explicit> {
    ?mainAndDependentResourceValueObject <http://www.knora.org/ontology/knora-base#valueHasListNode> ?listNode .
}
GRAPH <http://www.ontotext.com/explicit> {
    ?listNode <http://www.w3.org/2000/01/rdf-schema#label> ?listNodeLabel .
}
}
}

This is the main query result:

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix sesame: <http://www.openrdf.org/schema/sesame#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix fn: <http://www.w3.org/2005/xpath-functions#> .

<http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw> <http://www.knora.org/ontology/knora-base#isMainResource> "true"^^xsd:boolean ;
	a <http://www.knora.org/ontology/knora-base#Resource> , <http://www.knora.org/ontology/0001/anything#Thing> ;
	rdfs:label "testding" ;
	<http://www.knora.org/ontology/knora-base#isDeleted> "false"^^xsd:boolean ;
	<http://www.knora.org/ontology/knora-base#creationDate> "2018-05-28T15:52:03.897Z"^^xsd:dateTimeStamp ;
	<http://www.knora.org/ontology/knora-base#hasPermissions> "CR knora-base:Creator|M knora-base:ProjectMember|V knora-base:KnownUser|RV knora-base:UnknownUser" ;
	<http://www.knora.org/ontology/knora-base#attachedToProject> <http://rdfh.ch/projects/0001> ;
	<http://www.knora.org/ontology/knora-base#attachedToUser> <http://rdfh.ch/users/BhkfBc3hTeS_IDo-JgXRbQ> ;
	<http://www.knora.org/ontology/0001/anything#hasListItem> <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/XAhEeE3kSVqM4JPGdLt4Ew> ;
	<http://www.knora.org/ontology/0001/anything#hasOtherListItem> <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/j8VQjbD0RsyxpyuvfFJCDA> ;
	<http://www.knora.org/ontology/0001/anything#hasOtherThing> <http://rdfh.ch/0001/0C-0L1kORryKzJAJxxRyRQ> ;
	<http://www.knora.org/ontology/0001/anything#hasOtherThingValue> <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/uvRVxzL1RD-t9VIQ1TpfUw> ;
	<http://www.knora.org/ontology/0001/anything#hasText> <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/SZyeLLmOTcCCuS3B0VksHQ> ;
	<http://www.knora.org/ontology/0001/anything#hasRichtext> <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/rvB4eQ5MTF-Qxq0YgkwaDg> ;
	<http://www.knora.org/ontology/0001/anything#hasDate> <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/-rG4F5FTTu2iB5mTBPVn5Q> ;
	<http://www.knora.org/ontology/0001/anything#hasInteger> <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/dJ1ES8QTQNepFKF5-EAqdg> ;
	<http://www.knora.org/ontology/0001/anything#hasDecimal> <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/bXMwnrHvQH2DMjOFrGmNzg> ;
	<http://www.knora.org/ontology/0001/anything#hasBoolean> <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/IN4R19yYR0ygi3K2VEHpUQ> ;
	<http://www.knora.org/ontology/0001/anything#hasUri> <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/uBAmWuRhR-eo1u1eP7qqNg> ;
	<http://www.knora.org/ontology/0001/anything#hasInterval> <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/RbDKPKHWTC-0lkRKae-E6A> ;
	<http://www.knora.org/ontology/0001/anything#hasColor> <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/TAziKNP8QxuyhC4Qf9-b6w> ;
	<http://www.knora.org/ontology/knora-base#hasValue> <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/dJ1ES8QTQNepFKF5-EAqdg> .

<http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/dJ1ES8QTQNepFKF5-EAqdg> a <http://www.knora.org/ontology/knora-base#IntValue> ;
	<http://www.knora.org/ontology/knora-base#isDeleted> "false"^^xsd:boolean ;
	<http://www.knora.org/ontology/knora-base#valueCreationDate> "2018-05-28T15:52:03.897Z"^^xsd:dateTimeStamp ;
	<http://www.knora.org/ontology/knora-base#valueHasInteger> "1"^^xsd:integer ;
	<http://www.knora.org/ontology/knora-base#valueHasOrder> "0"^^xsd:integer ;
	<http://www.knora.org/ontology/knora-base#valueHasString> "1" ;
	<http://www.knora.org/ontology/knora-base#hasPermissions> "CR knora-base:Creator|M knora-base:ProjectMember|V knora-base:KnownUser|RV knora-base:UnknownUser" ;
	<http://www.knora.org/ontology/knora-base#attachedToUser> <http://rdfh.ch/users/BhkfBc3hTeS_IDo-JgXRbQ> .

<http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw> <http://www.knora.org/ontology/knora-base#hasValue> <http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/SZyeLLmOTcCCuS3B0VksHQ> .

<http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/SZyeLLmOTcCCuS3B0VksHQ> a <http://www.knora.org/ontology/knora-base#TextValue> ;
	<http://www.knora.org/ontology/knora-base#isDeleted> "false"^^xsd:boolean ;
	<http://www.knora.org/ontology/knora-base#valueCreationDate> "2018-05-28T15:52:03.897Z"^^xsd:dateTimeStamp ;
	<http://www.knora.org/ontology/knora-base#valueHasOrder> "0"^^xsd:integer ;
	<http://www.knora.org/ontology/knora-base#valueHasString> "test" ;
	<http://www.knora.org/ontology/knora-base#hasPermissions> "CR knora-base:Creator|M knora-base:ProjectMember|V knora-base:KnownUser|RV knora-base:UnknownUser" ;
	<http://www.knora.org/ontology/knora-base#attachedToUser> <http://rdfh.ch/users/BhkfBc3hTeS_IDo-JgXRbQ> .

I think all that is correct. But the responder returns ForbiddenResource. The requested resource and its values all have V knora-base:KnownUser permission, and the test is running as a user in the anything project, so I don't understand.

@tobiasschweizer
Copy link
Contributor

@benjamingeer Maybe there is something going wrong when it checks for the presence of all queried dependent resources and values after permission checking.

// for each main resource check if all dependent resources and value objects are still present after permission checking
                    // this ensures that the user has sufficient permissions on the whole query path
                    queryResWithFullQueryPath: Map[IRI, ConstructResponseUtilV2.ResourceWithValueRdfData] = queryResultsSep.foldLeft(Map.empty[IRI, ConstructResponseUtilV2.ResourceWithValueRdfData]) {
                        case (acc: Map[IRI, ConstructResponseUtilV2.ResourceWithValueRdfData], (mainResIri: IRI, values: ConstructResponseUtilV2.ResourceWithValueRdfData)) =>

                            // check for presence of dependent resources:  dependentResourceIrisPerMainResource, allResourceIrisFromTypeInspection
                            val expectedDependentResources: Set[IRI] = dependentResourceIrisPerMainResource(mainResIri) ++ allResourceIrisFromTypeInspection

                            // check for presence of value objects: valueObjectIrisPerMainResource
                            val expectedValueObjects: Set[IRI] = valueObjectIrisPerMainResource(mainResIri).values.flatten.toSet

                            // value property assertions for the current main resource
                            val valuePropAssertions: Map[IRI, Seq[ConstructResponseUtilV2.ValueRdfData]] = values.valuePropertyAssertions

                            // all the Iris of dependent resources and value objects contained in `valuePropAssertions`
                            val resAndValueObjIris: ResourceIrisAndValueObjectIris = traverseValuePropertyAssertions(valuePropAssertions)

                            // check if the client has sufficient permissions on all dependent resources present in the query path
                            val allDependentResources: Boolean = resAndValueObjIris.resourceIris.intersect(expectedDependentResources) == expectedDependentResources

                            // check if the client has sufficient permissions on all value objects Iris present in the query path
                            val allValueObjects: Boolean = resAndValueObjIris.valueObjectIris.intersect(expectedValueObjects) == expectedValueObjects

                            if (allDependentResources && allValueObjects) {
                                // sufficient permissions, include the main resource and its values
                                acc + (mainResIri -> values)
                            } else {
                                // insufficient permissions, skip the resource
                                acc
                            }
                    }

I will have a look at it on Monday.

@tobiasschweizer
Copy link
Contributor

tobiasschweizer commented Jun 4, 2018

@benjamingeer Ok, this is the problem:

if (allDependentResources && allValueObjects) {
                                // sufficient permissions, include the main resource and its values
                                acc + (mainResIri -> values)
                            } else {
                                // insufficient permissions, skip the resource
                                acc
                            }

allDependentResources && allValueObjects does not evaluate to true. This is because allDependentResources is false.

I think this line is the problem:

val expectedDependentResources: Set[IRI] = dependentResourceIrisPerMainResource(mainResIri) ++ allResourceIrisFromTypeInspection

It adds the IRI of the main resource to the collection of dependent resources. Just make sure it gets removed from that collection.

@tobiasschweizer
Copy link
Contributor

tobiasschweizer commented Jun 4, 2018

val expectedDependentResources: Set[IRI] = dependentResourceIrisPerMainResource(mainResIri) ++ allResourceIrisFromTypeInspection

Before, the main resource's Iri could not possibly have been contained in that collection because its IRI was not know (the main resource was represented by a variable only).

@tobiasschweizer
Copy link
Contributor

tobiasschweizer commented Jun 4, 2018

@benjamingeer

Now that I am thinking about it: adding allResourceIrisFromTypeInspection could be wrong if the linking prop is optional.

@tobiasschweizer
Copy link
Contributor

@benjamingeer I will add some more tests. I will get back to you in the early afternoon.

@benjamingeer
Copy link
Author

benjamingeer commented Jun 4, 2018

@tobiasschweizer I'm trying another approach: allow BIND in Gravsearch.

I have a test that doesn't work: the last test in SearchRouteV2R2RSpec, "perform a Gravsearch query for the pages of a book whose seqnum is lower than or equals 10, with the book as the main resource". I want it to return 10 pages as dependent resources inside the book. But it returns the book 10 times, each time with a single dependent resource, which is always the same page (the one with seqnum 10). Could you have a look?

@tobiasschweizer
Copy link
Contributor

tobiasschweizer commented Jun 4, 2018

this works:

PREFIX beol: <http://0.0.0.0:3333/ontology/0801/beol/simple/v2#>
PREFIX knora-api: <http://api.knora.org/ontology/knora-api/simple/v2#>

    CONSTRUCT {
        ?letter knora-api:isMainResource true .

        ?letter beol:creationDate ?date .

        ?letter ?linkingProp1 ?person1 .

        ?person1 beol:hasFamilyName ?familyName .


    } WHERE {
        ?letter a knora-api:Resource .
        ?letter a beol:letter .

        ?letter beol:creationDate ?date .

        beol:creationDate knora-api:objectType knora-api:Date .
        ?date a knora-api:Date .

        # testperson2
        ?letter ?linkingProp1 ?person1 .

        ?person1 a knora-api:Resource .

        ?linkingProp1 knora-api:objectType knora-api:Resource .
        FILTER(?linkingProp1 = beol:hasAuthor || ?linkingProp1 = beol:hasRecipient )

        ?person1 beol:hasFamilyName ?familyName .
        beol:hasFamilyName knora-api:objectType xsd:string .

        ?familyName a xsd:string .


    } ORDER BY ?date

result:

{
  "@id" : "http://rdfh.ch/0801/_B3lQa6tSymIq7_7SowBsA",
  "@type" : "beol:letter",
  "beol:creationDate" : {
    "@id" : "http://rdfh.ch/0801/_B3lQa6tSymIq7_7SowBsA/values/L2gv0paYSymiENk1c0fAAQ",
    "@type" : "knora-api:DateValue",
    "knora-api:dateValueHasCalendar" : "GREGORIAN",
    "knora-api:dateValueHasEndDay" : 4,
    "knora-api:dateValueHasEndEra" : "CE",
    "knora-api:dateValueHasEndMonth" : 6,
    "knora-api:dateValueHasEndYear" : 2018,
    "knora-api:dateValueHasStartDay" : 4,
    "knora-api:dateValueHasStartEra" : "CE",
    "knora-api:dateValueHasStartMonth" : 6,
    "knora-api:dateValueHasStartYear" : 2018,
    "knora-api:valueAsString" : "GREGORIAN:2018-06-04 CE"
  },
  "beol:hasAuthorValue" : {
    "@id" : "http://rdfh.ch/0801/_B3lQa6tSymIq7_7SowBsA/values/Cvp07eTqQQSnYdcvqlWW_g",
    "@type" : "knora-api:LinkValue",
    "knora-api:linkValueHasTarget" : {
      "@id" : "http://rdfh.ch/0801/VvYVIy-FSbOJBsh2d9ZFJw",
      "@type" : "beol:person",
      "beol:hasFamilyName" : {
        "@id" : "http://rdfh.ch/0801/VvYVIy-FSbOJBsh2d9ZFJw/values/5K24YxlwQ9OXcYjB0jRR4Q",
        "@type" : "knora-api:TextValue",
        "knora-api:valueAsString" : "Meier"
      },
      "rdfs:label" : "Testperson2"
    }
  },
  "beol:hasRecipientValue" : {
    "@id" : "http://rdfh.ch/0801/_B3lQa6tSymIq7_7SowBsA/values/DVqPKuBBSIauVqjUC7bNvA",
    "@type" : "knora-api:LinkValue",
    "knora-api:linkValueHasTarget" : {
      "@id" : "http://rdfh.ch/0801/H7s3FmuWTkaCXa54eFANOA",
      "@type" : "beol:person",
      "beol:hasFamilyName" : {
        "@id" : "http://rdfh.ch/0801/H7s3FmuWTkaCXa54eFANOA/values/7LhL_JdpTA-E0oQ1hdtPDQ",
        "@type" : "knora-api:TextValue",
        "knora-api:valueAsString" : "Muster"
      },
      "rdfs:label" : "Testperson1"
    }
  },
  "rdfs:label" : "Testbrief1",
  "@context" : {
    "rdf" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
    "rdfs" : "http://www.w3.org/2000/01/rdf-schema#",
    "knora-api" : "http://api.knora.org/ontology/knora-api/v2#",
    "beol" : "http://0.0.0.0:3333/ontology/0801/beol/v2#"
  }
}

@tobiasschweizer
Copy link
Contributor

this also works:

PREFIX beol: <http://0.0.0.0:3333/ontology/0801/beol/simple/v2#>
PREFIX knora-api: <http://api.knora.org/ontology/knora-api/simple/v2#>

    CONSTRUCT {
        ?letter knora-api:isMainResource true .

        ?letter beol:creationDate ?date .

        ?letter ?linkingProp1 ?person1 .

        ?person1 beol:hasFamilyName ?familyName .


    } WHERE {
        BIND(<http://rdfh.ch/0801/_B3lQa6tSymIq7_7SowBsA> AS ?letter)
        ?letter a knora-api:Resource .
        ?letter a beol:letter .



        ?letter beol:creationDate ?date .

        beol:creationDate knora-api:objectType knora-api:Date .
        ?date a knora-api:Date .

        # testperson2
        ?letter ?linkingProp1 ?person1 .

        ?person1 a knora-api:Resource .

        ?linkingProp1 knora-api:objectType knora-api:Resource .
        FILTER(?linkingProp1 = beol:hasAuthor || ?linkingProp1 = beol:hasRecipient )

        ?person1 beol:hasFamilyName ?familyName .
        beol:hasFamilyName knora-api:objectType xsd:string .

        ?familyName a xsd:string .


    } ORDER BY ?date

@benjamingeer
Copy link
Author

Now I understand. It's OK if we get one row of prequery results containing values for multiple dependent resources, because the main query doesn't actually need to know which value goes with which resource.

So I think in my example, the prequery should look like this. I removed the values of dependent resources from GROUP BY and ORDER BY, and added DISTINCT inside each GROUP_CONCAT (because otherwise there is a lot of redundancy in the query result).

SELECT DISTINCT ?book (GROUP_CONCAT(DISTINCT(?page); SEPARATOR='') AS ?pageConcat) (GROUP_CONCAT(DISTINCT(?seqnum); SEPARATOR='') AS ?seqnumConcat) (GROUP_CONCAT(DISTINCT(?title); SEPARATOR='') AS ?titleConcat) (GROUP_CONCAT(DISTINCT(?book__LinkValue); SEPARATOR='') AS ?book__LinkValueConcat)
WHERE {
BIND(<http://rdfh.ch/b6b5ff1eb703> AS ?book)
?book <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/knora-base#Resource> .
GRAPH <http://www.ontotext.com/explicit> {
    ?book <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?book <http://www.knora.org/ontology/0803/incunabula#title> ?title .
GRAPH <http://www.ontotext.com/explicit> {
    ?title <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?page <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/knora-base#Resource> .
GRAPH <http://www.ontotext.com/explicit> {
    ?page <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?page <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/0803/incunabula#page> .
?page <http://www.knora.org/ontology/knora-base#isPartOf> ?book .
?page <http://www.knora.org/ontology/knora-base#isPartOfValue> ?book__LinkValue .
GRAPH <http://www.ontotext.com/explicit> {
    ?book__LinkValue <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/knora-base#LinkValue> .
}
GRAPH <http://www.ontotext.com/explicit> {
    ?book__LinkValue <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
GRAPH <http://www.ontotext.com/explicit> {
    ?book__LinkValue <http://www.w3.org/1999/02/22-rdf-syntax-ns#subject> ?page .
}
GRAPH <http://www.ontotext.com/explicit> {
    ?book__LinkValue <http://www.w3.org/1999/02/22-rdf-syntax-ns#object> ?book .
}
?page <http://www.knora.org/ontology/0803/incunabula#seqnum> ?seqnum .
GRAPH <http://www.ontotext.com/explicit> {
    ?seqnum <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
GRAPH <http://www.ontotext.com/explicit> {
    ?seqnum <http://www.knora.org/ontology/knora-base#valueHasInteger> ?seqnum__valueHasInteger .
}
FILTER((?seqnum__valueHasInteger <= "10"^^<http://www.w3.org/2001/XMLSchema#integer>))
}

GROUP BY ?book
ORDER BY ASC(?book)
OFFSET 0
LIMIT 25

This prequery returns one row containing everything.

So I think that when we generate the prequery, we have to exclude variables from GROUP BY and ORDER BY if we know that they refer to values of dependent resources.

@benjamingeer
Copy link
Author

Ah now I see, the whole GROUP BY thing in the prequery was generated only because I had ORDER BY ?seqnum in the Gravsearch.

@tobiasschweizer
Copy link
Contributor

@benjamingeer

So I think that when we generate the prequery, we have to exclude variables from GROUP BY and ORDER BY if we know that they refer to values of dependent resources.

I think I had to add values to GROUP BY when the results should be sorted (ORDER BY). That did not take effect when the variable representing the value was not included in the GROUP BY statement.

… ORDER BY, ensure subject is main resource.
@tobiasschweizer
Copy link
Contributor

@benjamingeer

val incomingLinks = incomingLinksForResource(resourceIri).filterNot {
                case (incomingResIri: IRI, assertions: ResourceWithValueRdfData) =>
                    alreadyTraversed(incomingResIri) || flatResourcesWithValues(incomingResIri).isMainResource
            }.flatMap {
                case (incomingResIri: IRI, assertions: ResourceWithValueRdfData) =>
                    assertions.valuePropertyAssertions
            }

I think this flatMap is total bogus. If there are several instances of the same property, they will just be overwritten by whatever is the last value. So I have to change this to a foldLeft.

@tobiasschweizer
Copy link
Contributor

@benjamingeer How is that?

{
  "@id" : "http://rdfh.ch/b6b5ff1eb703",
  "@type" : "incunabula:book",
  "incunabula:title" : [ {
    "@id" : "http://rdfh.ch/b6b5ff1eb703/values/e6d1cf0dcf0e",
    "@type" : "knora-api:TextValue",
    "knora-api:valueAsString" : "[Das] Narrenschiff (lat.)"
  }, {
    "@id" : "http://rdfh.ch/b6b5ff1eb703/values/a9fb2247cf0e",
    "@type" : "knora-api:TextValue",
    "knora-api:valueAsString" : "Stultifera navis (...)"
  } ],
  "knora-api:hasIncomingLink" : [ {
    "@id" : "http://rdfh.ch/54d8597eb803/values/0b6bdaa2-7444-44ec-9c80-cc04c020742a",
    "@type" : "knora-api:LinkValue",
    "knora-api:linkValueHasSource" : {
      "@id" : "http://rdfh.ch/54d8597eb803",
      "@type" : "incunabula:page",
      "incunabula:partOfValue" : {
        "@id" : "http://rdfh.ch/54d8597eb803/values/0b6bdaa2-7444-44ec-9c80-cc04c020742a",
        "@type" : "knora-api:LinkValue",
        "knora-api:linkValueHasTargetIri" : {
          "@id" : "http://rdfh.ch/b6b5ff1eb703"
        }
      },
      "incunabula:seqnum" : {
        "@id" : "http://rdfh.ch/54d8597eb803/values/be90332ddf0e",
        "@type" : "knora-api:IntValue",
        "knora-api:intValueAsInt" : 6
      },
      "rdfs:label" : "a2v"
    }
  }, {
    "@id" : "http://rdfh.ch/68ef9568b903/values/58713048-3e67-4951-806d-fbfcc8ccb79b",
    "@type" : "knora-api:LinkValue",
    "knora-api:linkValueHasSource" : {
      "@id" : "http://rdfh.ch/68ef9568b903",
      "@type" : "incunabula:page",
      "incunabula:partOfValue" : {
        "@id" : "http://rdfh.ch/68ef9568b903/values/58713048-3e67-4951-806d-fbfcc8ccb79b",
        "@type" : "knora-api:LinkValue",
        "knora-api:linkValueHasTargetIri" : {
          "@id" : "http://rdfh.ch/b6b5ff1eb703"
        }
      },
      "incunabula:seqnum" : {
        "@id" : "http://rdfh.ch/68ef9568b903/values/ee2c66c2e20e",
        "@type" : "knora-api:IntValue",
        "knora-api:intValueAsInt" : 10
      },
      "rdfs:label" : "a4v"
    }
  }, {
    "@id" : "http://rdfh.ch/05c7acceb703/values/ad6b1ac8-7727-4893-9a30-4de4666b4780",
    "@type" : "knora-api:LinkValue",
    "knora-api:linkValueHasSource" : {
      "@id" : "http://rdfh.ch/05c7acceb703",
      "@type" : "incunabula:page",
      "incunabula:partOfValue" : {
        "@id" : "http://rdfh.ch/05c7acceb703/values/ad6b1ac8-7727-4893-9a30-4de4666b4780",
        "@type" : "knora-api:LinkValue",
        "knora-api:linkValueHasTargetIri" : {
          "@id" : "http://rdfh.ch/b6b5ff1eb703"
        }
      },
      "incunabula:seqnum" : {
        "@id" : "http://rdfh.ch/05c7acceb703/values/9a9b4d7ddc0e",
        "@type" : "knora-api:IntValue",
        "knora-api:intValueAsInt" : 3
      },
      "rdfs:label" : "a1r; Titelblatt, recto"
    }
  }, {
    "@id" : "http://rdfh.ch/8fd2ca43b803/values/38ac4bc2-a6d1-4d27-b22e-e793bfcdf9ff",
    "@type" : "knora-api:LinkValue",
    "knora-api:linkValueHasSource" : {
      "@id" : "http://rdfh.ch/8fd2ca43b803",
      "@type" : "incunabula:page",
      "incunabula:partOfValue" : {
        "@id" : "http://rdfh.ch/8fd2ca43b803/values/38ac4bc2-a6d1-4d27-b22e-e793bfcdf9ff",
        "@type" : "knora-api:LinkValue",
        "knora-api:linkValueHasTargetIri" : {
          "@id" : "http://rdfh.ch/b6b5ff1eb703"
        }
      },
      "incunabula:seqnum" : {
        "@id" : "http://rdfh.ch/8fd2ca43b803/values/b2e9e647de0e",
        "@type" : "knora-api:IntValue",
        "knora-api:intValueAsInt" : 5
      },
      "rdfs:label" : "a2r"
    }
  }, {
    "@id" : "http://rdfh.ch/40c11d94b703/values/3ee2ce17-6b6e-4a9c-b747-91d31375ab8e",
    "@type" : "knora-api:LinkValue",
    "knora-api:linkValueHasSource" : {
      "@id" : "http://rdfh.ch/40c11d94b703",
      "@type" : "incunabula:page",
      "incunabula:partOfValue" : {
        "@id" : "http://rdfh.ch/40c11d94b703/values/3ee2ce17-6b6e-4a9c-b747-91d31375ab8e",
        "@type" : "knora-api:LinkValue",
        "knora-api:linkValueHasTargetIri" : {
          "@id" : "http://rdfh.ch/b6b5ff1eb703"
        }
      },
      "incunabula:seqnum" : {
        "@id" : "http://rdfh.ch/40c11d94b703/values/8ef40098db0e",
        "@type" : "knora-api:IntValue",
        "knora-api:intValueAsInt" : 2
      },
      "rdfs:label" : "Vorsatzblatt, verso"
    }
  }, {
    "@id" : "http://rdfh.ch/dee377f3b803/values/2a19b42d-df5b-4289-a455-46094a438dc0",
    "@type" : "knora-api:LinkValue",
    "knora-api:linkValueHasSource" : {
      "@id" : "http://rdfh.ch/dee377f3b803",
      "@type" : "incunabula:page",
      "incunabula:partOfValue" : {
        "@id" : "http://rdfh.ch/dee377f3b803/values/2a19b42d-df5b-4289-a455-46094a438dc0",
        "@type" : "knora-api:LinkValue",
        "knora-api:linkValueHasTargetIri" : {
          "@id" : "http://rdfh.ch/b6b5ff1eb703"
        }
      },
      "incunabula:seqnum" : {
        "@id" : "http://rdfh.ch/dee377f3b803/values/d6deccf7e00e",
        "@type" : "knora-api:IntValue",
        "knora-api:intValueAsInt" : 8
      },
      "rdfs:label" : "a3v"
    }
  }, {
    "@id" : "http://rdfh.ch/cacc3b09b803/values/b3e7e7c5-b5ac-4efc-9279-067f8ec61a2b",
    "@type" : "knora-api:LinkValue",
    "knora-api:linkValueHasSource" : {
      "@id" : "http://rdfh.ch/cacc3b09b803",
      "@type" : "incunabula:page",
      "incunabula:partOfValue" : {
        "@id" : "http://rdfh.ch/cacc3b09b803/values/b3e7e7c5-b5ac-4efc-9279-067f8ec61a2b",
        "@type" : "knora-api:LinkValue",
        "knora-api:linkValueHasTargetIri" : {
          "@id" : "http://rdfh.ch/b6b5ff1eb703"
        }
      },
      "incunabula:seqnum" : {
        "@id" : "http://rdfh.ch/cacc3b09b803/values/a6429a62dd0e",
        "@type" : "knora-api:IntValue",
        "knora-api:intValueAsInt" : 4
      },
      "rdfs:label" : "a1v; Titelblatt, verso"
    }
  }, {
    "@id" : "http://rdfh.ch/a3e9062eb903/values/a3446ea8-918e-488f-977a-fc8b8de9b003",
    "@type" : "knora-api:LinkValue",
    "knora-api:linkValueHasSource" : {
      "@id" : "http://rdfh.ch/a3e9062eb903",
      "@type" : "incunabula:page",
      "incunabula:partOfValue" : {
        "@id" : "http://rdfh.ch/a3e9062eb903/values/a3446ea8-918e-488f-977a-fc8b8de9b003",
        "@type" : "knora-api:LinkValue",
        "knora-api:linkValueHasTargetIri" : {
          "@id" : "http://rdfh.ch/b6b5ff1eb703"
        }
      },
      "incunabula:seqnum" : {
        "@id" : "http://rdfh.ch/a3e9062eb903/values/e28519dde10e",
        "@type" : "knora-api:IntValue",
        "knora-api:intValueAsInt" : 9
      },
      "rdfs:label" : "a4r"
    }
  }, {
    "@id" : "http://rdfh.ch/19dee8b8b803/values/f27b06da-6576-445d-b771-22664a397913",
    "@type" : "knora-api:LinkValue",
    "knora-api:linkValueHasSource" : {
      "@id" : "http://rdfh.ch/19dee8b8b803",
      "@type" : "incunabula:page",
      "incunabula:partOfValue" : {
        "@id" : "http://rdfh.ch/19dee8b8b803/values/f27b06da-6576-445d-b771-22664a397913",
        "@type" : "knora-api:LinkValue",
        "knora-api:linkValueHasTargetIri" : {
          "@id" : "http://rdfh.ch/b6b5ff1eb703"
        }
      },
      "incunabula:seqnum" : {
        "@id" : "http://rdfh.ch/19dee8b8b803/values/ca378012e00e",
        "@type" : "knora-api:IntValue",
        "knora-api:intValueAsInt" : 7
      },
      "rdfs:label" : "a3r"
    }
  }, {
    "@id" : "http://rdfh.ch/7bbb8e59b703/values/448b77cc-b489-40af-83a5-7373d76b4443",
    "@type" : "knora-api:LinkValue",
    "knora-api:linkValueHasSource" : {
      "@id" : "http://rdfh.ch/7bbb8e59b703",
      "@type" : "incunabula:page",
      "incunabula:partOfValue" : {
        "@id" : "http://rdfh.ch/7bbb8e59b703/values/448b77cc-b489-40af-83a5-7373d76b4443",
        "@type" : "knora-api:LinkValue",
        "knora-api:linkValueHasTargetIri" : {
          "@id" : "http://rdfh.ch/b6b5ff1eb703"
        }
      },
      "incunabula:seqnum" : {
        "@id" : "http://rdfh.ch/7bbb8e59b703/values/824db4b2da0e",
        "@type" : "knora-api:IntValue",
        "knora-api:intValueAsInt" : 1
      },
      "rdfs:label" : "Vorsatzblatt, recto"
    }
  } ],
  "rdfs:label" : "[Das] Narrenschiff (lat.)",
  "@context" : {
    "rdf" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
    "rdfs" : "http://www.w3.org/2000/01/rdf-schema#",
    "knora-api" : "http://api.knora.org/ontology/knora-api/v2#",
    "incunabula" : "http://0.0.0.0:3333/ontology/0803/incunabula/v2#"
  }
}

@benjamingeer
Copy link
Author

@tobiasschweizer Looks great!

}

if (incomingLinks.nonEmpty) {
// link value assertions that point to this resource
val incomingLinkAssertions: Map[IRI, Seq[ValueRdfData]] = referringResources.values.foldLeft(Map.empty[IRI, Seq[ValueRdfData]]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@benjamingeer This collects different instances of the same property rather than just overwriting them.

|
| ?title a xsd:string .
|
| FILTER(?title = "Zeitglöcklein des Lebens und Leidens Christi")
Copy link
Author

@benjamingeer benjamingeer Jun 4, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so beautiful, it even has Zeitglöcklein in it. 😊

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gravsearch is just a fake, it will always return Zeitglöcklein. So this is the only possible test case.

@benjamingeer benjamingeer changed the title Gravsearch enhancements Gravsearch enhancements and fixes Jun 4, 2018
@tobiasschweizer
Copy link
Contributor

@benjamingeer Consider the following query:

PREFIX beol: <http://0.0.0.0:3333/ontology/0801/beol/simple/v2#>
PREFIX knora-api: <http://api.knora.org/ontology/knora-api/simple/v2#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

    CONSTRUCT {
        ?letter knora-api:isMainResource true .

        ?letter beol:creationDate ?date .

        ?letter ?linkingProp1  ?person1 .

        ?person1 beol:hasFamilyName ?name .

    } WHERE {
        ?letter a knora-api:Resource .
        ?letter a beol:letter .

        ?letter beol:creationDate ?date .

        beol:creationDate knora-api:objectType knora-api:Date .
        ?date a knora-api:Date .

        ?letter ?linkingProp1 ?person1 .

        ?person1 a knora-api:Resource .

        ?linkingProp1 knora-api:objectType knora-api:Resource .
        FILTER(?linkingProp1 = beol:hasAuthor || ?linkingProp1 = beol:hasRecipient )

      	OPTIONAL {
        ?person1 beol:hasFamilyName ?name .

        beol:hasFamilyName knora-api:objectType xsd:string .
        ?name a xsd:string .

        FILTER(?name = "Meier")
    }

    } ORDER BY ?date

The prequery looks like follows:

 SELECT DISTINCT ?letter (GROUP_CONCAT(DISTINCT(?person1); SEPARATOR='') AS ?person1Concat) (GROUP_CONCAT(DISTINCT(?date); SEPARATOR='') AS ?dateConcat) (GROUP_CONCAT(DISTINCT(?name); SEPARATOR='') AS ?nameConcat) (GROUP_CONCAT(DISTINCT(?person1__LinkValue); SEPARATOR='') AS ?person1__LinkValueConcat)
 WHERE {
 ?letter <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/knora-base#Resource> .
 GRAPH <http://www.ontotext.com/explicit> {
     ?letter <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
 }
 ?letter <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/0801/beol#letter> .
 ?letter <http://www.knora.org/ontology/0801/beol#creationDate> ?date .
 GRAPH <http://www.ontotext.com/explicit> {
     ?date <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
 }
 ?letter ?linkingProp1 ?person1 .
 ?letter ?linkingProp1__hasLinkToValue ?person1__LinkValue .
 GRAPH <http://www.ontotext.com/explicit> {
     ?person1__LinkValue <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/knora-base#LinkValue> .
 }
 GRAPH <http://www.ontotext.com/explicit> {
     ?person1__LinkValue <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
 }
 GRAPH <http://www.ontotext.com/explicit> {
     ?person1__LinkValue <http://www.w3.org/1999/02/22-rdf-syntax-ns#subject> ?letter .
 }
 GRAPH <http://www.ontotext.com/explicit> {
     ?person1__LinkValue <http://www.w3.org/1999/02/22-rdf-syntax-ns#object> ?person1 .
 }
 ?person1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/knora-base#Resource> .
 GRAPH <http://www.ontotext.com/explicit> {
     ?person1 <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
 }
 OPTIONAL {
 ?person1 <http://www.knora.org/ontology/0801/beol#hasFamilyName> ?name .
 GRAPH <http://www.ontotext.com/explicit> {
     ?name <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
 }
 }
 FILTER((((?linkingProp1 = <http://www.knora.org/ontology/0801/beol#hasAuthor>) && (?linkingProp1__hasLinkToValue = <http://www.knora.org/ontology/0801/beol#hasAuthorValue>)) || ((?linkingProp1 = <http://www.knora.org/ontology/0801/beol#hasRecipient>) && (?linkingProp1__hasLinkToValue = <http://www.knora.org/ontology/0801/beol#hasRecipientValue>))))
 GRAPH <http://www.ontotext.com/explicit> {
     ?date <http://www.knora.org/ontology/knora-base#valueHasStartJDN> ?date__valueHasStartJDN .
 }
 }
 
 GROUP BY ?letter ?date__valueHasStartJDN
 ORDER BY ASC(?date__valueHasStartJDN) ASC(?letter)
 OFFSET 0
 LIMIT 25

The filter inside the OPTIONAL is not regenerated in the prequery.

The result is this:

{
  "@id" : "http://rdfh.ch/0801/_B3lQa6tSymIq7_7SowBsA",
  "@type" : "beol:letter",
  "beol:creationDate" : {
    "@id" : "http://rdfh.ch/0801/_B3lQa6tSymIq7_7SowBsA/values/L2gv0paYSymiENk1c0fAAQ",
    "@type" : "knora-api:DateValue",
    "knora-api:dateValueHasCalendar" : "GREGORIAN",
    "knora-api:dateValueHasEndDay" : 4,
    "knora-api:dateValueHasEndEra" : "CE",
    "knora-api:dateValueHasEndMonth" : 6,
    "knora-api:dateValueHasEndYear" : 2018,
    "knora-api:dateValueHasStartDay" : 4,
    "knora-api:dateValueHasStartEra" : "CE",
    "knora-api:dateValueHasStartMonth" : 6,
    "knora-api:dateValueHasStartYear" : 2018,
    "knora-api:valueAsString" : "GREGORIAN:2018-06-04 CE"
  },
  "beol:hasAuthorValue" : {
    "@id" : "http://rdfh.ch/0801/_B3lQa6tSymIq7_7SowBsA/values/Cvp07eTqQQSnYdcvqlWW_g",
    "@type" : "knora-api:LinkValue",
    "knora-api:linkValueHasTarget" : {
      "@id" : "http://rdfh.ch/0801/VvYVIy-FSbOJBsh2d9ZFJw",
      "@type" : "beol:person",
      "beol:hasFamilyName" : {
        "@id" : "http://rdfh.ch/0801/VvYVIy-FSbOJBsh2d9ZFJw/values/5K24YxlwQ9OXcYjB0jRR4Q",
        "@type" : "knora-api:TextValue",
        "knora-api:valueAsString" : "Meier"
      },
      "rdfs:label" : "Testperson2"
    }
  },
  "beol:hasRecipientValue" : {
    "@id" : "http://rdfh.ch/0801/_B3lQa6tSymIq7_7SowBsA/values/DVqPKuBBSIauVqjUC7bNvA",
    "@type" : "knora-api:LinkValue",
    "knora-api:linkValueHasTarget" : {
      "@id" : "http://rdfh.ch/0801/H7s3FmuWTkaCXa54eFANOA",
      "@type" : "beol:person",
      "beol:hasFamilyName" : {
        "@id" : "http://rdfh.ch/0801/H7s3FmuWTkaCXa54eFANOA/values/7LhL_JdpTA-E0oQ1hdtPDQ",
        "@type" : "knora-api:TextValue",
        "knora-api:valueAsString" : "Muster"
      },
      "rdfs:label" : "Testperson1"
    }
  },
  "rdfs:label" : "Testbrief1",
  "@context" : {
    "rdf" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
    "rdfs" : "http://www.w3.org/2000/01/rdf-schema#",
    "knora-api" : "http://api.knora.org/ontology/knora-api/v2#",
    "beol" : "http://0.0.0.0:3333/ontology/0801/beol/v2#"
  }
}

I would expect that the name is only returned if it is "Meier". But therefore we need the filter.

@benjamingeer
Copy link
Author

Looks like a bug. :)

@tobiasschweizer
Copy link
Contributor

Looks like a bug. :)

I think so. Maybe transformFilter is never called for a filter inside an OPTIONAL.

@tobiasschweizer
Copy link
Contributor

@benjamingeer I tried the query from #870 (comment) and it worked. We should add it as a test.

Thanks for fixing this!

@benjamingeer
Copy link
Author

We should add it as a test.

I've already added it in GravsearchParserV2Spec.

@tobiasschweizer
Copy link
Contributor

@benjamingeer I also added it as an e2e tests.

Doppelt genäht hält besser.

@benjamingeer
Copy link
Author

@tobiasschweizer Can I merge this now?

Copy link
Contributor

@tobiasschweizer tobiasschweizer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, thx!

@benjamingeer benjamingeer merged commit 4858a9b into develop Jun 5, 2018
@benjamingeer benjamingeer deleted the wip/gravsearch-standoff branch June 5, 2018 11:42
@benjamingeer benjamingeer mentioned this pull request Sep 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API/V2 enhancement improve existing code or new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants