Tous les produits
Search
Centre de documentation

Lindorm:Fonctionnalités de base

Dernière mise à jour :Aug 11, 2026

Le moteur vectoriel Lindorm prend en charge la récupération de données vectorielles et la recherche hybride sur des champs scalaires, vectoriels et de texte intégral. Il est compatible avec le protocole Elasticsearch. Cette rubrique explique comment se connecter au moteur vectoriel et l'utiliser à l'aide de la commande curl.

Prérequis

Algorithmes

Sélectionnez un index vectoriel adapté à votre scénario métier en fonction des fonctionnalités et du volume de données pris en charge par chaque algorithme.

Algorithme

Volume de données

Utilisation des ressources

Fonctionnalités

Notes

flat

[0, 10 000)

Mémoire pure.

Recherche par force brute. Simple d'utilisation et adaptée aux petits ensembles de données.

Les performances de recherche diminuent à mesure que le volume de données augmente.

hnsw

[10 000, 1 000 000)

Mémoire pure, utilisation élevée des ressources.

Indexation en ligne. Adaptée aux ensembles de données de taille moyenne et relativement simple d'utilisation.

L'utilisation du processeur dépend du paramètre number_of_shards, qui est généralement défini sur le nombre de nœuds du moteur vectoriel. Si vous disposez d'un grand nombre d'index et que chaque index contient peu de données, définissez number_of_shards sur 1.

hnswq

[10 000, 1 000 000)

Prend en charge les ensembles de données contenant des dizaines de millions de vecteurs dans des scénarios haute performance.

Mémoire pure.

Nouvel algorithme HNSW multicouche développé par Lindorm :

Couche de classement grossier (couche 1) : compresse les vecteurs à l'aide de SQ8 + PCA pour la réduction de dimensionnalité et la quantification.

Couche de classement fin (couche 2) : charge les vecteurs en pleine précision pour reclasser un petit nombre de meilleurs candidats. Cette approche améliore considérablement le débit de recherche sans compromettre le taux de rappel.

  • La quantité de données écrites pour générer l'index doit être supérieure à la dimension du vecteur.

  • Le moteur de recherche et le moteur vectoriel doivent être en version V3.10.15 ou ultérieure. Contactez le support technique Lindorm (ID DingTalk : s0s3eg3) pour effectuer la mise à niveau.

ivfpq

Plus de 1 000 000

Indexation sur disque. Par défaut, le taux de compression 1:8 réduit l'utilisation de la mémoire à un huitième de la taille des données d'origine.

Indexation hors ligne. Vous devez écrire une quantité spécifique de données avant de générer un index. Cette méthode est rentable et adaptée aux grands ensembles de données.

Avant de générer un index, assurez-vous qu'une quantité suffisante de données a été écrite. Le nombre d'enregistrements doit être supérieur à 256 et dépasser 30 fois la valeur de nlist.

Déclenchez la génération de l'index une fois l'importation des données hors ligne terminée. Vous pouvez alors exécuter des requêtes kNN et des opérations d'écriture.

Remarque

Pour plus d'informations sur le paramètre nlist, consultez la section Paramètres.

ivfbq

Plus de 1 000 000

Indexation sur disque. Vous pouvez ajuster l'utilisation de la mémoire en réglant le paramètre exbits.

Pour l'indexation hors ligne, l'algorithme de compression ivf + rabitq convient actuellement mieux aux ensembles de données dont les dimensions de vecteur sont comprises entre 512 et 1024, et offre de meilleures performances que ivfpq.

Le moteur de recherche et le moteur vectoriel doivent être en version V3.10.4 ou ultérieure. Contactez le support technique Lindorm (ID DingTalk : s0s3eg3) pour effectuer la mise à niveau.

Créer un index vectoriel

Créez un index vectoriel où vector1 est une colonne vectorielle et field1 est une colonne standard. La colonne vectorielle et ses paramètres associés doivent être explicitement spécifiés dans la structure mappings lors de la création de l'index.

Index Hnsw

curl -u <username>:<password> -H 'Content-Type: application/json' -XPUT "http://<URL>/vector_test?pretty"  -d '
{
 "settings" : {
    "index": {
      "number_of_shards": 2
    }
  },
  "mappings": {
    "properties": {
      "vector1": {
        "type": "knn_vector",
        "dimension": 3,
        "method": {
          "name": "hnsw", 
          "space_type": "cosinesimil"
       }
      },
      "field1": {
        "type": "long"
      }
    }
  }
}'

Index Hnswq

Important

Pour générer un index HNSWQ, vous devez d'abord écrire une quantité de données supérieure à la dimension du vecteur.

curl -u <username>:<password> -H 'Content-Type: application/json' -XPUT "http://<URL>/vector_hnswq_test?pretty"  -d '
{
 "settings" : {
    "index": {
      "number_of_shards": 2
    }
  },
  "mappings": {
    "properties": {
      "vector1": {
        "type": "knn_vector",
        "dimension": 3,
        "method": {
          "name": "hnswq", 
          "space_type": "cosinesimil"
       }
      },
      "field1": {
        "type": "long"
      }
    }
  }
}'

Index Ivfpq

Important

Lors de la création d'un index IVFPQ, vous devez écrire une quantité suffisante de données avant de générer l'index. Vous ne pouvez exécuter des requêtes qu'une fois l'index généré.

curl -u <username>:<password> -H 'Content-Type: application/json' -XPUT "http://<URL>/vector_ivfpq_test?pretty"  -d '
{
  "settings": {
    "index": {
      "number_of_shards": 2
    }
  },
  "mappings": {
    "properties": {
      "vector1": {
        "type": "knn_vector",
        "dimension": 3,
        "method": {
          "name": "ivfpq",
          "space_type": "cosinesimil",
          "parameters": {
            "nlist": 10000
          }
        }
      },
      "field1": {
        "type": "long"
      }
    }
  }
}'

Index Ivfbq

Important

Lors de la création d'un index IVFBQ, vous devez écrire une quantité suffisante de données avant de générer l'index. Vous ne pouvez exécuter des requêtes qu'une fois l'index généré.

curl -u <username>:<password> -H 'Content-Type: application/json' -XPUT "http://<URL>/vector_ivfbq_test?pretty"  -d '
{
  "settings": {
    "index": {
      "number_of_shards": 2
    }
  },
  "mappings": {
    "properties": {
      "vector1": {
        "type": "knn_vector",
        "dimension": 3,  
        "method": {
          "name": "ivfbq",
          "space_type": "cosinesimil",
          "parameters": {
            "nlist": 10000
          }
        }
      },
      "field1": {
        "type": "long"
      }
    }
  }
}'

Index de vecteurs creux

curl -u <username>:<password> -H 'Content-Type: application/json' -XPUT "http://<URL>/vector_sparse_test?pretty"  -d '
{
 "settings" : {
    "index": {
      "number_of_shards": 2
    }
  },
  "mappings": {
    "properties": {
      "vector1": {
        "type": "knn_vector",
        "method": {
          "name": "sparse_hnsw"
       }
      },
      "field1": {
        "type": "long"
      }
    }
  }
}'

Index avec plusieurs champs vectoriels

curl -u <username>:<password> -H 'Content-Type: application/json' -XPUT "http://<URL>/mvector_test?pretty"  -d '
{
  "settings": {
    "index": {
      "number_of_shards": 2
    }
  },
  "mappings": {
    "properties": {
      "vector1": {
        "type": "knn_vector",
        "dimension": 3,
        "method": {
          "name": "ivfpq",
          "space_type": "cosinesimil",
          "parameters": {
            "nlist": 10000
          }
        }
      },
      "vector2": {
        "type": "knn_vector",
        "dimension": 3,
        "method": {
          "name": "hnsw", 
          "space_type": "cosinesimil"
       }
      },
      "field1": {
        "type": "long"
      }
    }
  }
}'

Index inversé creux

Les index inversés offrent un taux de rappel plus élevé que les index graphiques HNSW, mais leurs performances de recherche sont inférieures. Dans les applications pratiques, vous pouvez ajuster le paramètre threshold_factor (facteur d'ajustement du seuil) comme méthode principale pour équilibrer le taux de rappel et le débit des requêtes (QPS).

curl -u <username>:<password> -H 'Content-Type: application/json' -XPUT "http://<URL>/vector_sparse_inverted_test?pretty"  -d '
{
 "settings" : {
    "index": {
      "number_of_shards": 2
    }
  },
  "mappings": {
    "properties": {
      "vector1": {
        "type": "knn_vector",
        "method": {
          "name": "sparse_inverted_index"
       }
      },
      "field1": {
        "type": "long"
      }
    }
  }
}'

Paramètres

Paramètres de connexion

Paramètre

Obligatoire

Exemple

Description

URL

Oui

ld-bp106782jm96****-proxy-search-vpc.lindorm.aliyuncs.com:30070

L'URL de connexion Elasticsearch-compatible pour LindormSearch. Pour savoir comment obtenir cette URL, consultez la page Adresses compatibles avec Elasticsearch.

username

Oui

xltest

Le nom d'utilisateur et le mot de passe utilisés pour accéder au moteur vectoriel.

Pour obtenir le nom d'utilisateur et le mot de passe par défaut, sélectionnez Database Connections dans le volet de navigation de gauche de la console, puis cliquez sur l'onglet Search Engine. Les identifiants sont fournis dans l'onglet Search Engine.

password

Oui

test

Paramètres de colonne vectorielle

Paramètres généraux

Paramètre

Obligatoire

Description

type

Oui

Le type de la colonne d'index. Pour les colonnes vectorielles, cette valeur est fixée à knn_vector.

dimension

Oui

Le nombre de dimensions du vecteur. Valeurs valides : de 1 à 131 072.

data_type

Non

Le type de données du vecteur. Les types de données suivants sont pris en charge :

  • float

  • float16

  • sparse_vector (ce type est pris en charge uniquement pour un index de vecteurs creux.)

method.name

Oui

L'algorithme d'index vectoriel. Valeurs valides :

  • flat

  • hnsw

  • hnswq

  • ivfpq

  • ivfbq

  • sparse_hnsw (cet algorithme est pris en charge uniquement pour un index de vecteurs creux.)

  • sparse_inverted_index (vecteur creux basé sur un index inversé)

method.space_type

Non

L'algorithme de distance vectorielle. Valeurs valides :

  • l2 (par défaut) : distance euclidienne.

  • cosinesimil : distance cosinus.

  • innerproduct : produit scalaire.

Paramètres de l'algorithme Hnsw

Paramètre

Obligatoire

Description

method.parameters.m

Non

Le nombre maximal d'arêtes sortantes pour chaque couche du graphe.

Plage de valeurs : [1,100]. La valeur par défaut est 24.

method.parameters.ef_construction

Non

La longueur de la liste dynamique lors de la génération de l'index.

Plage valide : [1, 1 000]. La valeur par défaut est 500.

Paramètres de l'algorithme Hnswq

Paramètre

Obligatoire

Description

method.parameters.m

Non

Le nombre maximal d'arêtes sortantes pour chaque couche du graphe.

Plage valide : [1,100]. La valeur par défaut est 24.

method.parameters.ef_construction

Non

La longueur de la liste dynamique lors de la génération de l'index.

Plage de valeurs : [1,1000]. La valeur par défaut est 500.

method.parameters.level_1

Non

L'algorithme de quantification de premier niveau. Valeurs valides :

  • FP32 : virgule flottante 32 bits

  • FP16 : virgule flottante demi-précision 16 bits

La valeur par défaut est FP16.

method.parameters.level_2

Non

L'algorithme de quantification de deuxième niveau. Valeurs valides :

  • NONE

  • FP16 : virgule flottante demi-précision 16 bits, avec une perte de précision mineure.

  • SQ8U : quantification scalaire entière non signée 8 bits, offrant un équilibre entre précision et performance.

  • SQ4U : quantification scalaire entière non signée 4 bits, avec une utilisation minimale de la mémoire.

La valeur par défaut est SQ8U.

method.parameters.pca_level

Non

Indique s'il faut effectuer une réduction de dimensionnalité PCA sur les vecteurs. Valeurs valides :

  • NONE

  • level2 : effectue la PCA uniquement sur level_2.

  • all : effectue la PCA sur level_1 et level_2.

La valeur par défaut est level2.

Paramètres de l'algorithme Ivfpq

Paramètre

Obligatoire

Description

method.parameters.m

Non

Le nombre de sous-espaces dans la quantification. La plage de valeurs valides est [2, 131 072]. La valeur par défaut est dimension.

Important

Lors de la création d'un index IVFPQ, la valeur de ce paramètre doit correspondre à la valeur du paramètre dimension.

method.parameters.nlist

Non

Le nombre de centroïdes de cluster.

La plage valide est [2, 1 000 000]. La valeur par défaut est 10000.

method.parameters.centroids_use_hnsw

Non

Indique s'il faut utiliser l'algorithme HNSW lors de la recherche des centroïdes de cluster.

Valeurs valides :

  • true (par défaut)

  • false

method.parameters.centroids_hnsw_m

Non

Si HNSW est utilisé pour rechercher des centroïdes de cluster, ce paramètre spécifie le nombre maximal d'arêtes sortantes pour chaque couche du graphe.

La plage valide va de 1 à 100. La valeur par défaut est 32.

method.parameters.centroids_hnsw_ef_construct

Non

Si HNSW est utilisé pour rechercher des centroïdes de cluster, ce paramètre spécifie la longueur de la liste dynamique lors de la génération de l'index.

Plage de valeurs : [1,1000]. La valeur par défaut est 500.

method.parameters.centroids_hnsw_ef_search

Non

Si HNSW est utilisé pour rechercher des centroïdes de cluster, ce paramètre spécifie la longueur de la liste dynamique lors d'une requête.

Plage de valeurs : [1,1000]. La valeur par défaut est 200.

Paramètres de l'algorithme Ivfbq

Paramètre

Obligatoire

Description

method.parameters.exbits

Non

Spécifie le nombre de bits supplémentaires pour représenter le vecteur quantifié.

La plage de valeurs est [0, 2, 3, 4, 6, 7, 8]. La valeur par défaut est 0.

Lorsque vous utilisez la quantification Rabitq, plus la valeur de exbits est élevée, plus le taux de rappel et l'utilisation de la mémoire sont importants. Pour équilibrer le taux de rappel et l'utilisation de la mémoire, vous pouvez définir la valeur sur 2.

method.parameters.nlist

Non

Le nombre de centroïdes de cluster.

Valeurs valides : [2, 1 000 000]. La valeur par défaut est 10000.

method.parameters.centroids_use_hnsw

Non

Indique s'il faut utiliser HNSW lors de la recherche des centroïdes de cluster.

Valeurs valides :

  • true (par défaut)

  • false

method.parameters.centroids_hnsw_m

Non

Si HNSW est utilisé pour rechercher des centroïdes de cluster, ce paramètre spécifie le nombre maximal d'arêtes sortantes pour chaque couche du graphe.

Plage valide : [1, 100]. La valeur par défaut est 32.

method.parameters.centroids_hnsw_ef_construct

Non

Si HNSW est utilisé pour rechercher des centroïdes de cluster, ce paramètre spécifie la longueur de la liste dynamique lors de la génération de l'index.

La plage valide est [1, 1 000]. La valeur par défaut est 500.

method.parameters.centroids_hnsw_ef_search

Non

Si HNSW est utilisé pour rechercher des centroïdes de cluster, ce paramètre spécifie la longueur de la liste dynamique lors d'une requête.

Plage valide : [1,1000]. La valeur par défaut est 200.

Supposons que l'index vectoriel soit nommé vector_test. Le résultat est le suivant :

{"acknowledged":true,"shards_acknowledged":true,"index":"vector_test"}

Écrire des données

Vous pouvez écrire des données dans un index contenant des champs vectoriels de la même manière que dans un index standard. Les données vectorielles sont écrites sous forme de tableau de nombres à virgule flottante, par exemple [1.2, 1.3, 1.4].

Écriture unique

curl -u <username>:<password> -H 'Content-Type: application/json' -XPOST "http://<URL>/<index_name>/_doc/1?pretty"  -d '
{"field1": 1, "vector1": [1.2, 1.3, 1.4]}'

Pour un index nommé vector_test, la réponse suivante est renvoyée :

{"_index":"vector_test","_type":"_doc","_id":"1","_version":1,"result":"created","_shards":{"total":1,"successful":1,"failed":0},"_seq_no":0,"_primary_term":1}

Écriture groupée

curl -u <username>:<password> -H 'Content-Type: application/json' -XPUT "http://<URL>/_bulk?pretty"  -d '
{ "index" : { "_index" : "vector_test", "_id" : "2" } }
{ "field1" : 1, "vector1": [2.2, 2.3, 2.4]}
{ "index" : { "_index" : "vector_test", "_id" : "3" } }
{ "field1" : 2, "vector1": [1.2, 1.3, 4.4]}
{ "delete" : { "_index" : "vector_test", "_id" : "2" } }
{ "update" : {"_id" : "1", "_index" : "vector_test"} }
{ "doc" : {"field1" : 3, "vector1": [2.2, 3.3, 4.4]} }
'

Insertion

L'opération échoue si un document portant le même ID existe déjà.

curl -u <username>:<password> -H 'Content-Type: application/json' -XPOST "http://<URL>/_bulk?pretty"  -d '
{ "create" : { "_index" : "vector_test", "_id" : "1" } }
{ "field1" : 1, "vector1": [2.2, 2.3, 2.4]}
{ "create" : { "_index" : "vector_test", "_id" : "2" } }
{ "field1" : 2, "vector1": [1.2, 1.3, 4.4]}
'

Écrasement

Si un document avec l'ID spécifié n'existe pas, un nouveau document est créé. Si un document portant le même ID existe déjà, le document existant est écrasé. Par exemple, si vous écrivez un document ne contenant qu'un champ vectoriel, et qu'une écriture ultérieure pour le même ID ne contient qu'un champ scalaire, le champ vectoriel d'origine est supprimé.

curl -u <username>:<password> -H 'Content-Type: application/json' -XPOST "http://<URL>/_bulk?pretty"  -d '
{ "index" : { "_index" : "vector_test", "_id" : "3" } }
{ "field1" : 1, "vector1": [2.2, 2.3, 2.4]}
{ "index" : { "_index" : "vector_test", "_id" : "4" } }
{ "field1" : 2, "vector1": [1.2, 1.3, 4.4]}
'

Écriture de vecteurs creux

La méthode d'écriture est identique à celle décrite précédemment, mais le format du champ vector1 diffère. Deux formats sont pris en charge : JSON STRING et JSON Object. Le format JSON STRING offre de meilleures performances, tandis que le format JSON Object est plus convivial.

Chaîne JSON

curl -u <username>:<password> -H 'Content-Type: application/json' -XPUT "http://<URL>/vector_sparse_test/_doc/1?pretty"  -d '{
  "field1": 2, 
  "vector1": "{\"indices\": [10, 14, 16], \"values\": [0.5, 0.5, 0.2]}"
}'

Objet JSON

curl -u <username>:<password> -H 'Content-Type: application/json' -XPUT "http://<URL>/vector_sparse_test/_doc/1?pretty"  -d '{
  "field1": 1, 
  "vector1": {"indices": [10, 12, 16], "values": [0.5, 0.5, 0.2]}
}'

Génération d'index

Important
  • Avant de déclencher la génération d'index pour les index ivfpq ou ivfbq, assurez-vous que le volume de données est suffisant. Le volume de données doit être supérieur à 256 enregistrements et dépasser 30 fois la valeur du paramètre nlist.

  • Lorsque vous déclenchez la génération d'index pour un index hnswq, assurez-vous que le volume de données est supérieur à la dimension du vecteur.

  • Après avoir généré manuellement l'index, vous pouvez écrire et interroger des données normalement. Il n'est pas nécessaire de régénérer l'index.

Déclencher la génération d'index

curl -u <username>:<password> -H 'Content-Type: application/json' -XPOST "http://<URL>/_plugins/_vector/index/build"  -d '
{
  "indexName": "vector_ivfpq_test",
  "fieldName": "vector1",
  "removeOldIndex": "true"
}'

Paramètres

Paramètre

Obligatoire

Description

indexName

Oui

Le nom de l'index. Exemple : vector_ivfpq_test.

fieldName

Oui

Le champ à indexer. Exemple : vector1.

removeOldIndex

Oui

Indique s'il faut supprimer l'ancien index lors de la génération d'un nouvel index. Valeurs valides :

  • true : supprime les anciennes données d'index lorsque la génération est déclenchée. Vous ne pouvez exécuter des requêtes kNN qu'une fois le nouvel index généré.

    Important

    Pour les environnements de production, nous vous recommandons de définir ce paramètre sur true.

  • false (par défaut) : conserve l'ancien index. Cela peut affecter les performances de recherche.

Une requête réussie renvoie la réponse suivante :

{
  "payload": ["default_vector_ivfpq_test_vector1"]
}

Le résultat renvoyé correspond à l'identifiant taskId généré par la génération de l'index.

Afficher l'état de l'index

Utilisez la commande suivante pour vérifier l'état de la génération de l'index.

curl -u <username>:<password> -H 'Content-Type: application/json' -XGET "http://<URL>/_plugins/_vector/index/tasks"  -d '{
  "indexName": "vector_ivfpq_test",
  "fieldName": "vector1",
  "taskIds": "[\"default_vector_ivfpq_test_vector1\"]"
}'

Le paramètre taskIds correspond à l'identifiant taskId généré lors du déclenchement d'une génération. Vous pouvez spécifier un tableau vide, par exemple "taskIds": "[]". L'effet est identique à celui obtenu lorsque vous spécifiez une valeur pour taskIds.

Une requête réussie renvoie la réponse suivante :

{
  "payload": ["task: default_vector_ivfpq_test_vector1, stage: FINISH, innerTasks: xxx, info: finish building"]
}

Le champ stage indique l'état de la génération. Les valeurs valides sont START, TRAIN, BUILDING, ABORT, FINISH et FAIL.

Remarque

Vous pouvez appeler l'opération API /index/abort pour arrêter la génération d'un index. Une fois la génération arrêtée, son état passe à ABORT.

Arrêter la génération d'un index

Cette opération arrête le processus de génération de l'index. Vous ne pouvez pas arrêter la génération d'un index dont l'état est FINISH.

curl -u <username>:<password> -H 'Content-Type: application/json' -XPOST "http://<URL>/_plugins/_vector/index/tasks/abort"  -d '{
  "indexName": "vector_ivfpq_test",
  "fieldName": "vector1",
  "taskIds": "[\"default_vector_ivfpq_test_vector1\"]"
}'

Interroger des données

Recherche vectorielle pure

Utilisez la structure de requête knn pour effectuer une recherche vectorielle pure.

curl -u <username>:<password> -H 'Content-Type: application/json' -XGET "http://<URL>/<index_name>/_search?pretty"  -d '
{
  "size": 10,
  "query": {
    "knn": {
      "vector1": {
        "vector": [2.3, 3.3, 4.4],
        "k": 10
      }
    }
  },
  "ext": {"lvector": {"min_score": "0.01"}}
}'

Paramètres

Structure du paramètre

Paramètre

Obligatoire

Description

knn

vector

Oui

Le vecteur de requête.

k

Oui

Le nombre de voisins les plus proches à renvoyer.

Important

Pour les recherches vectorielles pures, définissez les paramètres size et k sur la même valeur.

ext

lvector.min_score

Non

Le seuil de similarité. Seuls les résultats dont le score est supérieur à cette valeur sont renvoyés. Le score vectoriel renvoyé varie de 0 à 1.

Valeurs valides : [0, +inf). Valeur par défaut : 0.

lvector.filter_type

Non

Le mode de requête intégré. Valeurs valides :

  • pre_filter : filtre les données structurées avant la recherche vectorielle.

  • post_filter : effectue la recherche vectorielle, puis filtre les résultats en fonction des données structurées.

  • efficient_filter : le système sélectionne automatiquement pre_filter ou post_filter en fonction d'une estimation interne des coûts.

    Important

    Nécessite Lindorm Search 3.9.10 ou version ultérieure.

Valeur par défaut : efficient_filter.

lvector.ef_search

Non

La longueur de la liste dynamique lors d'une requête. Ce paramètre s'applique uniquement à l'algorithme HNSW.

Valeurs valides : [1, 1 000]. Valeur par défaut : 100.

lvector.nprobe

Non

Le nombre d'unités de cluster à interroger. Une valeur plus élevée améliore le taux de rappel, mais réduit les performances de recherche. Ajustez cette valeur en fonction de vos exigences en matière de taux de rappel.

Valeurs valides : [1, method.parameters.nlist]. Aucune valeur par défaut n'est fournie.

Important

Ce paramètre s'applique uniquement aux algorithmes IVFPQ et IVFBQ.

lvector.reorder_factor

Non

Effectue un reclassement à l'aide des vecteurs d'origine. L'algorithme IVFPQ calcule les distances à partir de vecteurs quantifiés, ce qui peut entraîner une perte de précision. Pour améliorer la précision, activez le reclassement sur les vecteurs d'origine. Le nombre de résultats à reclasser est k * reorder_factor. Ce processus améliore le taux de rappel, mais augmente la charge de performance.

Valeurs valides : [1, 200]. Valeur par défaut : 2.

Important
  • Ce paramètre s'applique uniquement aux algorithmes IVFPQ et IVFBQ.

  • Si k est faible, définissez ce paramètre sur 5. Si k est supérieur à 100, définissez-le sur 1.

lvector.client_refactor

Non

Indique s'il faut effectuer le reclassement à un niveau système supérieur plutôt qu'au sein de chaque shard. Cela peut améliorer les performances. Valeurs valides :

  • true : Oui.

  • false (par défaut) : Non.

lvector. k_expand_scope

Non

Pour une recherche approximative en mode efficient_filter, si le système sélectionne la stratégie post_filter, ce paramètre est utilisé à la place du paramètre k pour étendre la portée de la recherche. La valeur par défaut est 1000.

L'exemple suivant montre une requête sur l'index HNSW vector_test et la sortie correspondante :

Afficher la sortie

{
  "took" : 30,
  "timed_out" : false,
  "terminated_early" : false,
  "num_reduce_phases" : 0,
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "vector_test",
        "_id" : "2",
        "_score" : 1.0
      },
      {
        "_index" : "vector_test",
        "_id" : "1",
        "_score" : 0.25
      },
      {
        "_index" : "vector_test",
        "_id" : "3",
        "_score" : 0.14285715
      }
    ]
  }
}

Renvoyer des champs spécifiques

Pour renvoyer uniquement des champs spécifiques dans les résultats de la requête, spécifiez "_source": ["field1", "field2"] . Pour renvoyer tous les champs non vectoriels, utilisez "_source": true. L'exemple suivant montre comment interroger l'index vector_test :

curl -u <username>:<password> -H 'Content-Type: application/json' -XGET "http://<URL>/vector_test/_search?pretty"  -d '
{
  "size": 10,
  "_source": ["field1"],
  "query": {
    "knn": {
      "vector1": {
        "vector": [2.2, 2.3, 2.4],
        "k": 10
      }
    }
  },
  "ext": {"lvector": {"min_score": "0.01"}}
}'

La requête renvoie la réponse suivante :

Afficher la sortie

{
  "took" : 35,
  "timed_out" : false,
  "terminated_early" : false,
  "num_reduce_phases" : 0,
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "vector_test",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "field1" : 1
        }
      },
      {
        "_index" : "vector_test",
        "_id" : "1",
        "_score" : 0.25,
        "_source" : {
          "field1" : 1
        }
      },
      {
        "_index" : "vector_test",
        "_id" : "3",
        "_score" : 0.14285715,
        "_source" : {
          "field1" : 2
        }
      }
    ]
  }
}

Requête HNSW et HNSWQ

L'exemple suivant montre comment interroger l'index HNSW vector_test :

curl -u <username>:<password> -H 'Content-Type: application/json' -XGET "http://<URL>/vector_test/_search?pretty"  -d '
{
  "size": 10,
  "query": {
    "knn": {
      "vector1": {
        "vector": [2.2, 2.3, 2.4],
        "k": 10
      }
    }
  },
  "ext": {"lvector": {"ef_search": "100"}}
}'

Requête IVFPQ et IVFBQ

Les algorithmes IVFPQ et IVFBQ utilisent les mêmes paramètres de requête. L'exemple suivant montre comment interroger l'index IVFPQ vector_ivfpq_test :

curl -u <username>:<password> -H 'Content-Type: application/json' -XGET "http://<URL>/vector_ivfpq_test/_search?pretty"  -d '
{
  "size": 10,
  "query": {
    "knn": {
      "vector1": {
        "vector": [2.2, 2.3, 2.4],
        "k": 10
      }
    }
  },
  "ext": {"lvector": {"nprobe": "60", "reorder_factor": "2"}}
}'
Important
  • Si k est élevé (par exemple, supérieur à 100), définissez reorder_factor sur 1.

  • Lorsque nlist est égal à 10000, vous pouvez d'abord définir nprobe sur 60 et vérifier les résultats de la recherche. Pour améliorer davantage le taux de rappel, vous pouvez augmenter nprobe à 80, 100, 120, 140 ou 160. La charge de performance liée à l'augmentation de nprobe est bien inférieure à celle liée à l'augmentation de reorder_factor, mais évitez de définir nprobe sur une valeur excessivement élevée.

Requête de vecteurs creux

La méthode de requête est identique, mais le format du champ vector1 diffère. Les vecteurs creux prennent en charge deux formats : JSON String pour de meilleures performances et JSON Object pour une meilleure convivialité.

Chaîne Json

L'exemple suivant montre comment interroger l'index de vecteurs creux vector_sparse_test :

curl -u <username>:<password> -H 'Content-Type: application/json' -XGET "http://<URL>/vector_sparse_test/_search?pretty"  -d '
{
  "size": 10,
  "query": {
    "knn": {
      "vector1": {
        "vector": "{\"indices\": [10, 45, 16], \"values\": [0.5, 0.5, 0.2]}",
        "k": 10
      }
    }
  }
}'

Objet Json

L'exemple suivant montre comment interroger l'index de vecteurs creux vector_sparse_test :

curl -u <username>:<password> -H 'Content-Type: application/json' -XGET "http://<URL>/vector_sparse_test/_search?pretty"  -d '
{
  "size": 10,
  "query": {
    "knn": {
      "vector1": {
        "vector": {"indices": [10, 45, 16], "values": [0.5, 0.5, 0.2]},
        "k": 10
      }
    }
  }
}'

Requête d'index inversé de vecteurs creux

curl -u <username>:<password> -H 'Content-Type: application/json' -XGET "http://ld-t631ui****.lindorm.aliyuncs.com:30070/vector_sparse_inverted_test/_search?pretty"  -d '
{
  "size": 10,
  "query": {
    "knn": {
      "vector1": {
        "vector": "{\"indices\": [10, 45, 16], \"values\": [0.5, 0.5, 0.2]}",
        "k": 10
      }
    }
  },
  "ext": {"lvector": {"search_algo": "max_score", "threshold_factor":"1.5"}}
}'

Voici les paramètres ext.lvector pour les requêtes d'index inversé de vecteurs creux. Pour plus d'informations sur les autres paramètres, consultez la section Descriptions des paramètres.

Paramètre

Description

Valeur par défaut

threshold_factor

Un facteur d'échelle pour le seuil qui contrôle le nombre de listes inversées accessibles. Vous pouvez ajuster cette valeur pour équilibrer le taux de rappel et le QPS. Une valeur plus élevée augmente le QPS, mais peut légèrement réduire le taux de rappel. Une valeur de 1 garantit un taux de rappel de 100 %. La valeur doit être supérieure ou égale à 1.

1

search_algo

L'algorithme de requête. Valeurs valides :

  • max_score : ignore les termes de faible valeur. Convient aux requêtes longues ou aux grandes valeurs de k.

  • wand : utilise l'élagage dynamique pour ignorer les documents à faible score et accélérer la récupération. Convient aux requêtes courtes ou aux petites valeurs de k.

max_score

Requête intégrée

Combinez une recherche vectorielle avec des filtres sur des colonnes standard pour obtenir des résultats plus pertinents. En pratique, le post-filtrage donne souvent de meilleurs résultats de recherche par similarité.

Recherche approximative avec pré-filtrage

Pour filtrer les données structurées avant la recherche vectorielle, ajoutez une clause filter à la requête knn et définissez le paramètre filter_type sur pre_filter.

Remarque

Vous pouvez filtrer un maximum de 10 000 enregistrements de données structurées.

curl -u <username>:<password> -H 'Content-Type: application/json' -XGET "http://<URL>/<index_name>/_search?pretty"  -d '
{
  "size": 10,
  "query": {
    "knn": {
      "vector1": {
        "vector": [2.3, 3.3, 4.4],
        "filter": {
          "range": {
            "field1": {
              "gte": 0
            }
          }
        },
        "k": 10
      }
    }
  },
  "ext": {"lvector": {"filter_type": "pre_filter"}}
}'

Recherche approximative avec post-filtrage

Pour filtrer les résultats après la recherche vectorielle, ajoutez une clause filter à la requête knn et définissez le paramètre filter_type sur post_filter.

Remarque

Lorsque vous utilisez le post-filtrage, vous devrez peut-être augmenter k pour garantir que suffisamment de résultats vectoriels soient récupérés pour le filtrage.

curl -u <username>:<password> -H 'Content-Type: application/json' -XGET "http://<URL>/<index_name>/_search?pretty"  -d '
{
  "size": 10,
  "query": {
    "knn": {
      "vector1": {
        "vector": [2.3, 3.3, 4.4],
        "filter": {
          "range": {
            "field1": {
              "gte": 0
            }
          }
        },
        "k": 10
      }
    }
  },
  "ext": {"lvector": {"filter_type": "post_filter"}}
}'

Lorsque vous utilisez le post-filtrage pour une recherche approximative, vous devez augmenter k. Si vous utilisez l'algorithme IVFPQ, vous devez également ajuster reorder_factor. Par exemple :

curl -u <username>:<password> -H 'Content-Type: application/json' -XGET "http://<URL>/<ivfpq_index_name>/_search?pretty"  -d '
{
  "size": 10,
  "query": {
    "knn": {
      "vector1": {
        "vector": [2.2, 2.3, 2.4],
        "filter": {
          "range": {
            "field1": {
              "gte": 0
            }
          }
        },
        "k": 1000
      }
    }
  },
  "ext": {"lvector": {"filter_type": "post_filter","nprobe": "60", "reorder_factor": "1"}}
}'
Important
  • Dans les scénarios de post-filtrage, vous pouvez augmenter k jusqu'à 10 000, avec un maximum de 20 000, pour maintenir la latence de traitement à quelques centaines de millisecondes. Si k est élevé, définissez reorder_factor sur 1.

  • Avec un nlist de 10000, commencez par définir nprobe sur 60 et vérifiez les résultats de la recherche. Si les résultats ne sont pas satisfaisants, vous pouvez augmenter nprobe à 80, 100, 120, 140 ou 160. L'augmentation de nprobe entraîne moins de charge de performance que l'augmentation de reorder_factor, mais évitez de définir nprobe sur une valeur excessivement élevée.

Vous pouvez également ajouter des conditions de filtre à l'aide de la clause post_filter pour effectuer une recherche approximative avec post-filtrage.

curl -u <username>:<password> -H 'Content-Type: application/json' -XGET "http://<URL>/<index_name>/_search?pretty"  -d '
{
  "size": 10,
  "query": {
    "knn": {
      "vector1": {
        "vector": [2.3, 3.3, 4.4],
        "k": 10
      }
    }
  },
  "post_filter": {
    "range": {
      "field1": {
        "gte": 0
      }
    }
  }
}'

Recherche approximative avec filtrage efficace

Important

Nécessite Lindorm Search 3.9.10 ou version ultérieure. Pour plus d'informations, consultez la page Effectuer une mise à jour de version mineure. Si votre version de Lindorm Search est antérieure à 3.9.10 mais que la console indique que vous utilisez la dernière version, contactez le support technique Lindorm (ID DingTalk : s0s3eg3).

Pour une recherche approximative, vous pouvez choisir explicitement une stratégie de filtrage en définissant le paramètre filter_type sur pre_filter ou post_filter. Pour laisser le système choisir automatiquement, définissez le paramètre filter_type sur efficient_filter, qui utilise une estimation interne des coûts pour sélectionner la stratégie pre_filter ou post_filter.

HNSW et HNSWQ

curl -u <username>:<password> -H 'Content-Type: application/json' -XGET "http://<URL>/<index_name>/_search?pretty"  -d '
{
  "size": 10,
  "query": {
    "knn": {
      "vector1": {
        "vector": [2.2, 2.3, 2.4],
        "filter": {
          "range": {
            "field1": {
              "gte": 0
            }
          }
        },
        "k": 10
      }
    }
  },
  "ext": {"lvector": {"filter_type": "efficient_filter", "ef_search":"
100", "k_expand_scope": "2000"}}
}'
Remarque
  • Nous vous recommandons de définir les paramètres size et k sur la même valeur.

  • Lorsque vous utilisez un index HNSW, vous pouvez augmenter ef_search pour améliorer le taux de rappel, mais cela peut réduire les performances. Par exemple, si la longueur de la liste dynamique est de 100 et qu'un taux de rappel élevé est requis, vous pouvez définir ef_search sur 200.

  • k_expand_scope : si le système sélectionne le mode post_filter, le paramètre k_expand_scope est utilisé à la place du paramètre k.

IVFPQ et IVFBQ

curl -u <username>:<password> -H 'Content-Type: application/json' -XGET "http://<URL>/<index_name>/_search?pretty"  -d '
{
  "size": 10,
  "query": {
    "knn": {
      "vector1": {
        "vector": [2.2, 2.3, 2.4],
        "filter": {
          "range": {
            "field1": {
              "gte": 0
            }
          }
        },
        "k": 10
      }
    }
  },
  "ext": {"lvector": {"filter_type": "efficient_filter","nprobe": "80", "reorder_factor": "2","client_refactor":"true", "k_expand_scope": "2000"}}
}'
Remarque
  • Nous vous recommandons de définir les paramètres size et k sur la même valeur.

  • Avec un nlist de 10000, commencez par définir nprobe sur 60. Si les résultats de la recherche ne sont pas satisfaisants, augmentez nprobe à 80, 100, 120, 140 ou 160. L'augmentation de nprobe entraîne moins de charge de performance que l'augmentation de reorder_factor, mais évitez de définir nprobe sur une valeur excessivement élevée.

  • k_expand_scope : si le système sélectionne le mode post_filter, le paramètre k_expand_scope est utilisé à la place du paramètre k.

Syntaxe de filtre d'attribut

La clause filter ajoute des conditions de filtre et accepte le DSL de requête OpenSearch standard.

"filter": {
  "range": {
    "field1": {
      "gte": 0
    }
  }
}

Plusieurs conditions ET

  • Utilisez bool.must pour exiger que toutes les conditions de la liste soient remplies.

    "filter": {
      "bool": {
        "must": [{
          "range": {
            "field1": {
              "gt": 2
            }
          }
        },
        {
          "term": {
            "field2": "flag2"
          }
        }]
      }
    }
  • Utilisez bool.filter pour exiger que toutes les conditions de la liste soient remplies. Cette clause prend uniquement en compte la correspondance d'un document et n'affecte pas le score. Cette méthode est plus efficace pour les recherches vectorielles et est recommandée.

    "filter": {
      "bool": {
        "filter": [{
          "range": {
            "field1": {
              "gt": 2
            }
          }
        },
        {
          "term": {
            "field2": "flag2"
          }
        }]
      }
    }

Plusieurs conditions OU

"filter": {
  "bool": {
    "should": [{
      "range": {
        "field1": {
          "gt": 2
        }
      }
    },
    {
      "term": {
        "field2": "flag2"
      }
    }]
  }
}

Opérations courantes

Cette section couvre les opérations d'index de base, notamment l'interrogation, la suppression de documents et la suppression d'un index. Les exemples suivants utilisent l'index HNSW vector_test.

  • Interrogez tous les index et leurs volumes de données.

    curl -u <username>:<password> -XGET "http://<URL>/_cat/indices?v"

    Exemple de sortie :

    health status index        uuid        pri rep docs.count docs.deleted store.size pri.store.size
    green  open   vector_test  vector_test 2   0          2            0      6.8kb          6.8kb
  • Interrogez le volume de données d'un index spécifique. Par exemple, la commande suivante interroge l'index vector_test.

    curl -u <username>:<password> -XGET "http://<URL>/vector_test/_count?pretty"

    Exemple de sortie :

    {
      "count" : 2,
      "_shards" : {
        "total" : 2,
        "successful" : 2,
        "skipped" : 0,
        "failed" : 0
      }
    }
  • Affichez les informations de création de l'index.

    curl -u <username>:<password> -XGET "http://<URL>/vector_test?pretty"

    Exemple de sortie :

    Afficher la sortie

    {
      "vector_test" : {
        "aliases" : { },
        "mappings" : {
          "_source" : {
            "excludes" : [
              "vector1"
            ]
          },
          "properties" : {
            "field1" : {
              "type" : "long"
            },
            "vector1" : {
              "type" : "knn_vector",
              "dimension" : 3,
              "data_type" : "float",
              "method" : {
                "engine" : "lvector",
                "space_type" : "l2",
                "name" : "hnsw",
                "parameters" : {
                  "ef_construction" : 200,
                  "m" : 24
                }
              }
            }
          }
        },
        "settings" : {
          "index" : {
            "search" : {
              "slowlog" : {
                "level" : "DEBUG",
                "threshold" : {
                  "fetch" : {
                    "warn" : "1s",
                    "trace" : "200ms",
                    "debug" : "500ms",
                    "info" : "800ms"
                  },
                  "query" : {
                    "warn" : "10s",
                    "trace" : "500ms",
                    "debug" : "1s",
                    "info" : "5s"
                  }
                }
              }
            },
            "indexing" : {
              "slowlog" : {
                "level" : "DEBUG",
                "threshold" : {
                  "index" : {
                    "warn" : "10s",
                    "trace" : "500ms",
                    "debug" : "2s",
                    "info" : "5s"
                  }
                }
              }
            },
            "number_of_shards" : "2",
            "provided_name" : "vector_test",
            "knn" : "true",
            "creation_date" : "1727169417350",
            "number_of_replicas" : "0",
            "uuid" : "vector_test",
            "version" : {
              "created" : "136287927"
            }
          }
        }
      }
    }
  • Supprimez un index entier.

    curl -u <username>:<password>  -XDELETE "http://<URL>/vector_test"
  • Supprimez des documents par requête.

    curl -u <username>:<password> -H 'Content-Type: application/json' -XPOST "http://<URL>/vector_test/_delete_by_query"  -d '
    {
      "query": {
        "term": {
          "field1": 1
        }
      }
    }'