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
Le moteur vectoriel Lindorm est activé. Pour plus d'informations, consultez la page Activation du moteur vectoriel.
LindormSearch est activé. Pour plus d'informations, consultez le Guide d'activation.
L'adresse IP de votre client figure dans la liste d'autorisation de votre instance Lindorm. Pour plus d'informations, consultez la page Configuration d'une liste d'autorisation.
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 |
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. |
|
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 | 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
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
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
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 à |
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 :
|
method.name | Oui | L'algorithme d'index vectoriel. Valeurs valides :
|
method.space_type | Non | L'algorithme de distance vectorielle. Valeurs valides :
|
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 |
|
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 |
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 |
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 |
method.parameters.level_1 | Non | L'algorithme de quantification de premier niveau. Valeurs valides :
La valeur par défaut est FP16. |
method.parameters.level_2 | Non | L'algorithme de quantification de deuxième niveau. Valeurs valides :
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 :
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 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 |
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 :
|
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 |
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 |
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 |
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 Lorsque vous utilisez la quantification Rabitq, plus la valeur de |
method.parameters.nlist | Non | Le nombre de centroïdes de cluster. Valeurs valides : [2, 1 000 000]. La valeur par défaut est |
method.parameters.centroids_use_hnsw | Non | Indique s'il faut utiliser HNSW lors de la recherche des centroïdes de cluster. Valeurs valides :
|
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 |
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 |
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 |
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
Avant de déclencher la génération d'index pour les index
ivfpqouivfbq, 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ètrenlist.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 : |
fieldName | Oui | Le champ à indexer. Exemple : |
removeOldIndex | Oui | Indique s'il faut supprimer l'ancien index lors de la génération d'un nouvel index. Valeurs valides :
|
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.
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 : |
lvector.filter_type | Non | Le mode de requête intégré. Valeurs valides :
Valeur par défaut : | |
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 : | |
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 Valeurs valides : [1, 200]. Valeur par défaut : Important
| |
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 :
| |
lvector. k_expand_scope | Non | Pour une recherche approximative en mode |
L'exemple suivant montre une requête sur l'index HNSW vector_test et la sortie correspondante :
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 :
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"}}
}'
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 sur60et 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 :
|
|
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.
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.
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"}}
}'
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
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"}}
}'
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
100et qu'un taux de rappel élevé est requis, vous pouvez définir ef_search sur200.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"}}
}'
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 sur60. Si les résultats de la recherche ne sont pas satisfaisants, augmentez nprobe à80,100,120,140ou160. 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.mustpour exiger que toutes les conditions de la liste soient remplies."filter": { "bool": { "must": [{ "range": { "field1": { "gt": 2 } } }, { "term": { "field2": "flag2" } }] } } -
Utilisez
bool.filterpour 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 :
-
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 } } }'