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

refactor: Search graphs properties clean-up #1775

Merged
merged 4 commits into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,13 @@ private object DatasetInfoDeleteQuery {
Prefixes of (renku -> "renku", schema -> "schema"),
sparql"""|DELETE {
| GRAPH ${GraphClass.Datasets.id} {
| ?imageId ?imagePred ?imageObj.
| ?linkId ?linkPred ?linkObj.
| ?topSameAs ?dsPred ?dsObj.
| }
|}
|WHERE {
| GRAPH ${GraphClass.Datasets.id} {
| BIND (${topmostSameAs.asEntityId} AS ?topSameAs)
|
| OPTIONAL {
| ?topSameAs schema:image ?imageId.
| ?imageId ?imagePred ?imageObj.
| }

| OPTIONAL {
| ?topSameAs renku:datasetProjectLink ?linkId.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ package commands
import DatasetSearchInfoOntology._
import Link.{ImportedDataset, OriginalDataset}
import cats.syntax.all._
import io.renku.entities.searchgraphs.toConcatValue
import io.renku.entities.searchgraphs.maybeTripleObject
import io.renku.graph.model.Schemas.{rdf, renku}
import io.renku.graph.model.images.Image
import io.renku.graph.model.{datasets, persons}
Expand All @@ -33,14 +33,6 @@ import io.renku.triplesstore.client.syntax._

private[datasets] object Encoders {

implicit val imageEncoder: QuadsEncoder[Image] = QuadsEncoder.instance { case Image(resourceId, uri, position) =>
Set(
DatasetsQuad(resourceId, rdf / "type", Image.Ontology.typeClass.id),
DatasetsQuad(resourceId, Image.Ontology.contentUrlProperty.id, uri.asObject),
DatasetsQuad(resourceId, Image.Ontology.positionProperty.id, position.asObject)
)
}

implicit val linkEncoder: QuadsEncoder[Link] = QuadsEncoder.instance { link =>
val typeQuads = link match {
case _: OriginalDataset =>
Expand All @@ -59,7 +51,7 @@ private[datasets] object Encoders {

implicit val projectsVisibilitiesConcatEncoder: QuadsEncoder[(datasets.TopmostSameAs, List[Link])] =
QuadsEncoder.instance { case (topSameAs, links) =>
toConcatValue[Link](links, link => s"${link.projectSlug.value}:${link.visibility.value}")
maybeTripleObject[Link](links, link => s"${link.projectSlug.value}:${link.visibility.value}")
.map(DatasetsQuad(topSameAs, projectsVisibilitiesConcatProperty.id, _))
.toSet
}
Expand All @@ -69,7 +61,7 @@ private[datasets] object Encoders {
DatasetsQuad(info.topmostSameAs, predicate, obj)

def maybeConcatQuad[A](property: Property, values: List[A], toValue: A => String): Option[Quad] =
toConcatValue(values, toValue).map(searchInfoQuad(property, _))
maybeTripleObject(values, toValue).map(searchInfoQuad(property, _))

val createdOrPublishedQuad = info.createdOrPublished match {
case d: datasets.DateCreated =>
Expand All @@ -93,18 +85,9 @@ private[datasets] object Encoders {
val maybeCreatorsNamesConcatQuad =
maybeConcatQuad[persons.Name](creatorsNamesConcatProperty.id, info.creators.toList.map(_.name).distinct, _.value)

val keywordsQuads = info.keywords.toSet.map { (k: datasets.Keyword) =>
searchInfoQuad(keywordsProperty.id, k.asObject)
}

val maybeKeywordsConcatQuad =
maybeConcatQuad[datasets.Keyword](keywordsConcatProperty.id, info.keywords.distinct, _.value)

val imagesQuads = info.images.toSet.flatMap { (i: Image) =>
i.asQuads +
searchInfoQuad(imageProperty, i.resourceId.asEntityId)
}

val maybeImagesConcatQuad =
maybeConcatQuad[Image](imagesConcatProperty.id,
info.images,
Expand All @@ -129,6 +112,6 @@ private[datasets] object Encoders {
maybeCreatorsNamesConcatQuad,
maybeKeywordsConcatQuad,
maybeImagesConcatQuad
).flatten ++ projectsVisibilitiesConcatQuads ++ creatorsQuads ++ keywordsQuads ++ imagesQuads ++ linksQuads
).flatten ++ projectsVisibilitiesConcatQuads ++ creatorsQuads ++ linksQuads
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ package io.renku.entities.searchgraphs.datasets

import io.renku.graph.model.Schemas.{xsd, _}
import io.renku.graph.model.entities.{Dataset, Person, Project}
import io.renku.graph.model.images.Image
import io.renku.jsonld.Property
import io.renku.jsonld.ontology._

Expand All @@ -31,12 +30,10 @@ object DatasetSearchInfoOntology {
val dateCreatedProperty: DataProperty.Def = Dataset.Ontology.dateCreatedProperty
val datePublishedProperty: DataProperty.Def = Dataset.Ontology.datePublishedProperty
val dateModifiedProperty: DataProperty.Def = DataProperty(schema / "dateModified", xsd / "dateTime")
val keywordsProperty: DataProperty.Def = Dataset.Ontology.keywordsProperty
val keywordsConcatProperty: DataProperty.Def = DataProperty(renku / "keywordsConcat", xsd / "string")
val descriptionProperty: DataProperty.Def = Dataset.Ontology.descriptionProperty
val creatorProperty: Property = Dataset.Ontology.creator
val creatorsNamesConcatProperty: DataProperty.Def = DataProperty(renku / "creatorsNamesConcat", xsd / "string")
val imageProperty: Property = Dataset.Ontology.image
val imagesConcatProperty: DataProperty.Def = DataProperty(renku / "imagesConcat", xsd / "string")
val linkProperty: Property = renku / "datasetProjectLink"
val projectsVisibilitiesConcatProperty: DataProperty.Def =
Expand All @@ -46,7 +43,6 @@ object DatasetSearchInfoOntology {
Class(renku / "DiscoverableDataset"),
ObjectProperties(
ObjectProperty(creatorProperty, Person.Ontology.typeDef),
ObjectProperty(imageProperty, Image.Ontology.typeDef),
ObjectProperty(linkProperty, LinkOntology.typeDef)
),
DataProperties(
Expand All @@ -55,7 +51,6 @@ object DatasetSearchInfoOntology {
dateCreatedProperty,
datePublishedProperty,
dateModifiedProperty,
keywordsProperty,
keywordsConcatProperty,
descriptionProperty,
creatorsNamesConcatProperty,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import io.renku.triplesstore.client.syntax._
package object searchgraphs {
val concatSeparator: Char = ';'

private[searchgraphs] def toConcatValue[A](values: List[A], toValue: A => String): Option[TripleObject] =
private[searchgraphs] def maybeTripleObject[A](values: List[A], toValue: A => String): Option[TripleObject] =
values match {
case Nil => Option.empty[TripleObject]
case vls =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,24 @@ import io.renku.jsonld.syntax._
import io.renku.triplesstore.client.model.{Quad, QuadsEncoder, TripleObject}
import io.renku.triplesstore.client.syntax._

private object Encoders {
object Encoders {

implicit val imageEncoder: QuadsEncoder[Image] = QuadsEncoder.instance { case Image(resourceId, uri, position) =>
Set(
ProjectsQuad(resourceId, rdf / "type", Image.Ontology.typeClass.id),
ProjectsQuad(resourceId, Image.Ontology.contentUrlProperty.id, uri.asObject),
ProjectsQuad(resourceId, Image.Ontology.positionProperty.id, position.asObject)
)
}
def maybeKeywordsObject(keywords: List[projects.Keyword]): Option[TripleObject] =
maybeTripleObject[projects.Keyword](keywords.distinct, _.value)

def maybeKeywordsQuad(id: projects.ResourceId, keywords: List[projects.Keyword]): Option[Quad] =
maybeKeywordsObject(keywords).map(ProjectsQuad(id, keywordsConcatProperty.id, _))

def maybeImagesObject(images: List[Image]): Option[TripleObject] =
maybeTripleObject[Image](images, image => s"${image.position.value}:${image.uri.value}")

def maybeImagesQuad(id: projects.ResourceId, images: List[Image]): Option[Quad] =
maybeImagesObject(images).map(ProjectsQuad(id, imagesConcatProperty.id, _))

implicit val searchInfoEncoder: QuadsEncoder[ProjectSearchInfo] = QuadsEncoder.instance { info =>
private[commands] implicit val searchInfoEncoder: QuadsEncoder[ProjectSearchInfo] = QuadsEncoder.instance { info =>
def searchInfoQuad(predicate: Property, obj: TripleObject): Quad =
ProjectsQuad(info.id, predicate, obj)

def maybeConcatQuad[A](property: Property, values: List[A], toValue: A => String): Option[Quad] =
toConcatValue(values, toValue).map(searchInfoQuad(property, _))

val maybeDescriptionQuad = info.maybeDescription.map { d =>
searchInfoQuad(descriptionProperty.id, d.asObject)
}
Expand All @@ -55,22 +56,9 @@ private object Encoders {
searchInfoQuad(creatorProperty, resourceId.asEntityId)
}

val keywordsQuads = info.keywords.toSet.map { (k: projects.Keyword) =>
searchInfoQuad(keywordsProperty.id, k.asObject)
}

val maybeKeywordsConcatQuad =
maybeConcatQuad[projects.Keyword](keywordsConcatProperty.id, info.keywords.distinct, _.value)

val imagesQuads = info.images.toSet.flatMap { (i: Image) =>
i.asQuads + searchInfoQuad(imageProperty, i.resourceId.asEntityId)
}
val maybeKeywordsConcatQuad = maybeKeywordsQuad(info.id, info.keywords)

val maybeImagesConcatQuad =
maybeConcatQuad[Image](imagesConcatProperty.id,
info.images,
image => s"${image.position.value}:${image.uri.value}"
)
val maybeImagesConcatQuad = maybeImagesQuad(info.id, info.images)

Set(
searchInfoQuad(rdf / "type", typeDef.clazz.id).some,
Expand All @@ -83,6 +71,6 @@ private object Encoders {
maybeKeywordsConcatQuad,
maybeImagesConcatQuad,
maybeDescriptionQuad
).flatten ++ creatorQuads ++ keywordsQuads ++ imagesQuads
).flatten ++ creatorQuads
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,12 @@ private[projects] object ProjectInfoDeleteQuery {
Prefixes of schema -> "schema",
sparql"""|DELETE {
| GRAPH ${GraphClass.Projects.id} {
| ?imageId ?imagePred ?imageObj.
| ?projId ?projPred ?projObj.
| }
|}
|WHERE {
| GRAPH ${GraphClass.Projects.id} {
| BIND (${projectId.asEntityId} AS ?projId)
|
| OPTIONAL {
| ?projId schema:image ?imageId.
| ?imageId ?imagePred ?imageObj.
| }
|
| ?projId ?projPred ?projObj.
| }
|}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
package io.renku.entities.searchgraphs.projects

import io.renku.graph.model.Schemas.renku
import io.renku.graph.model.entities.{Dataset, Person, Project}
import io.renku.graph.model.images.Image
import io.renku.graph.model.entities.{Person, Project}
import io.renku.jsonld.Property
import io.renku.jsonld.ontology._

Expand All @@ -32,18 +31,15 @@ object ProjectSearchInfoOntology {
val visibilityProperty: DataProperty.Def = Project.Ontology.visibilityProperty
val dateCreatedProperty: DataProperty.Def = Project.Ontology.dateCreatedProperty
val dateModifiedProperty: DataProperty.Def = Project.Ontology.dateModifiedProperty
val keywordsProperty: DataProperty.Def = Project.Ontology.keywordsProperty
val keywordsConcatProperty: DataProperty.Def = DataProperty(renku / "keywordsConcat", xsd / "string")
val descriptionProperty: DataProperty.Def = Project.Ontology.descriptionProperty
val creatorProperty: Property = Project.Ontology.creator
val imageProperty: Property = Project.Ontology.image
val imagesConcatProperty: DataProperty.Def = DataProperty(renku / "imagesConcat", xsd / "string")

lazy val typeDef: Type = Type.Def(
Class(renku / "DiscoverableProject"),
ObjectProperties(
ObjectProperty(creatorProperty, Person.Ontology.typeDef),
ObjectProperty(imageProperty, Image.Ontology.typeDef)
ObjectProperty(creatorProperty, Person.Ontology.typeDef)
),
DataProperties(
nameProperty,
Expand All @@ -52,25 +48,9 @@ object ProjectSearchInfoOntology {
visibilityProperty,
dateCreatedProperty,
dateModifiedProperty,
keywordsProperty,
keywordsConcatProperty,
descriptionProperty,
imagesConcatProperty
)
)
}

object LinkOntology {

val project: Property = renku / "project"
val dataset: Property = renku / "dataset"

lazy val typeDef: Type = Type.Def(
Class(renku / "DatasetProjectLink"),
ObjectProperties(
ObjectProperty(project, Project.Ontology.typeDef),
ObjectProperty(dataset, Dataset.Ontology.typeDef)
),
DataProperties()
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,9 @@ import Generators.{datasetSearchInfoObjects, importedDatasetLinkObjectsGen, orig
import cats.syntax.all._
import io.renku.entities.searchgraphs.concatSeparator
import io.renku.generators.Generators.Implicits._
import io.renku.generators.Generators.positiveInts
import io.renku.generators.jsonld.JsonLDGenerators.entityIds
import io.renku.graph.model.GraphModelGenerators.{datasetTopmostSameAs, imageUris}
import io.renku.graph.model.Schemas.{rdf, renku, schema}
import io.renku.graph.model.GraphModelGenerators.datasetTopmostSameAs
import io.renku.graph.model.Schemas.{rdf, renku}
import io.renku.graph.model.datasets
import io.renku.graph.model.images.{Image, ImagePosition, ImageResourceId}
import io.renku.jsonld.syntax._
import io.renku.triplesstore.client.model.Quad
import io.renku.triplesstore.client.syntax._
Expand All @@ -41,26 +38,6 @@ class EncodersSpec extends AnyWordSpec with should.Matchers with ScalaCheckPrope

import io.renku.entities.searchgraphs.datasets.commands.Encoders._

"imageEncoder" should {

"turn an Image object into a Set of relevant Quads" in {

val image = {
for {
id <- entityIds.toGeneratorOf(id => ImageResourceId(id.toString))
uri <- imageUris
position <- positiveInts().toGeneratorOf(p => ImagePosition(p.value))
} yield Image(id, uri, position)
}.generateOne

image.asQuads shouldBe Set(
DatasetsQuad(image.resourceId, rdf / "type", schema / "ImageObject"),
DatasetsQuad(image.resourceId, Image.Ontology.contentUrlProperty.id, image.uri.asObject),
DatasetsQuad(image.resourceId, Image.Ontology.positionProperty.id, image.position.asObject)
)
}
}

"linkEncoder" should {

"turn a OriginalDataset object into a Set of relevant Quads" in {
Expand Down Expand Up @@ -105,11 +82,9 @@ class EncodersSpec extends AnyWordSpec with should.Matchers with ScalaCheckPrope
) ++
maybeDateModifiedToQuad(searchInfo.topmostSameAs)(searchInfo.maybeDateModified) ++
creatorsToQuads(searchInfo) ++
keywordsToQuads(searchInfo) ++
maybeDescToQuad(searchInfo.topmostSameAs)(searchInfo.maybeDescription) ++
maybeKeywordsConcatToQuad(searchInfo).toSet ++
maybeImagesConcatToQuad(searchInfo).toSet ++
imagesToQuads(searchInfo) ++
linksToQuads(searchInfo)
}
}
Expand Down Expand Up @@ -139,11 +114,6 @@ class EncodersSpec extends AnyWordSpec with should.Matchers with ScalaCheckPrope
private def creatorsNamesConcat(searchInfo: DatasetSearchInfo) =
searchInfo.creators.map(_.name.value).intercalate(concatSeparator.toString).asTripleObject

private def keywordsToQuads(searchInfo: DatasetSearchInfo): Set[Quad] =
searchInfo.keywords
.map(k => DatasetsQuad(searchInfo.topmostSameAs, keywordsProperty.id, k.asObject))
.toSet

private def maybeKeywordsConcatToQuad(searchInfo: DatasetSearchInfo): Option[Quad] =
searchInfo.keywords match {
case Nil => Option.empty[Quad]
Expand Down Expand Up @@ -171,12 +141,6 @@ class EncodersSpec extends AnyWordSpec with should.Matchers with ScalaCheckPrope
).some
}

private def imagesToQuads(searchInfo: DatasetSearchInfo): Set[Quad] =
searchInfo.images
.map(i => i.asQuads + DatasetsQuad(searchInfo.topmostSameAs, imageProperty, i.resourceId.asEntityId))
.toSet
.flatten

private def linksToQuads(searchInfo: DatasetSearchInfo): Set[Quad] =
searchInfo.links
.map(l => l.asQuads + DatasetsQuad(searchInfo.topmostSameAs, linkProperty, l.resourceId.asEntityId))
Expand Down
Loading
Loading