Champ de texteCompatible with Milvus 3.0.x

Dans les applications de recherche basées sur l’IA, la recherche vectorielle permet de trouver des entités sémantiquement similaires, mais l’application a souvent également besoin du texte source original correspondant à chaque résultat. Un modèle de langage à grande échelle (LLM) ou un agent peut utiliser ce texte comme contexte pour lire, citer, résumer ou inclure le résultat dans une invite.

Milvus fournit le type de champ scalaire « TEXT » pour stocker directement de longs textes sources avec les entités. Les valeurs typiques comprennent des passages, des documents longs, le corps d’articles, des tickets et des journaux. Contrairement à « VARCHAR », qui nécessite une longueur maximale fixe ( max_length), « TEXT » ne vous oblige pas à définir une longueur maximale en octets dans le schéma de la collection.

Pour définir un champ « TEXT », définissez « datatype » sur « DataType.TEXT ».

Cette fonctionnalité nécessite Storage V3. Pour obtenir des instructions d’activation et connaître les considérations de compatibilité, consultez la section Storage V3.

common.storage.useLoonFFI La valeur par défaut est « false », ce qui signifie que Storage V3 est désactivé par défaut. Avant de créer une collection contenant un champ « TEXT », définissez ce paramètre sur « true » ; sinon, Milvus rejettera le schéma de collection.

schema.add_field(
    field_name="content",
    datatype=DataType.TEXT,
)

Une fois le champ défini, chaque entité peut inclure une valeur de type chaîne dans ce champ. Vous insérez les valeurs « TEXT » comme pour les autres champs scalaires et vous les récupérez dans les résultats de requête ou de recherche en listant le champ dans « output_fields ».

TEXT Les champs prennent en charge les valeurs nulles. Pour activer cette fonctionnalité, définissez nullable sur True. Pour plus de détails, reportez-vous à la section « Champ pouvant prendre la valeur nulle ».

Restrictions

  • Un champ de type « TEXT » ne peut pas être un champ principal, une clé de partition ou une clé de clustering.
  • TEXT ne peut pas être utilisé comme type d’élément d’un champ « ARRAY », y compris un sous-champ scalaire dans un champ « StructArray ».
  • Dans Milvus 3.0.0, les champs « TEXT » ne prennent pas en charge les valeurs par défaut.
  • Dans Milvus 3.0.0, les champs « TEXT » ne sont pas pris en charge dans les collections externes.
  • Les utilisateurs ne peuvent pas créer d’index scalaire sur un champ « TEXT ». Lorsque le champ est de type « enable_match=True », Milvus crée un index textuel géré par le système pour la correspondance de texte. Cet index interne n’est pas un index scalaire créé par l’utilisateur.
  • Les opérateurs de filtrage scalaires généraux ne peuvent pas être appliqués directement à un champ de type « TEXT ». Il s’agit notamment des opérateurs de comparaison tels que == et !=, des opérateurs de plage tels que >, >=, < et <=, ainsi que IN, LIKE, des opérateurs d’expressions régulières (=~ et !~) et IS NULL ou IS NOT NULL. Pour filtrer par termes analysés, définissez le champ avec enable_analyzer=True et enable_match=True, puis utilisez TEXT_MATCH ou TEXT_MATCH_FUZZY. Pour une recherche en texte intégral classée par pertinence, utilisez BM25.
  • Dans Milvus 3.0.0, une fonction BM25 ou MinHash utilisant un champ « TEXT » en entrée doit être définie lors de la création de la collection. Elle ne peut pas être ajoutée ultérieurement via add_function_field ou AlterCollectionSchema, même si la collection existante est vide, car Milvus ne peut pas remplir a posteriori la sortie de la fonction à partir des valeurs « TEXT » stockées. Pour ajouter une telle fonction à une collection existante, utilisez un champ d’entrée « VARCHAR » ou recréez la collection en incluant la fonction dans son schéma. Pour plus de détails sur l’ajout d’une fonction et de son champ vectoriel généré, reportez-vous à la section « Modifier le schéma d’une collection ».
  • Les fonctions d’embedding de texte doivent également être définies lors de la création de la collection. Milvus 3.0.0 ne prend pas en charge leur ajout lors de l’exécution.

Choisissez TEXT ou VARCHAR

TEXT et « VARCHAR » stockent tous deux des valeurs de type chaîne de caractères, mais répondent à des besoins applicatifs différents. Utilisez « VARCHAR » pour des métadonnées courtes et délimitées qui identifient, classent ou filtrent des entités. Utilisez « TEXT » pour un contenu source plus long qui fournit à un LLM ou à un agent suffisamment de contexte pour lire, citer, résumer ou construire une invite.

AspectVARCHARTEXT
Idéal pourMétadonnées courtes utilisées pour identifier, classer ou filtrer des entités, telles que title, tag, category ou external_id.Contenu source plus long utilisé par les LLM ou les workflows d’agents, tels que content, passage, article_body ou log_message.
Paramètre de longueurNécessite max_length, qui définit le nombre maximal d’octets que le champ peut stocker. La valeur maximale est de 65,535 octets. Si une valeur est susceptible de dépasser cette limite, utilisez TEXT.Ne nécessite pas de paramètre « max_length » ; le schéma n’a donc pas besoin d’une limite d’octets fixe pour la valeur textuelle.
Comportement de stockageChaque valeur est stockée dans la limite de taille configurée pour le champ ( max_length).Utilise la sélection automatique du stockage pour les valeurs de texte plus volumineuses. Pour plus de détails, consultez la section « Comment Milvus stocke les valeurs TEXT volumineuses ».
Prise en charge en tant que champ principalPeut être utilisé comme champ principal.Ne peut pas être utilisé comme champ principal.
FiltrageÀ utiliser pour les métadonnées sous forme de chaînes courtes devant apparaître dans des expressions de filtrage, telles que « category == "news" » ou « tag in ["ai", "database"] ».Ne prend pas en charge les opérateurs de filtrage scalaires généraux. Utilisez des opérateurs textuels avec correspondance pour le filtrage par termes analysés, ou BM25 pour la recherche en texte intégral classée par pertinence.

Pour plus de détails sur les champs de type « VARCHAR », reportez-vous à la section Champ VarChar.

Comment Milvus stocke les valeurs TEXT volumineuses

Développez pour voir comment cela fonctionne

Lorsque vous insérez une entité, la chaîne que vous fournissez pour un champ « TEXT » correspond à la valeur « TEXT ». Milvus compare la taille de cette valeur à dataNode.text.inlineThreshold, qui est de 65,536 octets par défaut, puis choisit l’un des deux chemins de stockage internes.

Large text storage Stockage de texte volumineux

  • Stockage en ligne: si la valeur de ` TEXT ` est inférieure à ` dataNode.text.inlineThreshold`, Milvus stocke la valeur textuelle d’origine directement dans les données du champ ` TEXT `.
  • Stockage LOB: si la valeur d’un champ « TEXT » est supérieure ou égale à dataNode.text.inlineThreshold, Milvus traite cette valeur comme un objet volumineux et stocke le texte d’origine séparément dans un système de stockage d’objets, tel que MinIO. Les données du champ « TEXT » stockent une référence interne vers le texte stocké séparément. Lorsque le champ « TEXT » est demandé dans les résultats d’une requête ou d’une recherche, Milvus utilise cette référence pour récupérer et renvoyer le texte d’origine.

Ce choix de stockage est interne. Vous insérez, interrogez et effectuez des recherches dans le champ « TEXT » de la même manière, quel que soit le chemin de stockage utilisé par Milvus. Pour ajuster le seuil ou le comportement associé en matière de stockage, de compactage et de collecte des données inutiles, reportez-vous aux configurations relatives à dataNode et à celles relatives à dataCoord.

Si votre déploiement utilise un stockage objet, les valeurs « TEXT » volumineuses peuvent apparaître sous forme d’objets gérés par Milvus dans des chemins tels que lobs/.... Ces objets relèvent des détails d’implémentation et ne doivent pas être déplacés, copiés ou supprimés manuellement. Après avoir supprimé des entités, supprimé des partitions ou compacté des données, l’utilisation du stockage d’objets ne diminuera qu’une fois que le ramasse-miettes de Milvus aura supprimé les données de grands objets non référencées, une fois la période de sécurité écoulée.

L’une des utilisations courantes d’ TEXT est la recherche en texte intégral avec BM25. Dans ce modèle, le champ TEXT stocke le contenu source d’origine, tandis que BM25 analyse le texte et génère des vecteurs clairsemés pour classer les correspondances basées sur des mots-clés. Les résultats de recherche peuvent alors renvoyer la valeur TEXT correspondante comme contexte pour les workflows LLM ou d’agents. L’exemple suivant montre comment utiliser un champ « TEXT » comme champ d’entrée pour BM25. Pour en savoir plus sur les concepts de la recherche en texte intégral et les options de requête, consultez la section Recherche en texte intégral.

Étape 1 : Créer une collection avec un champ TEXT

L’exemple suivant crée une collection comportant un champ « TEXT » pour le contenu source et un champ de vecteurs clairsemés pour les vecteurs clairsemés générés par BM25. La fonction BM25 convertit le texte tokenisé de « content » en vecteurs clairsemés stockés dans « sparse ».

Pour la recherche en texte intégral BM25, le champ d’entrée « TEXT » doit être défini sur enable_analyzer=True.

from pymilvus import DataType, Function, FunctionType, MilvusClient

client = MilvusClient(uri="http://localhost:19530")
COLLECTION_NAME = "text_bm25_collection"

if client.has_collection(COLLECTION_NAME):
    client.drop_collection(COLLECTION_NAME)

schema = client.create_schema(auto_id=False, enable_dynamic_field=False)
schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True)
schema.add_field(
    field_name="content",
    datatype=DataType.TEXT,
    enable_analyzer=True,
)
schema.add_field(field_name="sparse", datatype=DataType.SPARSE_FLOAT_VECTOR)

bm25_function = Function(
    name="content_bm25",
    input_field_names=["content"],
    output_field_names=["sparse"],
    function_type=FunctionType.BM25,
)
schema.add_function(bm25_function)

Étape 2 : Créer un index de vecteurs creux

Créez un index sur le champ de vecteurs creux généré par la fonction BM25. Le type de métrique doit être défini sur « BM25 ».

index_params = client.prepare_index_params()
index_params.add_index(
    field_name="sparse",
    index_type="SPARSE_INVERTED_INDEX",
    metric_type="BM25",
    params={
        "inverted_index_algo": "DAAT_MAXSCORE",
        "bm25_k1": 1.2,
        "bm25_b": 0.75,
    },
)

client.create_collection(
    collection_name=COLLECTION_NAME,
    schema=schema,
    index_params=index_params,
)

Étape 3 : Insérer des données TEXT

Insérez le texte directement dans le champ « TEXT ». Ne renseignez pas le champ « sparse ». Milvus génère les vecteurs creux en interne en appliquant la fonction BM25 à « content ».

data = [
    {
        "id": 1,
        "content": "Milvus stores vector embeddings and scalar fields in collections. It supports vector search, full text search, and metadata filtering for retrieval applications.",
    },
    {
        "id": 2,
        "content": "Long documents are often split into passages before embedding. Store each passage in a TEXT field so search results can return the source text.",
    },
    {
        "id": 3,
        "content": "Operational logs and support tickets often contain long natural-language text. TEXT fields can store these values without a fixed max_length setting.",
    },
]

client.insert(collection_name=COLLECTION_NAME, data=data)
client.load_collection(collection_name=COLLECTION_NAME)

Utilisez le texte brut de la requête comme données de recherche et effectuez la recherche sur le champ de vecteur creux. Milvus convertit le texte de la requête en vecteur creux, classe les résultats à l’aide de BM25 et renvoie le champ « TEXT » demandé dans « output_fields ».

results = client.search(
    collection_name=COLLECTION_NAME,
    data=["how does Milvus store source text for retrieval"],
    anns_field="sparse",
    limit=2,
    output_fields=["content"],
)

Étape 5 : Lire les valeurs TEXT renvoyées

Chaque résultat de recherche comprend le score BM25 et la valeur d’ TEXT e d’origine.

for hit in results[0]:
    print(f"id: {hit['id']}, score: {hit['distance']}")
    print(hit["entity"]["content"])

Pour plus d’informations sur les fonctions BM25, les index de vecteurs creux et la syntaxe de requête pour la recherche en texte intégral, consultez la section Recherche en texte intégral.