.. _installation_nouvel_analyseur_elasticsearch:

Recherche exacte sur des champs texte
#####################################

Pour pouvoir effectuer une recherche exacte sur un champ donné de type texte, il faudra un analyseur moins permissif que celui installé par défaut, il est possible d'avoir un second analyseur sur le même champ, pour cela il faudra suivre cette procédure:

.. caution:: il est important d'arrêter les ``services externals`` et ``scheduler`` et s'assurer qu'aucun workflow n'est en cours avant de démarrer cette procédure.

Prenant comme exemple le champ ``Title``.

Ajout du nouvel analyseur
=========================

Pour cela, il faudra ajouter la déclaration du nouvel analyseur dans le fichier de configuration d'elasticsearch qui se trouve ici :

``deployment/ansible-vitam/roles/vitam/files/elasticsearch-settings/elasticsearch-configuration.json``

dans le bloc ``analyzer`` , nous ajoutons un nouvel analyseur nommé par exemple strict_title_analyzer, avec uniquement quelques filtres tels que:
 - lowercase
 - asciifolding
 - html_strip

nous pouvons enréchir l'analyseur avec un stemmer, par exemple pour le français, il existe 3 stemmers:
 - light_french
 - french
 - minimal_french

Dans la configuration par défaut de Vitam, nous utilisons le stemmer ``french`` qui est riche mais très permissif, il est recommandé de tester la configuration de l'analyseur en incluant d'autres filtres, ou stemmers, pour le cas de recherche strict, on peut tester ``minimal_french``

Voici un exemple de configuration d'un analyseur à ajouter dans les paramètres dans le bloc ``analyzer`` du fichier de configuration d'elasticsearch :

.. code-block:: json

    "strict_title_analyzer": {
        "type": "custom",
        "tokenizer": "standard",
        "char_filter": [
            "html_strip"
        ],
        "filter": [
            "lowercase",
            "asciifolding"
        ]
    }

Par convention Vitam, si l'analyseur de recherche exacte est positionné sur un champ nommé **NomDuChamps**:

- la recherche classique se fait sur le critère de recherche "NomDuChamps"
- la recherche exacte se fait sur le critère de recherche "NomDuChamps.Strict"


Voici un autre example d'un analyseur un peu plus permissif que le précédent et moins permissif que celui installé par défaut, celui-ci utilise le stemmer ``minimal_french``:

.. code-block:: json

    "strict_title_analyzer": {
        "type": "custom",
        "tokenizer": "standard",
        "char_filter": [
            "html_strip"
        ],
        "filter": [
            "lowercase",
            "asciifolding",
            "minimal_french"
        ]
    }

Modification du mapping
=======================

Après l'ajout du nouvel analyseur, pour pouvoir l'utiliser, il faudra le référencer dans le mapping elasticsearch.

Pour l'exemple du champ ``Title`` de la collection ``Unit``, il faudra mettre à jour le mapping à travers le fichier

``environments/files/elasticsearch-mappings/unit-es-mapping.json``

.. code-block:: json

    "Title": {
        "type": "text",
        "analyzer": "default",
        "fields": {
            "Strict": {
            "type": "text",
            "analyzer": "strict_title_analyzer"
            }
        }
    }

A l'issue, il faut lancer le playbook de déploiement de :term:`VITAM` (et, si déployé, les extras) avec l'option supplémentaire ``--tags update_vitam_configuration``.

Exemple
-------

.. code-block:: console

      ansible-playbook ansible-vitam/vitam.yml -i environments/hosts.<environnement> --ask-vault-pass --tags update_vitam_configuration
      ansible-playbook ansible-vitam-extra/extra.yml -i environments/hosts.<environnement> --ask-vault-pass --tags update_vitam_configuration

Cette procédure permettra d'appliquer la configuration sur une nouvelle installation, par contre, si on veut appliquer les modifications sur des tenants existants, il faudra une re-indexation à travers la procédure suivante.

Réindexation des indexes liés aux tenants
=========================================

Pour pouvoir appliquer le nouvel analyseur et le nouveau mapping sur un tenant donné, il faudra re-indexer le contenu de l'index du tenant(s) en question.

Voir la documentation associée dans la rubrique : :ref:`reindexation_es`

Exemple
-------

.. code-block:: console

      ansible-playbook ansible-vitam-exploitation/reindex_es_data.yml -i environments/hosts.<environnement> --ask-vault-pass --tags unit -e "vitam_tenant_ids=<tenantsList>"

.. caution:: La purge des anciens index n'est pas réalisée par cette procédure scriptée et est laissée à la charge de l'exploitant.

.. caution:: Si un tenant fait partie d'un groupe de tenant, il faudra re-indexer l'ensemble des tenants

.. caution:: Si à un moment donné on ne souhaite appliquer la réindexation qu'à une sous partie de tenants, lors de certaines MDV on fait des full réindexation (et donc le mapping sera finalement appliqué à l'ensemble).

Configuration du mapping et des types de recherche par tenant et groupe de tenants
==================================================================================

.. caution::  Le mapping personnalisé doit être basé sur le mapping de Vitam étendu conformément à l'ontologie / schéma (responsabilité de l'exploitant, non contrôlé par Vitam).
.. caution::  L'exploitant doit maintenir les indexes personnalisés à chaque migration et/ou mise à jour des ontologies/schéma.
.. caution::  La configuration d'indexation personnalisée, uniquement disponible pour les champs "texte analysés", et les requêtes sont sous la responsabilité de l'utilisateur de l'API. Requêter un mauvais champ ou un index inconnu est à la responsabilité de l'application appelante.

Il est possible de définir de nouveaux analyseurs par tenants et groupe de tenants en personnalisant les mappings associés pour les collections ``Unit`` et ``ObjectGroup``.

Ces mappings personnalisés doivent être placés sous ``environments/files/elasticsearch-mappings/`` au format .json. Ils seront déployés via le rôle ``elasticsearch-mapping``. Une réindexation des tenants impactés sera nécessaire pour les tenants impactés en cas de mise à jour du mapping associés.

Ensuite, la configuration est définies, soit par tenants spécifiques, soit par groupes de tenants à travers la variable ``vitam_elasticsearch_tenant_indexation`` définie dans le fichier de configuration ``environments/group_vars/all/advanced/tenants_vars.yml``.

Les variables permettant de personnaliser ces nouveaux types de recherche :

* ``mappingFile`` : Nom du fichier de mapping à utiliser
* ``customSearch`` : Définition des recherches personnalisées associées au nouveau mapping pour chacun des champs (``fieldpath``)

Ci-dessous un exemple de configuration permettant de définir des mappings personnalisés et avec les types de recherches sur des champs spécifiques :

.. code-block:: yaml

vitam_elasticsearch_tenant_indexation:
  default_config:
    unit:
      mappingFile: custom-unit-es-mapping.json
      customSearch:
        - fieldPath: Title
          types:
            - Strict
            - Minimal
        - fieldPath: Description
          types:
            - SomeSearch
    objectgroup:
      mappingFile: custom-objectgroup-es-mapping.json
      customSearch:
        - fieldPath: Title
          types:
            - Strict
            - Minimal
        - fieldPath: Description
          types:
            - SomeSearch

  dedicated_tenants:
    - tenants: '1, 3, 11-20'
      unit:
        mappingFile: custom-unit-es-mapping.json
        customSearch:
          - fieldPath: Title
            types:
              - Strict
              - Minimal
          - fieldPath: FieldPath1
            types:
              - SomeSearch
              - SomeSearch2
      objectgroup:
        mappingFile: dedicated-objectgroup-es-mapping.json
        customSearch:
          - fieldPath: Title
            types:
              - Minimal
          - fieldPath: DedicatedFieldPath
            types:
              - SomeDedicatedSearch
              - SomeDedicatedSearch2

  grouped_tenants:
    - name: 'grp1'
      tenants: '5-10'
      unit:
        mappingFile: grp1-unit-es-mapping.json
        customSearch:
          - fieldPath: Title
            types:
              - Minimal
          - fieldPath: OtherFieldPath
            types:
              - SomeOtherSearch
              - SomeOtherSearch2
      objectgroup:
        mappingFile: grp1-objectgroup-es-mapping.json
        customSearch:
          - fieldPath: Title
            types:
              - Minimal
          - fieldPath: OtherFieldPath
            types:
              - SomeOtherSearch
              - SomeOtherSearch3

..
