mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-22 02:18:26 +00:00
Configure postgres fts backend
This commit is contained in:
@ -289,6 +289,9 @@ docspell.server {
|
||||
# Currently the SOLR search platform is supported.
|
||||
enabled = false
|
||||
|
||||
# Which backend to use, either solr or postgresql
|
||||
backend = "solr"
|
||||
|
||||
# Configuration for the SOLR backend.
|
||||
solr = {
|
||||
# The URL to solr
|
||||
@ -304,6 +307,43 @@ docspell.server {
|
||||
# The default combiner for tokens. One of {AND, OR}.
|
||||
q-op = "OR"
|
||||
}
|
||||
|
||||
# Configuration for PostgreSQL backend
|
||||
postgresql = {
|
||||
# Whether to use the default database, only works if it is
|
||||
# postgresql
|
||||
use-default-connection = false
|
||||
|
||||
# The database connection.
|
||||
jdbc {
|
||||
url = "jdbc:postgresql://server:5432/db"
|
||||
user = "pguser"
|
||||
password = ""
|
||||
}
|
||||
|
||||
# A mapping from a language to a postgres text search config. By
|
||||
# default a language is mapped to a predefined config.
|
||||
# PostgreSQL has predefined configs for some languages. This
|
||||
# setting allows to create a custom text search config and
|
||||
# define it here for some or all languages.
|
||||
#
|
||||
# Example:
|
||||
# { german = "my-german" }
|
||||
#
|
||||
# See https://www.postgresql.org/docs/14/textsearch-tables.html ff.
|
||||
pg-config = {
|
||||
}
|
||||
|
||||
# Define which query parser to use.
|
||||
#
|
||||
# https://www.postgresql.org/docs/14/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES
|
||||
pg-query-parser = "websearch_to_tsquery"
|
||||
|
||||
# Allows to define a normalization for the ranking.
|
||||
#
|
||||
# https://www.postgresql.org/docs/14/textsearch-controls.html#TEXTSEARCH-RANKING
|
||||
pg-rank-normalization = [ 4 ]
|
||||
}
|
||||
}
|
||||
|
||||
# Configuration for the backend.
|
||||
|
@ -9,6 +9,7 @@ package docspell.restserver
|
||||
import docspell.backend.auth.Login
|
||||
import docspell.backend.{Config => BackendConfig}
|
||||
import docspell.common._
|
||||
import docspell.config.{FtsType, PgFtsConfig}
|
||||
import docspell.ftssolr.SolrConfig
|
||||
import docspell.logging.LogConfig
|
||||
import docspell.oidc.ProviderConfig
|
||||
@ -92,7 +93,26 @@ object Config {
|
||||
}
|
||||
}
|
||||
|
||||
case class FullTextSearch(enabled: Boolean, solr: SolrConfig)
|
||||
case class FullTextSearch(
|
||||
enabled: Boolean,
|
||||
backend: FtsType,
|
||||
solr: SolrConfig,
|
||||
postgresql: PgFtsConfig
|
||||
) {
|
||||
|
||||
def info: String =
|
||||
if (!enabled) "Disabled."
|
||||
else
|
||||
backend match {
|
||||
case FtsType.Solr =>
|
||||
s"Solr(${solr.url.asString})"
|
||||
case FtsType.PostgreSQL =>
|
||||
if (postgresql.useDefaultConnection)
|
||||
"PostgreSQL(default)"
|
||||
else
|
||||
s"PostgreSQL(${postgresql.jdbc.url.asString})"
|
||||
}
|
||||
}
|
||||
|
||||
object FullTextSearch {}
|
||||
|
||||
|
@ -13,7 +13,7 @@ import cats.effect.Async
|
||||
|
||||
import docspell.backend.signup.{Config => SignupConfig}
|
||||
import docspell.config.Implicits._
|
||||
import docspell.config.{ConfigFactory, Validation}
|
||||
import docspell.config.{ConfigFactory, FtsType, Validation}
|
||||
import docspell.oidc.{ProviderConfig, SignatureAlgo}
|
||||
import docspell.restserver.auth.OpenId
|
||||
|
||||
@ -106,4 +106,15 @@ object ConfigFile {
|
||||
|
||||
def filesValidate: Validation[Config] =
|
||||
Validation(cfg => cfg.backend.files.validate.map(_ => cfg))
|
||||
|
||||
def postgresFtsValidate: Validation[Config] =
|
||||
Validation.failWhen(
|
||||
cfg =>
|
||||
cfg.fullTextSearch.enabled &&
|
||||
cfg.fullTextSearch.backend == FtsType.PostgreSQL &&
|
||||
cfg.fullTextSearch.postgresql.useDefaultConnection &&
|
||||
!cfg.backend.jdbc.dbmsName.contains("postgresql"),
|
||||
s"PostgreSQL defined fulltext search backend with default-connection, which is not a PostgreSQL connection!"
|
||||
)
|
||||
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ object Main extends IOApp {
|
||||
Option(System.getProperty("config.file")),
|
||||
cfg.appId,
|
||||
cfg.baseUrl,
|
||||
Some(cfg.fullTextSearch.solr.url).filter(_ => cfg.fullTextSearch.enabled),
|
||||
Some(cfg.fullTextSearch.info).filter(_ => cfg.fullTextSearch.enabled),
|
||||
cfg.backend.files.defaultStoreConfig
|
||||
)
|
||||
_ <- logger.info(s"\n${banner.render("***>")}")
|
||||
|
@ -12,9 +12,11 @@ import fs2.concurrent.Topic
|
||||
|
||||
import docspell.backend.BackendApp
|
||||
import docspell.backend.auth.{AuthToken, ShareToken}
|
||||
import docspell.common.Password
|
||||
import docspell.common.Pools
|
||||
import docspell.config.FtsType
|
||||
import docspell.ftsclient.FtsClient
|
||||
import docspell.ftspsql.{PsqlConfig, PsqlFtsClient}
|
||||
import docspell.ftspsql.PsqlFtsClient
|
||||
import docspell.ftssolr.SolrFtsClient
|
||||
import docspell.notification.api.NotificationModule
|
||||
import docspell.notification.impl.NotificationModuleImpl
|
||||
import docspell.oidc.CodeFlowRoutes
|
||||
@ -156,6 +158,7 @@ object RestAppImpl {
|
||||
|
||||
def create[F[_]: Async](
|
||||
cfg: Config,
|
||||
pools: Pools,
|
||||
store: Store[F],
|
||||
httpClient: Client[F],
|
||||
pubSub: PubSub[F],
|
||||
@ -164,7 +167,7 @@ object RestAppImpl {
|
||||
val logger = docspell.logging.getLogger[F](s"restserver-${cfg.appId.id}")
|
||||
|
||||
for {
|
||||
ftsClient <- createFtsClient(cfg, store)
|
||||
ftsClient <- createFtsClient(cfg, pools, store, httpClient)
|
||||
pubSubT = PubSubT(pubSub, logger)
|
||||
javaEmil = JavaMailEmil(cfg.backend.mailSettings)
|
||||
notificationMod <- Resource.eval(
|
||||
@ -190,20 +193,24 @@ object RestAppImpl {
|
||||
|
||||
private def createFtsClient[F[_]: Async](
|
||||
cfg: Config,
|
||||
store: Store[F] /*, client: Client[F] */
|
||||
pools: Pools,
|
||||
store: Store[F],
|
||||
client: Client[F]
|
||||
): Resource[F, FtsClient[F]] =
|
||||
// if (cfg.fullTextSearch.enabled) SolrFtsClient(cfg.fullTextSearch.solr, client)
|
||||
if (cfg.fullTextSearch.enabled)
|
||||
Resource.pure[F, FtsClient[F]](
|
||||
new PsqlFtsClient[F](
|
||||
PsqlConfig.defaults(
|
||||
cfg.backend.jdbc.url,
|
||||
cfg.backend.jdbc.user,
|
||||
Password(cfg.backend.jdbc.password)
|
||||
),
|
||||
store.transactor
|
||||
)
|
||||
)
|
||||
cfg.fullTextSearch.backend match {
|
||||
case FtsType.Solr =>
|
||||
SolrFtsClient(cfg.fullTextSearch.solr, client)
|
||||
|
||||
case FtsType.PostgreSQL =>
|
||||
val psqlCfg = cfg.fullTextSearch.postgresql.toPsqlConfig(cfg.backend.jdbc)
|
||||
if (cfg.fullTextSearch.postgresql.useDefaultConnection)
|
||||
Resource.pure[F, FtsClient[F]](
|
||||
new PsqlFtsClient[F](psqlCfg, store.transactor)
|
||||
)
|
||||
else
|
||||
PsqlFtsClient(psqlCfg, pools.connectEC)
|
||||
}
|
||||
else Resource.pure[F, FtsClient[F]](FtsClient.none[F])
|
||||
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ object RestServer {
|
||||
store,
|
||||
httpClient
|
||||
)(Topics.all.map(_.topic))
|
||||
restApp <- RestAppImpl.create[F](cfg, store, httpClient, pubSub, wsTopic)
|
||||
restApp <- RestAppImpl.create[F](cfg, pools, store, httpClient, pubSub, wsTopic)
|
||||
} yield (restApp, pubSub, setting)
|
||||
|
||||
def createHttpApp[F[_]: Async](
|
||||
|
Reference in New Issue
Block a user