Skip to content

feat(firestore): pipeline subqueries#14365

Merged
bhshkh merged 2 commits intogoogleapis:mainfrom
bhshkh:feat/fspq-join-subquery
Apr 6, 2026
Merged

feat(firestore): pipeline subqueries#14365
bhshkh merged 2 commits intogoogleapis:mainfrom
bhshkh:feat/fspq-join-subquery

Conversation

@bhshkh
Copy link
Copy Markdown
Contributor

@bhshkh bhshkh commented Apr 6, 2026

Overview
This PR introduces support for pipeline subqueries, variable definitions, and joins in the Go Firestore SDK, achieving strict 1:1 feature parity with the Java SDK's pipeline APIs googleapis/java-firestore#2323.
Another reference PR: googleapis/google-cloud-python#16470

What are Subqueries?
In Firestore pipelines, subqueries allow you to embed an entire pipeline execution as a value within a single stage of an outer pipeline. This is incredibly powerful for performing complex "join-like" operations across different collections.

For example, while querying a restaurants collection, you can use a subquery to fetch, filter, and aggregate all documents from a nested reviews subcollection, and embed that aggregated result (e.g., average_rating) directly into the restaurant document being returned. Subqueries can be
evaluated into either an array of results (ToArrayExpression()) or a single scalar value (ToScalarExpression()).

Key Features & API Additions:

  • Subqueries (Joins):
    • Implemented the Subcollection(path string) package-level function to instantiate relative-scope pipelines.
    • Added ToScalarExpression() and ToArrayExpression() methods on Pipeline to explicitly convert subqueries into expressions, allowing them to be seamlessly embedded inside stages like AddFields and Where.
  • Variable Definition & References:
    • Introduced the Define pipeline stage and the AliasedExpressions variadic helper to ergonomically bind values to variables.
    • Added Variable("name") and CurrentDocument() top-level functions to reference bound values in subsequent pipeline stages.
  • Field Access & Overloading:
    • Implemented GetField (accepting any to support both string and Expression arguments, mirroring Java's method overloading).
  • Rename sample options

Type Safety & Defensive Constraints:

@bhshkh bhshkh requested review from a team as code owners April 6, 2026 21:09
@product-auto-label product-auto-label Bot added the api: firestore Issues related to the Firestore API. label Apr 6, 2026
@bhshkh bhshkh requested a review from daniel-sanche April 6, 2026 21:10
@bhshkh bhshkh enabled auto-merge (squash) April 6, 2026 21:10
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces several enhancements to the Firestore Pipelines API, including support for subcollection pipelines, variable definitions via a new Define stage, and expressions for accessing fields (GetField) and variables (Variable). It also adds methods to convert pipelines into scalar or array expressions (ToScalarExpression, ToArrayExpression) and renames sampling functions for better clarity. The review feedback highlights a mismatch in a documentation example, suggests adhering to Go idiomatic error string and documentation comment conventions, and recommends removing a redundant top-level function to maintain API consistency.

Comment thread firestore/pipeline.go Outdated
Comment thread firestore/pipeline.go Outdated
Comment thread firestore/pipeline.go Outdated
Comment thread firestore/pipeline.go Outdated
Comment thread firestore/pipeline_function.go Outdated
@bhshkh bhshkh force-pushed the feat/fspq-join-subquery branch from 6397d34 to 24ffae5 Compare April 6, 2026 21:47
Comment thread firestore/pipeline.go
return p
}
if other.c == nil {
p.err = fmt.Errorf("union only supports combining root pipelines; relative scope pipelines (like subcollection pipelines) are not supported")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One ergonomic factor to consider for the future: would users benefit from having these kind of errors exported for easier checking via errors.Is or similar?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed in #14429

@bhshkh bhshkh merged commit c40e42f into googleapis:main Apr 6, 2026
11 checks passed
@bhshkh bhshkh deleted the feat/fspq-join-subquery branch April 10, 2026 00:41
bhshkh added a commit that referenced this pull request Apr 14, 2026
)

This PR introduces several refinements to the Firestore Pipelines
experimental feature, aimed at improving API consistency, error
reporting, and the reliability of integration tests.

  Key Changes:
   - API Refinement:
- Renamed ArraySliceWithLength to ArraySliceToEnd to better reflect its
behavior similar to
[Java](https://github.com/googleapis/java-firestore/blob/9065134fd70da22250f038d7e964f26aebfeb3cf/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Expression.java#L2644).
       - Enabled the ArrayFilter expression (previously commented out).
- Updated TimestampTruncateWithTimezone to accept any for the timezone
parameter, allowing for dynamic timezone expressions.
TimestampTruncateWithTimezone in Java accepts string or expression
[src](https://github.com/googleapis/java-firestore/blob/9065134fd70da22250f038d7e964f26aebfeb3cf/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Expression.java#L3763-L3908).
   - Error Handling:
- Introduced typed errors ErrPipelineWithoutDatabase and
ErrUnionNotSupportRelativeScope to replace generic fmt.Errorf calls
#14365 (comment).
- Added internal nil checks across various pipeline stages
(inputStageDocuments, findNearestStage, removeFieldsStage, etc.) to
provide more descriptive error messages during proto conversion.
   - Integration Test Enhancements:
- Replaced skipIfEnterprise with a more flexible skipIfEdition helper to
handle feature support across different Firestore
         editions.
- Improved resource cleanup in tests by moving t.Cleanup calls earlier,
ensuring documents are deleted even if a test fails prematurely.
- Updated deleteCollection to use Select().Documents(ctx) for more
efficient document deletion during test setup/teardown.
   - Bug Fixes & Robustness:
- Added nil checks when processing results in
TestIntegration_Query_Pipeline.
- Standardized test skipping logic across all pipeline-related
integration tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api: firestore Issues related to the Firestore API.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants