Fix fulltext search queries for new collective-id

This commit is contained in:
eikek 2022-08-07 16:19:56 +02:00
parent d9485355e9
commit 868285a26b
6 changed files with 21 additions and 15 deletions

View File

@ -29,7 +29,7 @@ object FtsResult {
case class ItemMatch( case class ItemMatch(
id: Ident, id: Ident,
itemId: Ident, itemId: Ident,
collectiveId: Ident, collectiveId: CollectiveId,
score: Double, score: Double,
data: MatchData data: MatchData
) )

View File

@ -16,6 +16,7 @@ import doobie._
import doobie.implicits._ import doobie.implicits._
object FtsRepository extends DoobieMeta { object FtsRepository extends DoobieMeta {
private[this] val logger = docspell.logging.getLogger[ConnectionIO]
val table = fr"ftspsql_search" val table = fr"ftspsql_search"
def containsData: ConnectionIO[Boolean] = def containsData: ConnectionIO[Boolean] =
@ -62,15 +63,17 @@ object FtsRepository extends DoobieMeta {
val query = mkQueryPart(pq, q) val query = mkQueryPart(pq, q)
sql"""select $select val sqlFrag =
|from $table, $query sql"""select $select
|where ${mkCondition(q)} AND query @@ text_index |from $table, $query
|order by rank desc |where ${mkCondition(q)} AND query @@ text_index
|limit ${q.limit} |order by rank desc
|offset ${q.offset} |limit ${q.limit}
|""".stripMargin |offset ${q.offset}
.query[SearchResult] |""".stripMargin
.to[Vector]
logger.asUnsafe.trace(s"PSQL Fulltext query: $sqlFrag")
sqlFrag.query[SearchResult].to[Vector]
} }
private def mkCondition(q: FtsQuery): Fragment = { private def mkCondition(q: FtsQuery): Fragment = {
@ -84,7 +87,7 @@ object FtsRepository extends DoobieMeta {
val folders = val folders =
NonEmptyList.fromList(q.folders.toList).map { nel => NonEmptyList.fromList(q.folders.toList).map { nel =>
val ids = nel.map(id => fr"$id").reduceLeft(_ ++ fr"," ++ _) val ids = nel.map(id => fr"$id").reduceLeft(_ ++ fr"," ++ _)
fr"folder_id in ($ids)" fr"(folder_id in ($ids) or folder_id is null)"
} }
List(items, folders).flatten.foldLeft(coll)(_ ++ fr"AND" ++ _) List(items, folders).flatten.foldLeft(coll)(_ ++ fr"AND" ++ _)

View File

@ -26,6 +26,8 @@ final class PsqlFtsClient[F[_]: Sync](cfg: PsqlConfig, xa: Transactor[F])
val engine = Ident.unsafe("postgres") val engine = Ident.unsafe("postgres")
val config = cfg val config = cfg
private[this] val logger = docspell.logging.getLogger[F]
private[ftspsql] val transactor = xa private[ftspsql] val transactor = xa
private[this] val searchSummary = private[this] val searchSummary =
@ -83,6 +85,7 @@ final class PsqlFtsClient[F[_]: Sync](cfg: PsqlConfig, xa: Transactor[F])
summary <- searchSummary(q).transact(xa) summary <- searchSummary(q).transact(xa)
results <- search(q, true).transact(xa) results <- search(q, true).transact(xa)
endNanos <- Sync[F].delay(System.nanoTime()) endNanos <- Sync[F].delay(System.nanoTime())
_ <- logger.debug(s"PSQL fulltext search hits: ${results.size}")
duration = Duration.nanos(endNanos - startNanos) duration = Duration.nanos(endNanos - startNanos)
res = SearchResult res = SearchResult
.toFtsResult(summary, results) .toFtsResult(summary, results)

View File

@ -13,7 +13,7 @@ import docspell.ftsclient.FtsResult.{ItemMatch, MatchData}
final case class SearchResult( final case class SearchResult(
id: Ident, id: Ident,
itemId: Ident, itemId: Ident,
collective: Ident, collective: CollectiveId,
language: Language, language: Language,
attachId: Option[Ident], attachId: Option[Ident],
folderId: Option[Ident], folderId: Option[Ident],

View File

@ -125,7 +125,7 @@ trait JsonCodec {
for { for {
itemId <- c.get[Ident](Field.itemId.name) itemId <- c.get[Ident](Field.itemId.name)
id <- c.get[Ident](Field.id.name) id <- c.get[Ident](Field.id.name)
coll <- c.get[Ident](Field.collectiveId.name) coll <- c.get[CollectiveId](Field.collectiveId.name)
score <- c.get[Double]("score") score <- c.get[Double]("score")
md <- decodeMatchData(c) md <- decodeMatchData(c)
} yield FtsResult.ItemMatch(id, itemId, coll, score, md) } yield FtsResult.ItemMatch(id, itemId, coll, score, md)

View File

@ -130,14 +130,14 @@ class TempFtsOpsTest extends DatabaseTest {
ItemMatch( ItemMatch(
id(s"m$n"), id(s"m$n"),
id(s"item-$n"), id(s"item-$n"),
DocspellSystem.user, CollectiveId(1),
math.random(), math.random(),
FtsResult.ItemData FtsResult.ItemData
), ),
ItemMatch( ItemMatch(
id(s"m$n-1"), id(s"m$n-1"),
id(s"item-$n"), id(s"item-$n"),
DocspellSystem.user, CollectiveId(1),
math.random(), math.random(),
AttachmentData(id(s"item-$n-attach-1"), "attachment.pdf") AttachmentData(id(s"item-$n-attach-1"), "attachment.pdf")
) )