Description
Effectue une recherche vectorielle des plus proches voisins dans le champ embedding donné à l'aide de
la distance_measure.
Exemples
Node.js
const results = await db.pipeline() .collection("cities") .findNearest({ field: "embedding", vectorValue: [1.5, 2.345], distanceMeasure: "euclidean" }) .execute();
Web
const results = await execute(db.pipeline() .collection("cities") .findNearest({ field: "embedding", vectorValue: [1.5, 2.345], distanceMeasure: "euclidean" }));
Swift
let results = try await db.pipeline() .collection("cities") .findNearest( field: Field("embedding"), vectorValue: VectorValue([1.5, 2.345]), distanceMeasure: .euclidean ) .execute()
Kotlin
val results = db.pipeline() .collection("cities") .findNearest( "embedding", doubleArrayOf(1.5, 2.345), FindNearestStage.DistanceMeasure.EUCLIDEAN ) .execute()
Java
Task<Pipeline.Snapshot> results = db.pipeline() .collection("cities") .findNearest( "embedding", new double[] {1.5, 2.345}, FindNearestStage.DistanceMeasure.EUCLIDEAN ) .execute();
Python
from google.cloud.firestore_v1.vector import Vector from google.cloud.firestore_v1.base_vector_query import DistanceMeasure results = ( client.pipeline() .collection("cities") .find_nearest( field="embedding", vector_value=Vector([1.5, 2.345]), distance_measure=DistanceMeasure.EUCLIDEAN, ) .execute() )
Java
Pipeline.Snapshot results = firestore .pipeline() .collection("cities") .findNearest( "embedding", new double[] {1.5, 2.345}, FindNearest.DistanceMeasure.EUCLIDEAN, new FindNearestOptions()) .execute() .get();
Comportement
Mesure de distance
L'étape find_nearest(...) accepte les options suivantes pour la distance vectorielle :
euclidean: mesure la distanceeuclideanentre les vecteurs. Pour en savoir plus, consultez la section Euclidienne.cosine: compare les vecteurs en fonction de l'angle entre eux, ce qui vous permet de mesurer la similarité qui n'est pas basée sur l'amplitude des vecteurs. Nous vous recommandons d'utiliserdot_productavec des vecteurs normalisés unitaires au lieu de la distance COSINE, qui est mathématiquement équivalente avec de meilleures performances. Pour en savoir plus, consultez la section Similarité cosinus.dot_product: semblable àcosine, mais affecté par l'amplitude des vecteurs. Pour en savoir plus, consultez la section Produit scalaire.
Choisir la mesure de distance
Selon que tous vos embeddings vectoriels sont normalisés ou non, vous pouvez déterminer la mesure de distance à utiliser pour trouver la mesure de distance. Un embedding vectoriel normalisé a une amplitude (longueur) de 1,0 exactement.
De plus, si vous savez avec quelle mesure de distance votre modèle a été entraîné, utilisez-la pour calculer la distance entre vos embeddings vectoriels.
Données normalisées
Si vous disposez d'un ensemble de données dans lequel tous les embeddings vectoriels sont normalisés, les trois mesures de distance fournissent les mêmes résultats de recherche sémantique. En substance, bien que chaque mesure de distance renvoie une valeur différente, ces valeurs sont triées de la même manière. Lorsque les embeddings sont normalisés, dot_product est généralement le plus efficace en termes de calcul, mais la différence est négligeable dans la plupart des cas. Toutefois, si votre application est très sensible aux performances, dot_product peut vous aider à les optimiser.
Données non normalisées
Si vous disposez d'un ensemble de données dans lequel les embeddings vectoriels ne sont pas normalisés, il n'est pas mathématiquement correct d'utiliser dot_product comme mesure de distance, car le produit scalaire ne mesure pas la distance. Selon la façon dont les embeddings ont été générés et le type de recherche préféré, la mesure de distance cosine ou euclidean produit des résultats de recherche qui sont subjectivement meilleurs que les autres mesures de distance.
Il peut être nécessaire d'expérimenter avec cosine ou euclidean pour déterminer la meilleure option pour votre cas d'utilisation.
Vous ne savez pas si les données sont normalisées ou non
Si vous ne savez pas si vos données sont normalisées ou non et que vous souhaitez utiliser dot_product, nous vous recommandons d'utiliser cosine à la place.
cosine est semblable à dot_product, mais avec une normalisation intégrée.
La distance mesurée à l'aide de cosine varie de 0 à 2. Un résultat proche de 0 indique que les vecteurs sont très similaires.
Limiter les résultats
Vous pouvez limiter le nombre de documents renvoyés par la requête en définissant le limit champ.
Node.js
const results = await db.pipeline()
.collection("cities")
.findNearest({
field: "embedding",
vectorValue: vector([1.5, 2.345]),
distanceMeasure: "euclidean",
limit: 10,
})
.execute();
Récupérer la distance vectorielle calculée
Vous pouvez récupérer la distance vectorielle calculée en attribuant un
distance_field nom de propriété de sortie à l'étape find_nearest(...),
comme illustré dans l'exemple suivant :
Par exemple, pour la collection suivante :
Node.js
await db.collection("cities").doc("SF").set({name: "San Francisco", embedding: vector([1.0, -1.0])});
await db.collection("cities").doc("TO").set({name: "Toronto", embedding: vector([5.0, -10.0])});
await db.collection("cities").doc("AT").set({name: "Atlantis", embedding: vector([2.0, -4.0])});
Effectuez une recherche vectorielle avec une sortie demandée distance_field :
Node.js
const results = await db.pipeline()
.collection("cities")
.findNearest({
field: "embedding",
vectorValue: vector([1.3, 2.345]),
distanceMeasure: "euclidean",
distanceField: "computedDistance",
})
.execute();
Résultat :
{name: "San Francisco", embedding: vector([1.0, -1.0]), computedDistance: 3.3584259705999178},
{name: "Atlantis", embedding: vector([2.0, -4.0]), computedDistance: 6.383496299051172},
{name: "Toronto", embedding: vector([5.0, -10.0]), computedDistance: 12.887553103673328}
Limites
Lorsque vous utilisez des embeddings vectoriels, tenez compte de la limite suivante :
- La dimension d'embedding maximale acceptée est de 2 048. Pour stocker des index plus volumineux, utilisez la réduction de dimensionnalité.