Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
fix(search): Return matching sub-nodes when searching for list label (D…
…EV-158) (#1973)

* Return matching sub-nodes when searching for list label

* add test

* remove code smells

* rename value names
  • Loading branch information
irinaschubert committed Jan 10, 2022
1 parent c78e252 commit 7e8c759
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 34 deletions.
82 changes: 78 additions & 4 deletions test_data/all_data/books-data.ttl
Expand Up @@ -30,6 +30,26 @@
knora-base:hasPermissions "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser" ;
knora-base:attachedToUser <http://rdfh.ch/users/BhkfBc3hTeS_IDo-JgXRbQ> .

<http://rdfh.ch/0001/book-instance-03/values/has-title-value-03>
a knora-base:TextValue ;
knora-base:valueHasUUID "IN4R19yYR0ygi3K2VEHpUQ"^^xsd:string ;
knora-base:isDeleted false ;
knora-base:valueCreationDate "2018-05-29T16:42:04.381Z"^^xsd:dateTime ;
knora-base:valueHasOrder 0 ;
knora-base:valueHasString "Lord of the Rings" ;
knora-base:hasPermissions "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser" ;
knora-base:attachedToUser <http://rdfh.ch/users/BhkfBc3hTeS_IDo-JgXRbQ> .

<http://rdfh.ch/0001/book-instance-04/values/has-title-value-04>
a knora-base:TextValue ;
knora-base:valueHasUUID "IN4R19yYR0ygi3K2VEHpUQ"^^xsd:string ;
knora-base:isDeleted false ;
knora-base:valueCreationDate "2018-05-29T16:42:04.381Z"^^xsd:dateTime ;
knora-base:valueHasOrder 0 ;
knora-base:valueHasString "Treasure Island" ;
knora-base:hasPermissions "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser" ;
knora-base:attachedToUser <http://rdfh.ch/users/BhkfBc3hTeS_IDo-JgXRbQ> .

<http://rdfh.ch/0001/page-instance-01/values/has-page-number-value-01>
a knora-base:IntValue ;
knora-base:valueHasUUID "SZyeLLmOTcCCuS3B0VksHQ"^^xsd:string ;
Expand All @@ -51,6 +71,26 @@
knora-base:valueCreationDate "2018-05-29T16:42:04.381Z"^^xsd:dateTime;
knora-base:hasPermissions "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser" .

<http://rdfh.ch/0001/book-instance-03/values/has-list-value-02> a knora-base:ListValue;
knora-base:valueHasUUID "list_value_fantasy"^^xsd:string;
knora-base:isDeleted false;
knora-base:attachedToUser <http://rdfh.ch/users/BhkfBc3hTeS_IDo-JgXRbQ>;
knora-base:valueHasString "http://rdfh.ch/lists/0001/ynm02-04";
knora-base:valueHasOrder 0;
knora-base:valueHasListNode <http://rdfh.ch/lists/0001/ynm02-04>;
knora-base:valueCreationDate "2018-05-29T16:42:04.381Z"^^xsd:dateTime;
knora-base:hasPermissions "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser" .

<http://rdfh.ch/0001/book-instance-04/values/has-list-value-03> a knora-base:ListValue;
knora-base:valueHasUUID "list_value_adventure"^^xsd:string;
knora-base:isDeleted false;
knora-base:attachedToUser <http://rdfh.ch/users/BhkfBc3hTeS_IDo-JgXRbQ>;
knora-base:valueHasString "http://rdfh.ch/lists/0001/ynm02-05";
knora-base:valueHasOrder 0;
knora-base:valueHasListNode <http://rdfh.ch/lists/0001/ynm02-05>;
knora-base:valueCreationDate "2018-05-29T16:42:04.381Z"^^xsd:dateTime;
knora-base:hasPermissions "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser" .

<http://rdfh.ch/0001/book-instance-01>
a books:Book ;
knora-base:attachedToUser <http://rdfh.ch/users/9XBCrDV3SRa7kS1WwynB4Q> ;
Expand All @@ -72,6 +112,28 @@
rdfs:label "instance of a book with a list value" ;
knora-base:isDeleted false .

<http://rdfh.ch/0001/book-instance-03>
a books:Book ;
knora-base:attachedToUser <http://rdfh.ch/users/9XBCrDV3SRa7kS1WwynB4Q> ;
knora-base:attachedToProject <http://rdfh.ch/projects/0001> ;
knora-base:hasPermissions "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser" ;
knora-base:creationDate "2019-11-29T10:00:00.673298Z"^^xsd:dateTime ;
books:hasTitle <http://rdfh.ch/0001/book-instance-03/values/has-title-value-03> ;
books:hasTextType <http://rdfh.ch/0001/book-instance-03/values/has-list-value-02> ;
rdfs:label "Lord of the Rings" ;
knora-base:isDeleted false .

<http://rdfh.ch/0001/book-instance-04>
a books:Book ;
knora-base:attachedToUser <http://rdfh.ch/users/9XBCrDV3SRa7kS1WwynB4Q> ;
knora-base:attachedToProject <http://rdfh.ch/projects/0001> ;
knora-base:hasPermissions "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser" ;
knora-base:creationDate "2019-11-29T10:00:00.673298Z"^^xsd:dateTime ;
books:hasTitle <http://rdfh.ch/0001/book-instance-04/values/has-title-value-04> ;
books:hasTextType <http://rdfh.ch/0001/book-instance-04/values/has-list-value-03> ;
rdfs:label "Treasure Island" ;
knora-base:isDeleted false .

<http://rdfh.ch/0001/page-instance-01>
a books:Page ;
knora-base:attachedToUser <http://rdfh.ch/users/9XBCrDV3SRa7kS1WwynB4Q> ;
Expand All @@ -96,7 +158,22 @@
knora-base:hasRootNode <http://rdfh.ch/lists/0001/ynm02> ;
knora-base:listNodePosition 0 ;
rdfs:label "Novel"@en ;
rdfs:label "Roman"@de .
rdfs:label "Roman"@de ;
knora-base:hasSubListNode <http://rdfh.ch/lists/0001/ynm02-04> , <http://rdfh.ch/lists/0001/ynm02-05> .

<http://rdfh.ch/lists/0001/ynm02-04> a knora-base:ListNode ;
knora-base:listNodeName "fantasy" ;
knora-base:hasRootNode <http://rdfh.ch/lists/0001/ynm02> ;
knora-base:listNodePosition 0 ;
rdfs:label "Fantasy novel"@en ;
rdfs:label "Fantasyroman"@de .

<http://rdfh.ch/lists/0001/ynm02-05> a knora-base:ListNode ;
knora-base:listNodeName "adventure" ;
knora-base:hasRootNode <http://rdfh.ch/lists/0001/ynm02> ;
knora-base:listNodePosition 1 ;
rdfs:label "Adventure novel"@en ;
rdfs:label "abenteuerroman"@de .

<http://rdfh.ch/lists/0001/ynm02-02> a knora-base:ListNode ;
knora-base:listNodeName "short-story" ;
Expand All @@ -111,6 +188,3 @@
knora-base:listNodePosition 2 ;
rdfs:label "Non fiction"@en ;
rdfs:label "Sachbuch"@de .



Expand Up @@ -103,12 +103,16 @@ WHERE {
}

OPTIONAL {
?matchingSubject a ?valueObjectType .
# get all list nodes that match the search term
?matchingSubject a knora-base:ListNode .

?valueObjectType rdfs:subClassOf *knora-base:ListNode .
# get sub-node(s) of that node(s) (recursively)
?matchingSubject knora-base:hasSubListNode* ?subListNode .

?listValue knora-base:valueHasListNode ?matchingSubject .
# get all values that point to the node(s) and sub-node(s)
?listValue knora-base:valueHasListNode ?subListNode .

# get all resources that have that values
?subjectWithListValue ?predicate ?listValue .

FILTER NOT EXISTS {
Expand Down
Expand Up @@ -260,7 +260,30 @@ class SearchResponderV2Spec extends CoreSpec() with ImplicitSender {

expectMsgPF(timeout) { case response: ReadResourcesSequenceV2 =>
compareReadResourcesSequenceV2Response(
expected = searchResponderV2SpecFullData.fulltextSearchForListNodeLabel,
expected = searchResponderV2SpecFullData.expectedResultFulltextSearchForListNodeLabel,
received = response
)
}
}

"search for list label and find sub-nodes" in {

responderManager ! FulltextSearchRequestV2(
searchValue = "novel",
offset = 0,
limitToProject = None,
limitToResourceClass = None,
limitToStandoffClass = None,
returnFiles = false,
targetSchema = ApiV2Complex,
schemaOptions = SchemaOptions.ForStandoffWithTextValues,
featureFactoryConfig = defaultFeatureFactoryConfig,
requestingUser = SharedTestDataADM.anythingUser1
)

expectMsgPF(timeout) { case response: ReadResourcesSequenceV2 =>
compareReadResourcesSequenceV2Response(
expected = searchResponderV2SpecFullData.expectedResultFulltextSearchForListNodeLabelWithSubnodes,
received = response
)
}
Expand Down
Expand Up @@ -18,6 +18,41 @@ class SearchResponderV2SpecFullData(implicit stringFormatter: StringFormatter) {

implicit lazy val system: ActorSystem = ActorSystem("webapi")

val booksBookIri: String = "http://www.knora.org/ontology/0001/books#Book"
val booksHasTextType: String = "http://www.knora.org/ontology/0001/books#hasTextType"
val testUser1: String = "http://rdfh.ch/users/9XBCrDV3SRa7kS1WwynB4Q"
val testUser2: String = "http://rdfh.ch/users/BhkfBc3hTeS_IDo-JgXRbQ"
val bookTemplateReadResource: ReadResourceV2 = ReadResourceV2(
label = "",
resourceIri = "",
permissions =
"CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser",
userPermission = ChangeRightsPermission,
attachedToUser = testUser1,
resourceClassIri = booksBookIri.toSmartIri,
projectADM = SharedTestDataADM.anythingProject,
creationDate = Instant.parse("2019-11-29T10:00:00.673298Z"),
values = Map(),
lastModificationDate = None,
versionDate = None,
deletionInfo = None
)
val listValueTemplateReadOtherValue: ReadOtherValueV2 = ReadOtherValueV2(
valueContent = HierarchicalListValueContentV2(
ontologySchema = InternalSchema,
valueHasListNode = ""
),
valueIri = "",
valueHasUUID = stringFormatter.decodeUuid("d34d34d3-4d34-d34d-3496-2b2dfef6a5b9"),
permissions =
"CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser",
userPermission = ModifyPermission,
previousValueIri = None,
valueCreationDate = Instant.parse("2018-05-29T16:42:04.381Z"),
attachedToUser = testUser2,
deletionInfo = None
)

val fulltextSearchForNarr: ReadResourcesSequenceV2 = ReadResourcesSequenceV2(
resources = Vector(
ReadResourceV2(
Expand Down Expand Up @@ -980,7 +1015,7 @@ class SearchResponderV2SpecFullData(implicit stringFormatter: StringFormatter) {
resourceIri = "http://rdfh.ch/0001/a-thing-with-text-values",
permissions = "CR knora-admin:Creator|V knora-admin:ProjectMember",
userPermission = ChangeRightsPermission,
attachedToUser = "http://rdfh.ch/users/9XBCrDV3SRa7kS1WwynB4Q",
attachedToUser = testUser1,
resourceClassIri = "http://www.knora.org/ontology/0001/anything#Thing".toSmartIri,
projectADM = SharedTestDataADM.anythingProject,
creationDate = Instant.parse("2016-03-02T15:05:10Z"),
Expand Down Expand Up @@ -1390,7 +1425,7 @@ class SearchResponderV2SpecFullData(implicit stringFormatter: StringFormatter) {
userPermission = ChangeRightsPermission,
previousValueIri = None,
valueCreationDate = Instant.parse("2016-03-02T15:05:54Z"),
attachedToUser = "http://rdfh.ch/users/9XBCrDV3SRa7kS1WwynB4Q",
attachedToUser = testUser1,
deletionInfo = None
),
ReadTextValueV2(
Expand Down Expand Up @@ -1797,7 +1832,7 @@ class SearchResponderV2SpecFullData(implicit stringFormatter: StringFormatter) {
userPermission = ChangeRightsPermission,
previousValueIri = None,
valueCreationDate = Instant.parse("2016-03-02T15:05:54Z"),
attachedToUser = "http://rdfh.ch/users/9XBCrDV3SRa7kS1WwynB4Q",
attachedToUser = testUser1,
deletionInfo = None
)
)
Expand Down Expand Up @@ -2040,40 +2075,60 @@ class SearchResponderV2SpecFullData(implicit stringFormatter: StringFormatter) {
querySchema = Some(ApiV2Simple)
)

val fulltextSearchForListNodeLabel: ReadResourcesSequenceV2 = ReadResourcesSequenceV2(
val expectedResultFulltextSearchForListNodeLabel: ReadResourcesSequenceV2 = ReadResourcesSequenceV2(
resources = Vector(
ReadResourceV2(
bookTemplateReadResource.copy(
label = "instance of a book with a list value",
resourceIri = "http://rdfh.ch/0001/book-instance-02",
permissions =
"CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser",
userPermission = ChangeRightsPermission,
attachedToUser = "http://rdfh.ch/users/9XBCrDV3SRa7kS1WwynB4Q",
resourceClassIri = "http://www.knora.org/ontology/0001/books#Book".toSmartIri,
projectADM = SharedTestDataADM.anythingProject,
creationDate = Instant.parse("2019-11-29T10:00:00.673298Z"),
values = Map(
"http://www.knora.org/ontology/0001/books#hasTextType".toSmartIri -> Vector(
ReadOtherValueV2(
booksHasTextType.toSmartIri -> Vector(
listValueTemplateReadOtherValue.copy(
valueContent = HierarchicalListValueContentV2(
ontologySchema = InternalSchema,
valueHasListNode = "http://rdfh.ch/lists/0001/ynm02-03"
),
valueIri = "http://rdfh.ch/0001/book-instance-02/values/has-list-value-01",
valueHasUUID = stringFormatter.decodeUuid("d34d34d3-4d34-d34d-3496-2b2dfef6a5b9"),
permissions =
"CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser",
userPermission = ModifyPermission,
previousValueIri = None,
valueCreationDate = Instant.parse("2018-05-29T16:42:04.381Z"),
attachedToUser = "http://rdfh.ch/users/BhkfBc3hTeS_IDo-JgXRbQ",
deletionInfo = None
valueHasUUID = stringFormatter.decodeUuid("d34d34d3-4d34-d34d-3496-2b2dfef6a5b9")
)
)
),
lastModificationDate = None,
versionDate = None,
deletionInfo = None
)
)
)
)

val expectedResultFulltextSearchForListNodeLabelWithSubnodes: ReadResourcesSequenceV2 = ReadResourcesSequenceV2(
resources = Vector(
bookTemplateReadResource.copy(
label = "Lord of the Rings",
resourceIri = "http://rdfh.ch/0001/book-instance-03",
values = Map(
booksHasTextType.toSmartIri -> Vector(
listValueTemplateReadOtherValue.copy(
valueContent = HierarchicalListValueContentV2(
ontologySchema = InternalSchema,
valueHasListNode = "http://rdfh.ch/lists/0001/ynm02-04"
),
valueIri = "http://rdfh.ch/0001/book-instance-03/values/has-list-value-02",
valueHasUUID = stringFormatter.decodeUuid("d34d3496-2b2d-fef6-a5b9-efdf6a7b5ab3")
)
)
)
),
bookTemplateReadResource.copy(
label = "Treasure Island",
resourceIri = "http://rdfh.ch/0001/book-instance-04",
values = Map(
booksHasTextType.toSmartIri -> Vector(
listValueTemplateReadOtherValue.copy(
valueContent = HierarchicalListValueContentV2(
ontologySchema = InternalSchema,
valueHasListNode = "http://rdfh.ch/lists/0001/ynm02-05"
),
valueIri = "http://rdfh.ch/0001/book-instance-04/values/has-list-value-03",
valueHasUUID = stringFormatter.decodeUuid("d34962b2-dfef-6a5b-9efd-a76f7a7b6ead")
)
)
)
)
)
)
Expand Down

0 comments on commit 7e8c759

Please sign in to comment.