Skip to content

Commit

Permalink
Select entities with namespace and projects with creators
Browse files Browse the repository at this point in the history
This will select only entities, where a `namespace` property exists.
Additionally, it selects only projects that have an existing
`createBy` property.

This doesn't filter out results, where a subquery would return no
results.
  • Loading branch information
eikek committed Oct 25, 2024
1 parent d9f9ad1 commit 363899f
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ object RenkuEntityQuery:
def apply(role: SearchRole, sq: SolrQuery, limit: Int, offset: Int): QueryData =
QueryData(QueryString(sq.query.value, limit, offset))
.addFilter(
SolrToken.kindIs(DocumentKind.FullEntity).value
SolrToken.kindIs(DocumentKind.FullEntity).value,
SolrToken.namespaceExists.value,
SolrToken.createdByExists.value
)
.addFilter(constrainRole(role).map(_.value)*)
.withSort(sq.sort)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package io.renku.search.solr.query

import cats.Monad
import cats.effect.Sync
import cats.syntax.all.*

import io.renku.search.query.Query
import io.renku.search.solr.SearchRole
Expand All @@ -33,7 +34,7 @@ final class LuceneQueryInterpreter[F[_]: Monad]
private val encoder = SolrTokenEncoder[F, Query]

def run(ctx: Context[F], query: Query): F[SolrQuery] =
encoder.encode(ctx, query)
encoder.encode(ctx, query).map(_.emptyToAll)

object LuceneQueryInterpreter:
def forSync[F[_]: Sync](role: SearchRole): QueryInterpreter.WithContext[F] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ final case class SolrQuery(
def ++(next: SolrQuery): SolrQuery =
SolrQuery(query && next.query, sort ++ next.sort)

def emptyToAll: SolrQuery =
if (query.isEmpty) SolrQuery(SolrToken.all, sort)
else this

object SolrQuery:
val empty: SolrQuery = SolrQuery(SolrToken.empty, SolrSort.empty)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ object SolrToken:
def fromVisibility(v: Visibility): SolrToken = v.name
private def fromEntityType(et: EntityType): SolrToken = et.name

val all: SolrToken = "*:*"

def fromKeyword(kw: Keyword): SolrToken =
StringEscape.queryChars(kw.value)

Expand Down Expand Up @@ -79,6 +81,11 @@ object SolrToken:
def namespaceIs(ns: Namespace): SolrToken =
fieldIs(SolrField.namespace, fromNamespace(ns))

def namespaceExists: SolrToken = fieldExists(SolrField.namespace)

def createdByExists: SolrToken =
"(createdBy:[* TO *] OR (*:* AND -_type:Project))"

def createdDateIs(date: Instant): SolrToken =
fieldIs(SolrField.creationDate, fromInstant(date))
def createdDateGt(date: Instant): SolrToken =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,15 @@ class RenkuEntityQuerySpec extends FunSuite:
query("bla", adminRole),
SolrToken.kindIs(DocumentKind.FullEntity).value
)

test("only entities with existing namespace property"):
assertFilter(
query("bla", adminRole),
SolrToken.namespaceExists.value
)

test("only projects with createdBy property"):
assertFilter(
query("bla", adminRole),
SolrToken.createdByExists.value
)
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,64 @@ class SearchSolrClientSpec extends CatsEffectSuite with SearchSolrSuite:
override def munitFixtures: Seq[munit.AnyFixture[?]] =
List(solrServer, searchSolrClient)

// test("ignore entities with non-resolvable namespace"):
// val user = userDocumentGen.generateOne
// val group = groupDocumentGen.generateOne
// val project0 = projectDocumentGen(
// "project-test0",
// "project-test0 description",
// Gen.const(None),
// Gen.const(None)
// ).generateOne.copy(createdBy = user.id, namespace = group.namespace.some)
// val project1 = projectDocumentGen(
// "project-test1",
// "project-test1 description",
// Gen.const(None),
// Gen.const(None)
// ).generateOne.copy(createdBy = user.id, namespace = group.namespace.some)

// for
// client <- IO(searchSolrClient())
// _ <- client.upsert(Seq(project0.widen, project1.widen, user.widen, group.widen))

// qr <- client.queryEntity(
// SearchRole.admin(Id("admin")),
// Query.parse("test0").toOption.get,
// 10,
// 0
// )
// _ = assertEquals(qr.responseBody.docs.size, 1)
// yield ()

// test("ignore entities with non-existing namespace"):
// val user = userDocumentGen.generateOne
// val group = groupDocumentGen.generateOne
// val project0 = projectDocumentGen(
// "project-test0",
// "project-test0 description",
// Gen.const(None),
// Gen.const(None)
// ).generateOne.copy(createdBy = user.id, namespace = group.namespace.some)
// val project1 = projectDocumentGen(
// "project-test1",
// "project-test1 description",
// Gen.const(None),
// Gen.const(None)
// ).generateOne.copy(createdBy = user.id, namespace = None)

// for
// client <- IO(searchSolrClient())
// _ <- client.upsert(Seq(project0.widen, project1.widen, user.widen, group.widen))

// qr <- client.queryEntity(
// SearchRole.admin(Id("admin")),
// Query.parse("test0").toOption.get,
// 10,
// 0
// )
// _ = assertEquals(qr.responseBody.docs.size, 1)
// yield ()

test("load project with resolved namespace and creator"):
val user = userDocumentGen.generateOne
val group = groupDocumentGen.generateOne
Expand Down

0 comments on commit 363899f

Please sign in to comment.