# Fonctions de Recherche Fulltext et Vectorielle

{% hint style="info" %}
**Disponible à partir de la version 11.48.0**

Ces fonctions nécessitent que la licence/préférence **OPENSEARCH\_ENABLED** soit activée pour votre organisation. Sans activation, toutes les fonctions lèvent une `RuntimeError("Fulltext search license is missing")`.
{% endhint %}

Fonctions pour rechercher dans les archives de documents, trouver des documents similaires et interroger les données de référence ERP. Elles recherchent dans **tous les documents** de l'organisation — contrairement à `get_document_content()` qui ne lit que le texte du document actuel.

{% hint style="success" %}
**Security:** The `org_id` is automatically injected by the script sandbox. You never need to pass it — your scripts always operate within your own organization's data.
{% endhint %}

**Source :** `module/script/helper/document_script_functions.py`

***

## fulltext\_search()

Recherche dans le texte OCR complet de **tous les documents** de l'organisation.

```python
fulltext_search(query, **kwargs)
```

**Paramètres :**

| Nom           | Type  | Défaut           | Description                                                                                                                       |
| ------------- | ----- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `query`       | `str` | obligatoire      | Terme de recherche (recherché dans le texte OCR de tous les documents)                                                            |
| `search_type` | `str` | `"match_phrase"` | `"match_phrase"` (phrase exacte), `"fuzzy"` (tolérant aux erreurs, jusqu'à 2 caractères de différence), `"prefix"` (commence par) |
| `doc_type`    | `str` | `None`           | Filtrer par type de document (séparé par des virgules, ex. `"INVOICE,CREDIT_NOTE"`)                                               |
| `status`      | `str` | `None`           | Filtrer par statut de document (séparé par des virgules, ex. `"ready_for_validation,exported"`)                                   |
| `vendor_name` | `str` | `None`           | Filtrer par nom du fournisseur                                                                                                    |
| `date_range`  | `str` | `None`           | `"last_30_days"`, `"last_90_days"`, `"last_180_days"`, `"last_365_days"`                                                          |
| `size`        | `int` | `10`             | Nb. max de résultats (limité à 50)                                                                                                |

**Retourne :** `list[dict]` — Chaque dict contient :

| Champ          | Description                                                  |
| -------------- | ------------------------------------------------------------ |
| `doc_id`       | UUID du document                                             |
| `name`         | Nom du fichier (ex. `"INV-2026-001.pdf"`)                    |
| `doc_type`     | Type de document (`"INVOICE"`, `"ORDER_CONFIRMATION"`, etc.) |
| `vendor_name`  | Nom du fournisseur                                           |
| `status`       | Statut du document                                           |
| `total_amount` | Montant total                                                |
| `ocr_content`  | Extrait de texte correspondant du document                   |
| `highlights`   | Dict avec les correspondances surlignées par champ           |

**Exemple — Recherche de phrase exacte :**

```python
results = fulltext_search("REVERSE CHARGE",
                          doc_type="INVOICE", size=10)
for doc in results:
    print(doc["name"], doc["ocr_content"])
```

**Exemple — Recherche floue (tolérante aux erreurs OCR) :**

```python
results = fulltext_search("REVERSE CHARGE",
                          search_type="fuzzy",
                          vendor_name="ACME Corp")
```

**Exemple — Recherche par préfixe :**

```python
results = fulltext_search("Rechn", search_type="prefix",
                          date_range="last_90_days")
```

{% hint style="warning" %}
**Requête vide :** Passer une chaîne vide retourne `[]` immédiatement sans effectuer d'appel HTTP.
{% endhint %}

{% hint style="info" %}
**Gestion des erreurs :** Si le service fulltextsearch est inaccessible, la fonction retourne `[]` et enregistre un avertissement. Elle ne lève **pas** d'exception.
{% endhint %}

***

## vector\_search()

Trouve des documents sémantiquement similaires à l'aide d'embeddings vectoriels (recherche k-NN avec des vecteurs à 384 dimensions).

```python
vector_search(doc_id, **kwargs)
```

**Paramètres :**

| Nom      | Type  | Défaut      | Description                                              |
| -------- | ----- | ----------- | -------------------------------------------------------- |
| `doc_id` | `str` | obligatoire | UUID du document source                                  |
| `k`      | `int` | `5`         | Nombre de documents similaires à retourner (limité à 50) |

**Retourne :** `list[dict]` — Chaque dict contient : `doc_id`, `name`, `doc_type`, `similarity_score` (0-1), `similarity_percent` (0-100).

**Exemple :**

```python
doc_id = document_json["doc_id"]
similar = vector_search(doc_id, k=5)
for doc in similar:
    print(f"{doc['name']}: {doc['similarity_percent']}% similaire")
```

{% hint style="info" %}
**Fonctionnement :** Chaque document est converti en vecteur à 384 dimensions lors de l'indexation. La recherche vectorielle trouve les voisins les plus proches dans cet espace vectoriel.
{% endhint %}

***

## fulltext\_search\_erp()

Recherche dans les données de référence ERP (fournisseurs, commandes d'achat, clients, matériaux) indexées dans OpenSearch.

```python
fulltext_search_erp(query, **kwargs)
```

**Paramètres :**

| Nom             | Type  | Défaut      | Description                                                                                                      |
| --------------- | ----- | ----------- | ---------------------------------------------------------------------------------------------------------------- |
| `query`         | `str` | obligatoire | Terme de recherche                                                                                               |
| `entity_types`  | `str` | `None`      | Filtrer par type d'entité (séparé par des virgules : `"vendor"`, `"purchase_order"`, `"customer"`, `"material"`) |
| `vendor_number` | `str` | `None`      | Filtrer par numéro de fournisseur                                                                                |
| `vendor_name`   | `str` | `None`      | Filtrer par nom du fournisseur                                                                                   |
| `company_code`  | `str` | `None`      | Filtrer par code société                                                                                         |
| `size`          | `int` | `10`        | Nb. max de résultats (limité à 50)                                                                               |

**Exemple — Valider un fournisseur dans l'ERP :**

```python
vendor = get_field_value(document_data, "supplier_name", "")
if vendor:
    matches = fulltext_search_erp(vendor,
                                   entity_types="vendor", size=5)
    if not matches:
        set_field_as_invalid(document_data, "supplier_name",
                             "Fournisseur introuvable dans les données ERP")
```

***

## fulltext\_suggestions()

Retourne des suggestions d'autocomplétion pour les termes de recherche.

```python
fulltext_suggestions(query, **kwargs)
```

**Paramètres :**

| Nom     | Type  | Défaut      | Description                                        |
| ------- | ----- | ----------- | -------------------------------------------------- |
| `query` | `str` | obligatoire | Préfixe / terme de recherche                       |
| `limit` | `int` | `10`        | Nb. max de suggestions par catégorie (limité à 20) |

**Exemple :**

```python
suggestions = fulltext_suggestions("ACM", limit=5)
vendor_list = suggestions.get("vendors", [])
```

***

## Référence Rapide

| Fonction                           | Objectif                                        | Retourne     |
| ---------------------------------- | ----------------------------------------------- | ------------ |
| `fulltext_search(query, ...)`      | Rechercher le texte OCR dans tous les documents | `list[dict]` |
| `vector_search(doc_id, ...)`       | Trouver des documents sémantiquement similaires | `list[dict]` |
| `fulltext_search_erp(query, ...)`  | Rechercher dans les données ERP                 | `list[dict]` |
| `fulltext_suggestions(query, ...)` | Suggestions d'autocomplétion                    | `dict`       |

***

## Schémas Courants

### Vérification de Licence

```python
try:
    results = fulltext_search("test")
except RuntimeError:
    results = []
```

### Combinaison avec les Fonctions de Champ

```python
invoice_number = get_field_value(document_data, "invoice_id", "")
results = fulltext_search(invoice_number,
                          status="exported", size=1)
if results:
    set_field_as_invalid(document_data, "invoice_id",
                         f"Existe déjà : {results[0]['name']}")
else:
    set_field_as_valid(document_data, "invoice_id", "Aucun doublon trouvé")
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs-fr.docbits.com/administration-and-setup/settings/global-settings/document-types/script/scripting-in-docbits/fulltext-search-functions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
