From d9f0f05613192312da259e67aae5c3f1b29e1c48 Mon Sep 17 00:00:00 2001 From: Eike Kettner Date: Tue, 23 Jun 2020 21:27:01 +0200 Subject: [PATCH] Refactor findItemsWithTags to more general useful --- .../docspell/backend/ops/OItemSearch.scala | 8 ++++++-- .../scala/docspell/ftsclient/FtsClient.scala | 1 + .../scala/docspell/ftsclient/FtsQuery.scala | 3 ++- .../scala/docspell/store/queries/QItem.scala | 20 ++++++++++++++----- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/modules/backend/src/main/scala/docspell/backend/ops/OItemSearch.scala b/modules/backend/src/main/scala/docspell/backend/ops/OItemSearch.scala index a1478aad..d6bf64ee 100644 --- a/modules/backend/src/main/scala/docspell/backend/ops/OItemSearch.scala +++ b/modules/backend/src/main/scala/docspell/backend/ops/OItemSearch.scala @@ -110,11 +110,15 @@ object OItemSearch { .compile .toVector - def findItemsWithTags(q: Query, batch: Batch): F[Vector[ListItemWithTags]] = + def findItemsWithTags(q: Query, batch: Batch): F[Vector[ListItemWithTags]] = { + val search = QItem.findItems(q, batch) store - .transact(QItem.findItemsWithTags(q, batch).take(batch.limit.toLong)) + .transact( + QItem.findItemsWithTags(q.collective, search).take(batch.limit.toLong) + ) .compile .toVector + } def findAttachment(id: Ident, collective: Ident): F[Option[AttachmentData[F]]] = store diff --git a/modules/fts-client/src/main/scala/docspell/ftsclient/FtsClient.scala b/modules/fts-client/src/main/scala/docspell/ftsclient/FtsClient.scala index b678b27f..b25cb1c9 100644 --- a/modules/fts-client/src/main/scala/docspell/ftsclient/FtsClient.scala +++ b/modules/fts-client/src/main/scala/docspell/ftsclient/FtsClient.scala @@ -24,6 +24,7 @@ trait FtsClient[F[_]] { /** Run a full-text search. */ def search(q: FtsQuery): F[FtsResult] + /** Continually run a full-text search and concatenate the results. */ def searchAll(q: FtsQuery): Stream[F, FtsResult] = Stream.eval(search(q)).flatMap { result => if (result.results.size < q.limit) Stream.emit(result) diff --git a/modules/fts-client/src/main/scala/docspell/ftsclient/FtsQuery.scala b/modules/fts-client/src/main/scala/docspell/ftsclient/FtsQuery.scala index d2fe953a..785d2e20 100644 --- a/modules/fts-client/src/main/scala/docspell/ftsclient/FtsQuery.scala +++ b/modules/fts-client/src/main/scala/docspell/ftsclient/FtsQuery.scala @@ -8,7 +8,8 @@ import docspell.common._ * interpret it according to the system in use. * * Searches must only look for given collective and in the given list - * of item ids. + * of item ids, if it is non-empty. If the item set is empty, then + * don't restrict the result in this way. */ final case class FtsQuery( q: String, diff --git a/modules/store/src/main/scala/docspell/store/queries/QItem.scala b/modules/store/src/main/scala/docspell/store/queries/QItem.scala index abb6202d..70544741 100644 --- a/modules/store/src/main/scala/docspell/store/queries/QItem.scala +++ b/modules/store/src/main/scala/docspell/store/queries/QItem.scala @@ -214,7 +214,7 @@ object QItem { Batch(0, c) } - def findItems(q: Query, batch: Batch): Stream[ConnectionIO, ListItem] = { + private def findItemsBase(q: Query): Fragment = { val IC = RItem.Columns val AC = RAttachment.Columns val PC = RPerson.Columns @@ -271,6 +271,16 @@ object QItem { fr"LEFT JOIN orgs o0 ON" ++ IC.corrOrg.prefix("i").is(OC.oid.prefix("o0")) ++ fr"LEFT JOIN persons p1 ON" ++ IC.concPerson.prefix("i").is(PC.pid.prefix("p1")) ++ fr"LEFT JOIN equips e1 ON" ++ IC.concEquipment.prefix("i").is(EC.eid.prefix("e1")) + query + } + + def findItems(q: Query, batch: Batch): Stream[ConnectionIO, ListItem] = { + val IC = RItem.Columns + val PC = RPerson.Columns + val OC = ROrganization.Columns + val EC = REquipment.Columns + + val query = findItemsBase(q) // inclusive tags are AND-ed val tagSelectsIncl = q.tagsInclude @@ -370,8 +380,8 @@ object QItem { * this is implemented by running an additional query per item. */ def findItemsWithTags( - q: Query, - batch: Batch + collective: Ident, + search: Stream[ConnectionIO, ListItem] ): Stream[ConnectionIO, ListItemWithTags] = { def findTag( cache: Ref[ConnectionIO, Map[Ident, RTag]], @@ -394,10 +404,10 @@ object QItem { for { resolvedTags <- Stream.eval(Ref.of[ConnectionIO, Map[Ident, RTag]](Map.empty)) - item <- findItems(q, batch) + item <- search tagItems <- Stream.eval(RTagItem.findByItem(item.id)) tags <- Stream.eval(tagItems.traverse(ti => findTag(resolvedTags, ti))) - ftags = tags.flatten.filter(t => t.collective == q.collective) + ftags = tags.flatten.filter(t => t.collective == collective) } yield ListItemWithTags(item, ftags.toList.sortBy(_.name)) }