com.google.cloud.firestore.VectorQuery Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of google-cloud-firestore Show documentation
Show all versions of google-cloud-firestore Show documentation
Java idiomatic client for Google Cloud Firestore.
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.cloud.firestore;
import com.google.api.core.ApiFuture;
import com.google.cloud.Timestamp;
import com.google.firestore.v1.RunQueryRequest;
import com.google.firestore.v1.StructuredQuery;
import com.google.protobuf.ByteString;
import java.util.List;
import java.util.Objects;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* A query that finds the documents whose vector fields are closest to a certain query vector.
* Create an instance of `VectorQuery` with {@link Query#findNearest}.
*/
public final class VectorQuery extends StreamableQuery {
final Query query;
final FieldPath vectorField;
final VectorValue queryVector;
final int limit;
final DistanceMeasure distanceMeasure;
final VectorQueryOptions options;
/** Creates a VectorQuery */
VectorQuery(
Query query,
FieldPath vectorField,
VectorValue queryVector,
int limit,
DistanceMeasure distanceMeasure,
VectorQueryOptions options) {
super(query.rpcContext, query.options);
this.query = query;
this.options = options;
this.vectorField = vectorField;
this.queryVector = queryVector;
this.limit = limit;
this.distanceMeasure = distanceMeasure;
}
/**
* Executes the query and returns the results as {@link QuerySnapshot}.
*
* @return An ApiFuture that will be resolved with the results of the VectorQuery.
*/
@Override
@Nonnull
public ApiFuture get() {
return get(null, null);
}
/**
* Plans and optionally executes this VectorQuery. Returns an ApiFuture that will be resolved with
* the planner information, statistics from the query execution (if any), and the query results
* (if any).
*
* @return An ApiFuture that will be resolved with the planner information, statistics from the
* query execution (if any), and the query results (if any).
*/
@Override
@Nonnull
public ApiFuture> explain(ExplainOptions options) {
return super.explain(options);
}
/**
* Returns true if this VectorQuery is equal to the provided object.
*
* @param obj The object to compare against.
* @return Whether this VectorQuery is equal to the provided object.
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || !(obj instanceof VectorQuery)) {
return false;
}
VectorQuery otherQuery = (VectorQuery) obj;
return Objects.equals(query, otherQuery.query)
&& Objects.equals(vectorField, otherQuery.vectorField)
&& Objects.equals(queryVector, otherQuery.queryVector)
&& Objects.equals(options, otherQuery.options)
&& limit == otherQuery.limit
&& distanceMeasure == otherQuery.distanceMeasure;
}
@Override
public int hashCode() {
return Objects.hash(query, options, vectorField, queryVector, limit, distanceMeasure);
}
@Override
protected RunQueryRequest.Builder toRunQueryRequestBuilder(
@Nullable final ByteString transactionId,
@Nullable final Timestamp readTime,
@Nullable ExplainOptions explainOptions) {
// Builder for the base query
RunQueryRequest.Builder requestBuilder =
query.toRunQueryRequestBuilder(transactionId, readTime, explainOptions);
// Builder for find nearest
StructuredQuery.FindNearest.Builder findNearestBuilder =
requestBuilder.getStructuredQueryBuilder().getFindNearestBuilder();
findNearestBuilder.getQueryVectorBuilder().setMapValue(this.queryVector.toProto());
findNearestBuilder.getLimitBuilder().setValue(this.limit);
findNearestBuilder.setDistanceMeasure(toProto(this.distanceMeasure));
findNearestBuilder.getVectorFieldBuilder().setFieldPath(this.vectorField.toString());
if (this.options != null) {
if (this.options.getDistanceThreshold() != null) {
findNearestBuilder
.getDistanceThresholdBuilder()
.setValue(this.options.getDistanceThreshold().doubleValue());
}
if (this.options.getDistanceResultField() != null) {
findNearestBuilder.setDistanceResultField(this.options.getDistanceResultField().toString());
}
}
return requestBuilder;
}
private static StructuredQuery.FindNearest.DistanceMeasure toProto(
DistanceMeasure distanceMeasure) {
switch (distanceMeasure) {
case COSINE:
return StructuredQuery.FindNearest.DistanceMeasure.COSINE;
case EUCLIDEAN:
return StructuredQuery.FindNearest.DistanceMeasure.EUCLIDEAN;
case DOT_PRODUCT:
return StructuredQuery.FindNearest.DistanceMeasure.DOT_PRODUCT;
default:
return StructuredQuery.FindNearest.DistanceMeasure.UNRECOGNIZED;
}
}
@Override
boolean isRetryableWithCursor() {
return false;
}
@Override
VectorQuery startAfter(@Nonnull DocumentSnapshot snapshot) {
throw new RuntimeException("Not implemented");
}
@Override
VectorQuerySnapshot createSnaphot(
Timestamp readTime, final List documents) {
return VectorQuerySnapshot.withDocuments(this, readTime, documents);
}
/**
* The distance measure to use when comparing vectors in a {@link VectorQuery}.
*
* @see com.google.cloud.firestore.Query#findNearest
*/
public enum DistanceMeasure {
/**
* COSINE distance compares vectors based on the angle between them, which allows you to measure
* similarity that isn't based on the vectors' magnitude. We recommend using DOT_PRODUCT with
* unit normalized vectors instead of COSINE distance, which is mathematically equivalent with
* better performance.
*/
COSINE,
/** Measures the EUCLIDEAN distance between the vectors. */
EUCLIDEAN,
/** Similar to cosine but is affected by the magnitude of the vectors. */
DOT_PRODUCT
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy