Skip to content

Commit

Permalink
Add in query, category, references queries to tags
Browse files Browse the repository at this point in the history
  • Loading branch information
fredex42 committed Jul 14, 2024
1 parent dd1d0d1 commit 01b2597
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ object Content {

ReplaceField("tags", Field("tags", OptionType(ListType(Tags.Tag)),
arguments = TagQueryParameters.NonPaginatedTagQueryParameters,
resolve=ctx=> ctx.ctx.repo.tagsForList(ctx.value.tags, ctx arg TagQueryParameters.Section, ctx arg TagQueryParameters.TagType))
resolve=ctx=> ctx.ctx.repo.tagsForList(ctx.value.tags, ctx arg TagQueryParameters.Section, ctx arg TagQueryParameters.TagType, ctx arg TagQueryParameters.Category, ctx arg TagQueryParameters.Reference))
),
ExcludeFields("atomIds", "isGone", "isExpired", "sectionId"),
AddFields(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,14 @@ object RootQuery {
Field("tag", TagEdge,
arguments = TagQueryParameters.AllTagQueryParameters,
resolve = ctx =>
ctx.ctx.repo.marshalledTags(ctx arg TagQueryParameters.tagId, ctx arg TagQueryParameters.Section, ctx arg TagQueryParameters.TagType, ctx arg PaginationParameters.OrderBy, ctx arg PaginationParameters.Limit, ctx arg PaginationParameters.Cursor)
ctx.ctx.repo.marshalledTags(ctx arg TagQueryParameters.QueryString,
ctx arg TagQueryParameters.tagId,
ctx arg TagQueryParameters.Section,
ctx arg TagQueryParameters.TagType,
ctx arg TagQueryParameters.Category,
ctx arg TagQueryParameters.Reference,
ctx arg PaginationParameters.OrderBy,
ctx arg PaginationParameters.Limit, ctx arg PaginationParameters.Cursor)
),
Field("atom", AtomEdge,
arguments = AtomQueryParameters.AllParameters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,11 @@ object TagQueryParameters {
val tagId = Argument("tagId", OptionInputType(StringType), description = "Retrieve this specific tag")
val Section = Argument("section", OptionInputType(StringType), description = "Only return tags from this section")
val TagType = Argument("type", OptionInputType(TagTypes), description = "Type of the tag to return")
val AllTagQueryParameters = tagId :: Section :: TagType :: Cursor :: OrderBy :: Limit :: Nil
val QueryString = Argument("q", OptionInputType(StringType), description = "Generic Lucene query string for finding tags")
val Category = Argument("category", OptionInputType(StringType), description = "A category to match against tags")
val Reference = Argument("reference", OptionInputType(StringType), description = "A reference to match against tags")
val AllTagQueryParameters = QueryString :: tagId :: Section :: TagType :: Category ::
Reference :: Cursor :: OrderBy :: Limit :: Nil

val NonPaginatedTagQueryParameters = Section :: TagType :: Nil
}
15 changes: 11 additions & 4 deletions src/main/scala/datastore/DocumentRepo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,17 @@ trait DocumentRepo {
orderDate:Option[String], orderBy:Option[SortOrder],
limit: Option[Int], cursor: Option[String]): Future[Edge[Content]]

def marshalledTags(maybeTagId:Option[String], maybeSection: Option[String], tagType:Option[String],
orderBy: Option[SortOrder], limit: Option[Int], cursor: Option[String]): Future[Edge[Tag]]

def tagsForList(tagIdList:Seq[String], maybeSection: Option[String], tagType:Option[String]):Future[Seq[Tag]]
def marshalledTags(maybeQuery:Option[String],
maybeTagId:Option[String],
maybeSection: Option[String],
tagType:Option[String],
maybeCategory:Option[String],
maybeReferences:Option[String],
orderBy: Option[SortOrder],
limit: Option[Int],
cursor: Option[String]): Future[Edge[Tag]]

def tagsForList(tagIdList:Seq[String], maybeSection: Option[String], tagType:Option[String], maybeCategory:Option[String], maybeReferences:Option[String]):Future[Seq[Tag]]

def atomsForList(atomIds: Seq[String], atomType: Option[String]):Future[Seq[Json]]

Expand Down
78 changes: 51 additions & 27 deletions src/main/scala/datastore/ElasticsearchRepo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,9 @@ class ElasticsearchRepo(endpoint:ElasticNodeEndpoint, val defaultPageSize:Int=20
}
}

private def tagQueryParams(maybeTagId:Option[String], maybeSection:Option[String], tagType:Option[String]):Seq[Query] = {
private def tagQueryParams(maybeTagId:Option[String], maybeSection:Option[String],
tagType:Option[String], maybeCategory:Option[String],
maybeReferences: Option[String]):Seq[Query] = {
Seq(
maybeTagId.map(MatchQuery("id", _)),
maybeSection.map(MatchQuery("sectionId", _)),
Expand All @@ -192,18 +194,28 @@ class ElasticsearchRepo(endpoint:ElasticNodeEndpoint, val defaultPageSize:Int=20
ExistsQuery("podcast")
case tp: String =>
MatchQuery("type", tp)
})
}),
maybeSection.map(s=>termQuery("section",s)),
maybeCategory.map(cat=>termQuery("tagCategories", cat)),
maybeReferences.map(ref=>termQuery("references", ref)) //this is an object field - check how terming works!!
).collect({ case Some(param) => param })
}
private def buildTagQuery(maybeTagId:Option[String], maybeSection:Option[String], tagType:Option[String]) = {
val base = search("tag")

val params = tagQueryParams(maybeTagId, maybeSection, tagType)
private def buildTagQuery(maybeTagId:Option[String],
maybeSection:Option[String],
tagType:Option[String], maybeQuery:Option[String],
maybeCategory:Option[String], maybeReferences:Option[String]) = {
val baseSearch = search("tag")
val searchWithQuery = maybeQuery match {
case Some(q)=>baseSearch.query(q)
case None=>baseSearch
}
val params = tagQueryParams(maybeTagId, maybeSection, tagType, maybeCategory, maybeReferences)

if(params.isEmpty) {
base
searchWithQuery
} else {
base.query(BoolQuery(must=params))
searchWithQuery.query(BoolQuery(must=params))
}
}

Expand All @@ -217,7 +229,15 @@ class ElasticsearchRepo(endpoint:ElasticNodeEndpoint, val defaultPageSize:Int=20

//FIXME: tagsForList / marshalledTags could be DRY'd out a bit

override def marshalledTags(maybeTagId:Option[String], maybeSection: Option[String], tagType:Option[String], orderBy: Option[SortOrder], limit: Option[Int], cursor: Option[String]): Future[Edge[Tag]] = {
override def marshalledTags(maybeQuery:Option[String],
maybeTagId:Option[String],
maybeSection: Option[String],
tagType:Option[String],
maybeCategory:Option[String],
maybeReferences:Option[String],
orderBy: Option[SortOrder],
limit: Option[Int],
cursor: Option[String]): Future[Edge[Tag]] = {
val pageSize = limit.getOrElse(defaultPageSize)

val sortParam = if(maybeSection.isDefined || tagType.isDefined) {
Expand All @@ -229,7 +249,7 @@ class ElasticsearchRepo(endpoint:ElasticNodeEndpoint, val defaultPageSize:Int=20
Edge.decodeCursor(cursor) match {
case Right(maybeCursor)=>
client.execute {
buildTagQuery(maybeTagId, maybeSection, tagType)
buildTagQuery(maybeTagId, maybeSection, tagType, maybeQuery, maybeCategory, maybeReferences)
.sortBy(sortParam)
.limit(pageSize)
.searchAfter(maybeCursor)
Expand All @@ -239,25 +259,10 @@ class ElasticsearchRepo(endpoint:ElasticNodeEndpoint, val defaultPageSize:Int=20
}
}

override def tagsForList(tagIdList:Seq[String], maybeSection: Option[String], tagType:Option[String]):Future[Seq[Tag]] = {
val tagIdMatches = tagIdList.map(MatchQuery("id", _))

client.execute {
val restrictions = tagQueryParams(None, maybeSection, tagType)

if(restrictions.nonEmpty) {
search("tag").query(
BoolQuery(
must=restrictions :+ BoolQuery(should=tagIdMatches)
)
)
} else {
search("tag").query(BoolQuery(should=tagIdMatches))
}

} flatMap { response=>
private def marshalTags(response:Future[Response[SearchResponse]]):Future[Seq[Tag]] = {
response flatMap { response=>
if(response.isError) {
logger.error(s"Could not make query for tags ${tagIdList}: ${response.error}")
logger.error(s"Could not make query for tags: ${response.error}")
Future.failed(response.error.asException)
} else {
Future(response.result.hits.hits.map(hit=>
Expand All @@ -272,6 +277,25 @@ class ElasticsearchRepo(endpoint:ElasticNodeEndpoint, val defaultPageSize:Int=20
}
}

override def tagsForList(tagIdList:Seq[String], maybeSection: Option[String], tagType:Option[String], maybeCategory:Option[String], maybeReferences:Option[String]):Future[Seq[Tag]] = {
val tagIdMatches = tagIdList.map(MatchQuery("id", _))

val response = client.execute {
val restrictions = tagQueryParams(None, maybeSection, tagType, maybeCategory, maybeReferences)

if(restrictions.nonEmpty) {
search("tag").query(
BoolQuery(
must=restrictions :+ BoolQuery(should=tagIdMatches)
)
)
} else {
search("tag").query(BoolQuery(should=tagIdMatches))
}
}
marshalTags(response)
}

private def findAtoms(atomIds: Option[Seq[String]], queryString: Option[String],
queryFields: Option[Seq[String]], atomType: Option[String],
revisionBefore: Option[Long], revisionAfter: Option[Long],
Expand Down

0 comments on commit 01b2597

Please sign in to comment.