Débloquez des moteurs de recommandation avancés grâce à la nouvelle recherche par plage de Milvus
Introduction
Dans la recherche de similarité, les développeurs ont souvent besoin d’aide concernant les limitations, en particulier lorsqu’il s’agit d’équilibrer la qualité et la diversité des résultats de recherche. Découvrez la nouvelle fonctionnalité de Milvus : Range Search. Cet article présentera ce qu’est Range Search, quand l’utiliser plutôt que la recherche Top-K traditionnelle, et examinera en détail son architecture technique et son guide d’utilisation.
Qu’est-ce que Range Search ?
Range Search dans Milvus offre un contrôle granulaire de la similarité vectorielle dans les résultats de recherche, vous permettant de spécifier une plage de distance pour les vecteurs pertinents. Cette fonctionnalité répond aux limitations des recherches KNN traditionnelles dans les systèmes de recommandation, où les résultats peuvent être soit trop similaires, soit trop divers par rapport à vos attentes.
Quand choisir range search plutôt que Top-K search ?
La recherche KNN traditionnelle présente deux lacunes fondamentales :
Recommandations déséquilibrées : Elle peut recommander des éléments trop similaires, ce qui affecte la qualité des recommandations. Par exemple, un agrégateur d’actualités sportives pourrait finir par recommander à un utilisateur plusieurs articles sur le même match de football, simplement parce qu’il a lu un article sur ce match. Cela pourrait évincer du contenu diversifié, rendant les recommandations répétitives et moins attrayantes.
Contraintes système : Le paramètre Top-K est plafonné à 16 384, ce qui pose des problèmes pour les requêtes de données à grande échelle et l’utilisation des ressources. Imaginez un scénario dans lequel vous interrogez un jeu de données de millions de produits. La limite Top-K de 16 384 signifie que vous pourriez passer à côté de milliers de produits pertinents susceptibles d’intéresser l’utilisateur, tout en sollicitant fortement vos ressources système lorsqu’il tente de traiter et de transmettre ce grand volume de données.
Range Search résout ces problèmes. Elle permet d’obtenir un ensemble équilibré de résultats en vous permettant de définir une plage de distance pour la similarité vectorielle. L’ajout de paramètres comme radius et le paramètre facultatif range_filter offre un contrôle plus nuancé, éliminant le besoin de filtrage après requête. Ce contrôle nuancé rend Range Search idéale pour les applications nécessitant un contrôle précis des résultats de recherche.
Détails techniques derrière Range Search
Maintenant que nous avons exploré ce qu’est Range Search et quand l’utiliser, plongeons dans son architecture et ses algorithmes. Cette exploration fournira des informations essentielles sur ses forces, ses limites et son intégration avec des bibliothèques tierces.
Le flux Range Search s’appuie sur le flux Search existant, réutilisant la plupart des voies de données aux niveaux supérieurs. Voici un aperçu des étapes suivies lorsqu’une requête de recherche est reçue :
Le SDK traite la requête de recherche : Le SDK reçoit une requête de recherche utilisateur contenant des paramètres comme radius et range_filter.
Le proxy génère SearchTask : À la réception de la requête de recherche, le proxy crée une SearchTask et la transmet au nœud de requête.
Du Querynode à Segcore : Le nœud de requête invoque l’interface Search dans Segcore via un appel cgo.
Analyse par Segcore : Segcore analyse les paramètres dans search_param. Si un paramètre radius est présent, il invoque knowhere::RangeSearch.
Knowhere et bibliothèques tierces : Knowhere (le moteur d’exécution vectorielle central de Milvus) achemine ensuite l’appel vers la fonction range_search de la bibliothèque tierce correspondante, en fonction du type d’index.
Tous les index de bibliothèques tierces que nous prenons en charge sont configurés pour effectuer une Range Search unilatérale. « Unilatérale » signifie qu’ils n’acceptent qu’un seul paramètre 'radius' et renvoient tous les résultats non triés dans ce rayon. Le tableau ci-dessous présente les stratégies Range Search pour différents types d’index.
| Type d’index | Stratégie de recherche |
|---|---|
| IDMAP / BIN_IDMAP | Recherche par force brute |
| IVF_xxx / SCANN / BIN_IVF_xxx (mis à jour) | Commencez la recherche à partir du compartiment le plus proche du point central. Arrêtez la recherche lorsque l’une des conditions suivantes est remplie : 1. Tous les compartiments ont été recherchés 2. Aucun vecteur répondant à la condition n’est trouvé dans un compartiment. |
| HNSW (développé en interne) | Commencez la recherche à partir de la couche supérieure et identifiez le vecteur le plus proche de la cible, puis passez à la couche inférieure suivante. Continuez ce processus couche par couche jusqu’à atteindre le plus proche voisin dans la couche la plus basse (1re). À partir de là, effectuez une recherche en largeur (BFS) en commençant par ce plus proche voisin et en continuant jusqu’à ce que tous les points visités et leurs voisins sortants se trouvent en dehors de la plage souhaitée. |
| DISKANN | Commencez avec l_search = min_l_search. À chaque itération, définissez l_search = 2 * l_search. Arrêtez la recherche lorsque l’une des conditions suivantes est remplie : 1. Le nombre de résultats renvoyés dans une itération est inférieur à l_search / 2 2. l_search > max_l_search. |
Les types de métriques HAMMING et JACCARD offrent tous deux une prise en charge complète de la recherche par plage pour les types de données binaires. Cependant, les types de métriques SUBSTRUCTURE/SUPERSTRUCTURE sont incompatibles avec la recherche par plage, car leur sémantique repose sur un système de valeurs vrai/faux. Quant aux index de type float, ceux qui utilisent les métriques L2, IP et COSINE sont entièrement compatibles avec la recherche par plage.
Le tableau ci-dessous présente en détail les types d’index et de métriques compatibles avec la recherche par plage.
| L2 | IP | COSINE | HAMMING | JACCARD | SUBSTRUCTURE | SUPERSTRUCTURE | |
|---|---|---|---|---|---|---|---|
| BIN_IDMAP | √ | √ | |||||
| BIN_IVF_FLAT | √ | √ | |||||
| IDMAP | √ | √ | √ | ||||
| IVF_FLAT | √ | √ | √ | ||||
| IVF_PQ | √ | √ | √ | ||||
| IVF_SQ8 | √ | √ | √ | ||||
| HNSW | √ | √ | √ | √ | √ | ||
| SCANN | √ | √ | √ | ||||
| DISKANN | √ | √ | √ |
Comment utiliser la recherche par plage dans Milvus
Pour utiliser la recherche par plage dans Milvus, vous devrez modifier les paramètres de recherche dans votre requête de recherche. Voici un guide étape par étape, incluant un exemple d’extrait de code Python :
Prérequis
Assurez-vous que Milvus est installé et en cours d’exécution.
Assurez-vous d’avoir créé une collection et de l’avoir indexée.
Paramètres importants de la recherche par plage
radius : Il s’agit d’un paramètre obligatoire qui détermine si la requête de recherche effectuera une recherche par plage ou une recherche classique.
range_filter : Il s’agit d’un paramètre facultatif. S’il est fourni, il effectuera un filtrage secondaire sur les résultats. S’il n’est pas spécifié, la fonction renverra directement les résultats.
En configurant ces deux paramètres, vous pouvez affiner le comportement de vos requêtes de recherche par plage pour différents besoins applicatifs. Dans cet esprit, examinons un exemple de code pour vous aider à démarrer.
default_index = {
"index_type": "HNSW",
"metric_type": "L2",
"params": {"M":48,"efConstruction":500}
}
collection.create_index("float_vector", default_index)
search_params = {
"metric_type": "L2",
"limit": TOPK,
"params": {"ef":32,"range_filter":1.0,"radius":2.0}
}
res = collection.search(vectors[:nq], "float_vector", search_params, limit)
Considérations relatives aux métriques
Maintenant que vous comprenez comment utiliser la recherche par plage, il est essentiel de prendre en compte l’impact des types de métriques sur vos requêtes. Selon le type de métrique que vous choisissez, vous devez vérifier le Radius comme nous l’avons suggéré dans le tableau ci-dessous.
| Type de métrique | Rayon | Similaire | Non similaire |
|---|---|---|---|
| L2 | [0.0, inf] | 0.0 | inf |
| IP | [-inf, inf] | inf | -inf |
| COSINE | [-1.0, 1.0] | 1.0 | -1.0 |
| HAMMING | [0, n] | 0 | n |
| JACCARD | [0.0, 1.0] | 0.0 | 1.0 |
De plus, le range_filter doit respecter les règles suivantes :
Pour L2/Hamming/Jaccard, range_filter < radius
Pour IP/Cosine, range_filter > radius
Conclusion
La recherche par plage dans Milvus ne se limite pas aux moteurs de recommandation ; elle a des applications plus larges dans des domaines tels que la correspondance de contenu, la détection d’anomalies et les tâches de recherche NLP. En exploitant des paramètres comme radius et range_filter, vous pouvez adapter précisément vos requêtes à ces divers cas d’utilisation.
Prêt à prendre le contrôle de vos requêtes de recherche ? La recherche par plage est désormais disponible en aperçu public sur Zilliz Cloud. Passez à la version bêta de Zilliz Cloud ou téléchargez Milvus 2.3.x pour l’essayer. Vos retours sont essentiels à son amélioration continue, donc si vous rencontrez des problèmes ou avez des suggestions, nous sommes à votre écoute. Améliorons ensemble la recherche par plage.
Continuer à lire

Introducing Loon: A New Storage Engine for Vector Data That Never Stops Changing
Loon is a new storage engine for Milvus 3.0 and Zilliz Vector Lakebase, built to manage evolving vector datasets with ColumnGroups, row ID alignment, and Manifests.

From Vector Database to Vector Lakebase
Zilliz offers a fully managed Vector Lakebase powered by Milvus, unifying real-time vector search, lake-scale discovery, and Al data operations.

Zilliz Cloud Now Available in AWS Europe (Ireland)
Zilliz Cloud launches in AWS eu-west-1 (Ireland) — bringing low-latency vector search, EU data residency, and full GDPR-ready infrastructure to European AI teams. Now live across 30 regions on five cloud providers.



