mirror of
				https://github.com/TheAnachronism/docspell.git
				synced 2025-10-30 21:40:12 +00:00 
			
		
		
		
	Refactoring solr/fts migration
When re-indexing everything, skip intermediate populating the index and do this as the very last step. Parameterize adding new fields by their language.
This commit is contained in:
		| @@ -1,5 +1,8 @@ | ||||
| package docspell.ftsclient | ||||
|  | ||||
| import cats.Functor | ||||
| import cats.implicits._ | ||||
|  | ||||
| import docspell.common._ | ||||
|  | ||||
| final case class FtsMigration[F[_]]( | ||||
| @@ -7,7 +10,13 @@ final case class FtsMigration[F[_]]( | ||||
|     engine: Ident, | ||||
|     description: String, | ||||
|     task: F[FtsMigration.Result] | ||||
| ) | ||||
| ) { | ||||
|  | ||||
|   def changeResult(f: FtsMigration.Result => FtsMigration.Result)(implicit | ||||
|       F: Functor[F] | ||||
|   ): FtsMigration[F] = | ||||
|     copy(task = task.map(f)) | ||||
| } | ||||
|  | ||||
| object FtsMigration { | ||||
|  | ||||
|   | ||||
| @@ -126,19 +126,10 @@ object SolrSetup { | ||||
|         lang match { | ||||
|           case None => | ||||
|             run(DeleteField.command(DeleteField(field))).attempt *> | ||||
|               run(AddField.command(AddField.text(field))) | ||||
|           case Some(Language.German) => | ||||
|               run(AddField.command(AddField.textGeneral(field))) | ||||
|           case Some(lang) => | ||||
|             run(DeleteField.command(DeleteField(field))).attempt *> | ||||
|               run(AddField.command(AddField.textDE(field))) | ||||
|           case Some(Language.English) => | ||||
|             run(DeleteField.command(DeleteField(field))).attempt *> | ||||
|               run(AddField.command(AddField.textEN(field))) | ||||
|           case Some(Language.French) => | ||||
|             run(DeleteField.command(DeleteField(field))).attempt *> | ||||
|               run(AddField.command(AddField.textFR(field))) | ||||
|           case Some(Language.Italian) => | ||||
|             run(DeleteField.command(DeleteField(field))).attempt *> | ||||
|               run(AddField.command(AddField.textIT(field))) | ||||
|               run(AddField.command(AddField.textLang(field, lang))) | ||||
|         } | ||||
|     } | ||||
|   } | ||||
| @@ -164,20 +155,11 @@ object SolrSetup { | ||||
|     def string(field: Field): AddField = | ||||
|       AddField(field, "string", true, true, false) | ||||
|  | ||||
|     def text(field: Field): AddField = | ||||
|     def textGeneral(field: Field): AddField = | ||||
|       AddField(field, "text_general", true, true, false) | ||||
|  | ||||
|     def textDE(field: Field): AddField = | ||||
|       AddField(field, "text_de", true, true, false) | ||||
|  | ||||
|     def textEN(field: Field): AddField = | ||||
|       AddField(field, "text_en", true, true, false) | ||||
|  | ||||
|     def textFR(field: Field): AddField = | ||||
|       AddField(field, "text_fr", true, true, false) | ||||
|  | ||||
|     def textIT(field: Field): AddField = | ||||
|       AddField(field, "text_it", true, true, false) | ||||
|     def textLang(field: Field, lang: Language): AddField = | ||||
|       AddField(field, s"text_${lang.iso2}", true, true, false) | ||||
|   } | ||||
|  | ||||
|   case class DeleteField(name: Field) | ||||
|   | ||||
| @@ -14,16 +14,26 @@ object FtsWork { | ||||
|   def apply[F[_]](f: FtsContext[F] => F[Unit]): FtsWork[F] = | ||||
|     Kleisli(f) | ||||
|  | ||||
|   def allInitializeTasks[F[_]: Monad]: FtsWork[F] = | ||||
|     FtsWork[F](_ => ().pure[F]).tap[FtsContext[F]].flatMap { ctx => | ||||
|       NonEmptyList.fromList(ctx.fts.initialize.map(fm => from[F](fm.task))) match { | ||||
|   /** Runs all migration tasks unconditionally and inserts all data as last step. */ | ||||
|   def reInitializeTasks[F[_]: Monad]: FtsWork[F] = | ||||
|     FtsWork { ctx => | ||||
|       val migrations = | ||||
|         ctx.fts.initialize.map(fm => fm.changeResult(_ => FtsMigration.Result.workDone)) | ||||
|  | ||||
|       NonEmptyList.fromList(migrations) match { | ||||
|         case Some(nel) => | ||||
|           nel.reduce(semigroup[F]) | ||||
|           nel | ||||
|             .map(fm => from[F](fm.task)) | ||||
|             .append(insertAll[F](None)) | ||||
|             .reduce(semigroup[F]) | ||||
|             .run(ctx) | ||||
|         case None => | ||||
|           FtsWork[F](_ => ().pure[F]) | ||||
|           ().pure[F] | ||||
|       } | ||||
|     } | ||||
|  | ||||
|   /** | ||||
|     */ | ||||
|   def from[F[_]: FlatMap: Applicative](t: F[FtsMigration.Result]): FtsWork[F] = | ||||
|     Kleisli.liftF(t).flatMap(transformResult[F]) | ||||
|  | ||||
|   | ||||
| @@ -11,6 +11,11 @@ import docspell.joex.Config | ||||
| import docspell.store.records.RFtsMigration | ||||
| import docspell.store.{AddResult, Store} | ||||
|  | ||||
| /** Migrating the index from the previous version to this version. | ||||
|   * | ||||
|   * The sql database stores the outcome of a migration task. If this | ||||
|   * task has already been applied, it is skipped. | ||||
|   */ | ||||
| case class Migration[F[_]]( | ||||
|     version: Int, | ||||
|     engine: Ident, | ||||
|   | ||||
| @@ -46,6 +46,6 @@ object ReIndexTask { | ||||
|               FtsWork.log[F](_.info("Clearing data failed. Continue re-indexing.")) | ||||
|             ) ++ | ||||
|             FtsWork.log[F](_.info("Running index initialize")) ++ | ||||
|             FtsWork.allInitializeTasks[F] | ||||
|             FtsWork.reInitializeTasks[F] | ||||
|       }) | ||||
| } | ||||
|   | ||||
| @@ -4,6 +4,9 @@ import cats.data.Kleisli | ||||
|  | ||||
| package object fts { | ||||
|  | ||||
|   /** Some work that must be done to advance the schema of the fulltext | ||||
|     * index. | ||||
|     */ | ||||
|   type FtsWork[F[_]] = Kleisli[F, FtsContext[F], Unit] | ||||
|  | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user