-
Notifications
You must be signed in to change notification settings - Fork 76
feat: Added public preview support for full-text search and geo search in Pipelines. #2346
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
4cf8b9d
Initial implementation of search API
MarkDuckworth b002ceb
Spotless and tests
MarkDuckworth 2e4cdf0
Skip search tests on Standard edition
MarkDuckworth 56e09f5
Update copyright. Also fix tests to remove tests of unsupported features
MarkDuckworth 3858f8a
Make FunctionExpression constructor accepting options internal becaus…
MarkDuckworth 1c97c79
spotless
MarkDuckworth 41c12ca
ref doc cleanup
MarkDuckworth f97ef14
Merge branch 'main' of github.com:googleapis/java-firestore into mark…
MarkDuckworth 7fff988
chore: generate libraries at Wed Apr 1 15:51:29 UTC 2026
cloud-java-bot 4f0c0c8
chore: generate libraries at Wed Apr 1 15:54:06 UTC 2026
cloud-java-bot 62e45ae
replaced DSL acronym will full word
MarkDuckworth 21c8bc6
Merge branch 'markduckworth/search' of github.com:googleapis/java-fir…
MarkDuckworth fc16d5a
test cleanup
MarkDuckworth e4e308e
Formatting
MarkDuckworth 8f80056
make QueryEnhancement internal. Test with geoDistance standalone func…
MarkDuckworth 5ae808d
skip search tests unless running against nightly and enterprise
MarkDuckworth f1c656b
Merge branch 'main' into markduckworth/search
MarkDuckworth eea9799
Update pipeline search test setup to only run once for the class. Thi…
MarkDuckworth 7f13efc
Merge branch 'markduckworth/search' of github.com:googleapis/java-fir…
MarkDuckworth File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -121,7 +121,7 @@ public static Expression constant(Timestamp value) { | |
| */ | ||
| @BetaApi | ||
| public static BooleanExpression constant(Boolean value) { | ||
| return equal(new Constant(value), true); | ||
| return new BooleanConstant(new Constant(value)); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -4593,6 +4593,200 @@ public static BooleanExpression isError(Expression expr) { | |
| return new BooleanFunctionExpression("is_error", expr); | ||
| } | ||
|
|
||
| /** | ||
| * Evaluates to the distance in meters between the location in the specified field and the query | ||
| * location. | ||
| * | ||
| * <p>This Expression can only be used within a {@code Search} stage. | ||
| * | ||
| * @param fieldName Specifies the field in the document which contains the first {@link GeoPoint} | ||
| * for distance computation. | ||
| * @param location Compute distance to this {@link GeoPoint}. | ||
| * @return A new {@link Expression} representing the geoDistance operation. | ||
| */ | ||
| @BetaApi | ||
| public static Expression geoDistance(String fieldName, GeoPoint location) { | ||
| return geoDistance(field(fieldName), location); | ||
| } | ||
|
|
||
| /** | ||
| * Evaluates to the distance in meters between the location in the specified field and the query | ||
| * location. | ||
| * | ||
| * <p>This Expression can only be used within a {@code Search} stage. | ||
| * | ||
| * <p>Example: | ||
| * | ||
| * <pre>{@code | ||
| * db.pipeline().collection("restaurants").search( | ||
| * Search.withQuery("waffles").withSort(geoDistance(field("location"), new GeoPoint(37.0, -122.0)).ascending()) | ||
| * ) | ||
| * }</pre> | ||
| * | ||
| * @param field Specifies the field in the document which contains the first {@link GeoPoint} for | ||
| * distance computation. | ||
| * @param location Compute distance to this {@link GeoPoint}. | ||
| * @return A new {@link Expression} representing the geoDistance operation. | ||
| */ | ||
| @BetaApi | ||
| public static Expression geoDistance(Field field, GeoPoint location) { | ||
| return new FunctionExpression( | ||
| "geo_distance", java.util.Arrays.asList(field, constant(location))); | ||
| } | ||
|
|
||
| /** | ||
| * Perform a full-text search on all indexed search fields in the document. | ||
| * | ||
| * <p>This Expression can only be used within a {@code Search} stage. | ||
| * | ||
| * <p>Example: | ||
| * | ||
| * <pre>{@code | ||
| * db.pipeline().collection("restaurants").search(Search.withQuery(documentMatches("waffles OR pancakes"))) | ||
| * }</pre> | ||
| * | ||
| * @param rquery Define the search query using the search domain-specific language (DSL). | ||
| * @return A new {@link BooleanExpression} representing the documentMatches operation. | ||
| */ | ||
| @BetaApi | ||
| public static BooleanExpression documentMatches(String rquery) { | ||
| return new BooleanFunctionExpression("document_matches", constant(rquery)); | ||
| } | ||
|
|
||
| /** | ||
| * Perform a full-text search on the specified field. | ||
| * | ||
| * <p>This Expression can only be used within a {@code Search} stage. | ||
| * | ||
| * <p>Example: | ||
| * | ||
| * <pre>{@code | ||
| * db.pipeline().collection("restaurants").search(Search.withQuery(matches("menu", "waffles"))) | ||
| * }</pre> | ||
| * | ||
| * @param fieldName Perform search on this field. | ||
| * @param rquery Define the search query using the search domain-specific language (DSL). | ||
| */ | ||
| @InternalApi | ||
| static BooleanExpression matches(String fieldName, String rquery) { | ||
| return matches(field(fieldName), rquery); | ||
| } | ||
|
|
||
| /** | ||
| * Perform a full-text search on the specified field. | ||
| * | ||
| * <p>This Expression can only be used within a {@code Search} stage. | ||
| * | ||
| * @param field Perform search on this field. | ||
| * @param rquery Define the search query using the search domain-specific language (DSL). | ||
| */ | ||
| @InternalApi | ||
| static BooleanExpression matches(Field field, String rquery) { | ||
| return new BooleanFunctionExpression("matches", field, constant(rquery)); | ||
| } | ||
|
|
||
| /** | ||
| * Evaluates to the search score that reflects the topicality of the document to all of the text | ||
| * predicates (for example: {@code documentMatches}) in the search query. | ||
| * | ||
| * <p>This Expression can only be used within a {@code Search} stage. | ||
| * | ||
| * <p>Example: | ||
| * | ||
| * <pre>{@code | ||
| * db.pipeline().collection("restaurants").search( | ||
| * Search.withQuery("waffles").withSort(score().descending()) | ||
| * ) | ||
| * }</pre> | ||
| * | ||
| * @return A new {@link Expression} representing the score operation. | ||
| */ | ||
| @BetaApi | ||
| public static Expression score() { | ||
| return new FunctionExpression("score", com.google.common.collect.ImmutableList.of()); | ||
| } | ||
|
|
||
| /** | ||
| * Evaluates to an HTML-formatted text snippet that highlights terms matching the search query in | ||
| * {@code <b>bold</b>}. | ||
| * | ||
| * <p>This Expression can only be used within a {@code Search} stage. | ||
| * | ||
| * <p>Example: | ||
| * | ||
| * <pre>{@code | ||
| * db.pipeline().collection("restaurants").search( | ||
| * Search.withQuery("waffles").withAddFields(snippet("menu", "waffles").as("snippet")) | ||
| * ) | ||
| * }</pre> | ||
| * | ||
| * @param fieldName Search the specified field for matching terms. | ||
| * @param rquery Define the search query using the search domain-specific language (DSL). | ||
| * @return A new {@link Expression} representing the snippet operation. | ||
| */ | ||
| @BetaApi | ||
| public static Expression snippet(String fieldName, String rquery) { | ||
| return new FunctionExpression( | ||
| "snippet", java.util.Arrays.asList(field(fieldName), constant(rquery))); | ||
| } | ||
|
|
||
| /** | ||
| * Evaluates to an HTML-formatted text snippet that highlights terms matching the search query in | ||
| * {@code <b>bold</b>}. | ||
| * | ||
| * <p>This Expression can only be used within a {@code Search} stage. | ||
| * | ||
| * <p>Example: | ||
| * | ||
| * <pre>{@code | ||
| * db.pipeline().collection("restaurants").search( | ||
| * Search.withQuery("waffles").withAddFields(field("menu").snippet("waffles").as("snippet")) | ||
| * ) | ||
| * }</pre> | ||
| * | ||
| * @param rquery Define the search query using the search domain-specific language (DSL). | ||
| * @return A new {@link Expression} representing the snippet operation. | ||
| */ | ||
| @BetaApi | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I need to make this internal because it will not be supported at launch |
||
| public final Expression snippet(String rquery) { | ||
| return new FunctionExpression( | ||
| "snippet", | ||
| java.util.Arrays.asList(this, constant(rquery)), | ||
| java.util.Collections.singletonMap( | ||
| "query", com.google.cloud.firestore.PipelineUtils.encodeValue(rquery))); | ||
| } | ||
|
|
||
| @InternalApi | ||
| static BooleanExpression between(String fieldName, Expression lowerBound, Expression upperBound) { | ||
| return between(field(fieldName), lowerBound, upperBound); | ||
| } | ||
|
|
||
| @InternalApi | ||
| static BooleanExpression between(String fieldName, Object lowerBound, Object upperBound) { | ||
| return between(fieldName, toExprOrConstant(lowerBound), toExprOrConstant(upperBound)); | ||
| } | ||
|
|
||
| @InternalApi | ||
| static BooleanExpression between( | ||
| Expression expression, Expression lowerBound, Expression upperBound) { | ||
| return new BooleanFunctionExpression("between", expression, lowerBound, upperBound); | ||
| } | ||
|
|
||
| @InternalApi | ||
| static BooleanExpression between(Expression expression, Object lowerBound, Object upperBound) { | ||
| return between(expression, toExprOrConstant(lowerBound), toExprOrConstant(upperBound)); | ||
| } | ||
|
|
||
| @InternalApi | ||
| public final BooleanExpression between(Expression lowerBound, Expression upperBound) { | ||
| return Expression.between(this, lowerBound, upperBound); | ||
| } | ||
|
|
||
| @InternalApi | ||
| public final BooleanExpression between(Object lowerBound, Object upperBound) { | ||
| return Expression.between(this, lowerBound, upperBound); | ||
| } | ||
|
|
||
| // Other Utility Functions | ||
| /** | ||
| * Creates an expression that returns the document ID from a path. | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.