firestore-query-collection-parameterizable
Query a Firestore collection with parameterizable filters and Firestore native JSON value types
Overview
The firestore-query-collection-parameterizable
tool allows you to query Firestore collections with dynamic, parameterizable filters that support Firestore’s native JSON value types. This tool is particularly useful when you need to create reusable query templates with parameters that can be substituted at runtime.
Key Features
- Parameterizable Queries: Use Go template syntax to create dynamic queries
- Native JSON Value Types: Support for Firestore’s typed values (stringValue, integerValue, doubleValue, etc.)
- Complex Filter Logic: Support for AND/OR logical operators in filters
- Template Substitution: Dynamic collection paths, filters, and ordering
- Query Analysis: Optional query performance analysis with explain metrics
Configuration
Basic Configuration
tools:
query_countries:
kind: firestore-query-collection-parameterizable
source: my-firestore-source
description: Query countries with dynamic filters
collectionPath: "countries"
filters: |
{
"field": "continent",
"op": "==",
"value": {"stringValue": "{{.continent}}"}
}
parameters:
- name: continent
type: string
description: Continent to filter by
required: true
Advanced Configuration with Complex Filters
tools:
advanced_query:
kind: firestore-query-collection-parameterizable
source: my-firestore-source
description: Advanced query with complex filters
collectionPath: "{{.collection}}"
filters: |
{
"or": [
{"field": "status", "op": "==", "value": {"stringValue": "{{.status}}"}},
{
"and": [
{"field": "priority", "op": ">", "value": {"integerValue": "{{.priority}}"}},
{"field": "area", "op": "<", "value": {"doubleValue": {{.maxArea}}}},
{"field": "active", "op": "==", "value": {"booleanValue": {{.isActive}}}}
]
}
]
}
select:
- name
- status
- priority
orderBy:
field: "{{.sortField}}"
direction: "{{.sortDirection}}"
limit: 100
analyzeQuery: true
parameters:
- name: collection
type: string
description: Collection to query
required: true
- name: status
type: string
description: Status to filter by
required: true
- name: priority
type: string
description: Minimum priority value
required: true
- name: maxArea
type: float
description: Maximum area value
required: true
- name: isActive
type: boolean
description: Filter by active status
required: true
- name: sortField
type: string
description: Field to sort by
required: false
default: "createdAt"
- name: sortDirection
type: string
description: Sort direction (ASCENDING or DESCENDING)
required: false
default: "DESCENDING"
Parameters
Configuration Parameters
Parameter | Type | Required | Description |
---|---|---|---|
kind | string | Yes | Must be firestore-query-collection-parameterizable |
source | string | Yes | Name of the Firestore source to use |
description | string | Yes | Description of what this tool does |
collectionPath | string | Yes | Path to the collection (supports templates) |
filters | string | No | JSON string defining query filters (supports templates) |
select | array | No | Fields to select from documents(supports templates - string or array) |
orderBy | object | No | Ordering configuration with field and direction (supports templates for the value of field or direction) |
limit | integer | No | Maximum number of documents to return (default: 100) (supports templates) |
analyzeQuery | boolean | No | Whether to analyze query performance (default: false) (supports templates) |
parameters | array | Yes | Parameter definitions for template substitution |
Runtime Parameters
Runtime parameters are defined in the parameters
array and can be used in templates throughout the configuration.
Filter Format
Simple Filter
{
"field": "age",
"op": ">",
"value": {"integerValue": "25"}
}
AND Filter
{
"and": [
{"field": "status", "op": "==", "value": {"stringValue": "active"}},
{"field": "age", "op": ">=", "value": {"integerValue": "18"}}
]
}
OR Filter
{
"or": [
{"field": "role", "op": "==", "value": {"stringValue": "admin"}},
{"field": "role", "op": "==", "value": {"stringValue": "moderator"}}
]
}
Nested Filters
{
"or": [
{"field": "type", "op": "==", "value": {"stringValue": "premium"}},
{
"and": [
{"field": "type", "op": "==", "value": {"stringValue": "standard"}},
{"field": "credits", "op": ">", "value": {"integerValue": "1000"}}
]
}
]
}
Firestore Native Value Types
The tool supports all Firestore native JSON value types:
Type | Format | Example |
---|---|---|
String | {"stringValue": "text"} | {"stringValue": "{{.name}}"} |
Integer | {"integerValue": "123"} or {"integerValue": 123} | {"integerValue": "{{.age}}"} or {"integerValue": {{.age}}} |
Double | {"doubleValue": 45.67} | {"doubleValue": {{.price}}} |
Boolean | {"booleanValue": true} | {"booleanValue": {{.active}}} |
Null | {"nullValue": null} | {"nullValue": null} |
Timestamp | {"timestampValue": "RFC3339"} | {"timestampValue": "{{.date}}"} |
GeoPoint | {"geoPointValue": {"latitude": 0, "longitude": 0}} | See below |
Array | {"arrayValue": {"values": [...]}} | See below |
Map | {"mapValue": {"fields": {...}}} | See below |
Complex Type Examples
GeoPoint:
{
"field": "location",
"op": "==",
"value": {
"geoPointValue": {
"latitude": 37.7749,
"longitude": -122.4194
}
}
}
Array:
{
"field": "tags",
"op": "array-contains",
"value": {"stringValue": "{{.tag}}"}
}
Supported Operators
<
- Less than<=
- Less than or equal>
- Greater than>=
- Greater than or equal==
- Equal!=
- Not equalarray-contains
- Array contains valuearray-contains-any
- Array contains any of the valuesin
- Value is in arraynot-in
- Value is not in array
Examples
Example 1: Query with Dynamic Collection Path
tools:
user_documents:
kind: firestore-query-collection-parameterizable
source: my-firestore
description: Query user-specific documents
collectionPath: "users/{{.userId}}/documents"
filters: |
{
"field": "type",
"op": "==",
"value": {"stringValue": "{{.docType}}"}
}
parameters:
- name: userId
type: string
description: User ID
required: true
- name: docType
type: string
description: Document type to filter
required: true
Example 2: Complex Geographic Query
tools:
location_search:
kind: firestore-query-collection-parameterizable
source: my-firestore
description: Search locations by area and population
collectionPath: "cities"
filters: |
{
"and": [
{"field": "country", "op": "==", "value": {"stringValue": "{{.country}}"}},
{"field": "population", "op": ">", "value": {"integerValue": "{{.minPopulation}}"}},
{"field": "area", "op": "<", "value": {"doubleValue": {{.maxArea}}}}
]
}
orderBy:
field: "population"
direction: "DESCENDING"
limit: 50
parameters:
- name: country
type: string
description: Country code
required: true
- name: minPopulation
type: string
description: Minimum population (as string for large numbers)
required: true
- name: maxArea
type: float
description: Maximum area in square kilometers
required: true
Example 3: Time-based Query with Analysis
tools:
activity_log:
kind: firestore-query-collection-parameterizable
source: my-firestore
description: Query activity logs within time range
collectionPath: "logs"
filters: |
{
"and": [
{"field": "timestamp", "op": ">=", "value": {"timestampValue": "{{.startTime}}"}},
{"field": "timestamp", "op": "<=", "value": {"timestampValue": "{{.endTime}}"}},
{"field": "severity", "op": "in", "value": {"arrayValue": {"values": [
{"stringValue": "ERROR"},
{"stringValue": "CRITICAL"}
]}}}
]
}
select:
- timestamp
- message
- severity
- userId
orderBy:
field: "timestamp"
direction: "DESCENDING"
analyzeQuery: true
parameters:
- name: startTime
type: string
description: Start time in RFC3339 format
required: true
- name: endTime
type: string
description: End time in RFC3339 format
required: true
Usage
Invoking the Tool
# Using curl
curl -X POST http://localhost:5000/api/tool/your-tool-name/invoke \
-H "Content-Type: application/json" \
-d '{
"continent": "Europe",
"minPopulation": "1000000",
"maxArea": 500000.5,
"isActive": true
}'
Response Format
Without analyzeQuery:
[
{
"id": "doc1",
"path": "countries/doc1",
"data": {
"name": "France",
"continent": "Europe",
"population": 67000000,
"area": 551695
},
"createTime": "2024-01-01T00:00:00Z",
"updateTime": "2024-01-15T10:30:00Z"
}
]
With analyzeQuery:
{
"documents": [...],
"explainMetrics": {
"planSummary": {
"indexesUsed": [...]
},
"executionStats": {
"resultsReturned": 10,
"executionDuration": "15ms",
"readOperations": 10
}
}
}
Best Practices
- Use Typed Values: Always use Firestore’s native JSON value types for proper type handling
- String Numbers for Large Integers: Use string representation for large integers to avoid precision loss
- Template Security: Validate all template parameters to prevent injection attacks
- Index Optimization: Use
analyzeQuery
to identify missing indexes - Limit Results: Always set a reasonable
limit
to prevent excessive data retrieval - Field Selection: Use
select
to retrieve only necessary fields
Limitations
- Maximum of 100 filters per query (configurable)
- Template parameters must be properly escaped in JSON contexts
- Complex nested queries may require composite indexes
See Also
- firestore-query-collection - Non-parameterizable query tool
- Firestore Source Configuration
- Firestore Query Documentation