GC-301f · Module 2
NoSQL & Document Stores
3 min read
Document databases like MongoDB, Firestore, and DynamoDB require a different tool design than SQL. There is no universal query language — each database has its own query API. MongoDB uses filter objects with operators like $eq, $gt, $in. Firestore uses chained where() calls. DynamoDB uses KeyConditionExpression with ExpressionAttributeValues. Do not try to build a generic "query any NoSQL database" tool. Build database-specific tools that accept structured filter parameters and translate them to the native query format.
Schema flexibility in document stores creates a tool design challenge. A SQL table has fixed columns. A MongoDB collection might have documents with different field sets. Handle this by defining a canonical document shape in your tool — the fields you expect and will return. Use projection to select only those fields from the database. If a document is missing a field, return null for it. Gemini needs consistent response shapes to reason about data across multiple tool calls.
import { initializeApp, cert } from "firebase-admin/app";
import { getFirestore } from "firebase-admin/firestore";
const app = initializeApp({
credential: cert(JSON.parse(process.env.FIREBASE_CREDS!)),
});
const db = getFirestore(app);
async function getCustomersByRegion(region: string, limit = 25) {
const snap = await db
.collection("customers")
.where("region", "==", region)
.where("status", "==", "active")
.orderBy("lastActivity", "desc")
.limit(Math.min(limit, 50))
.get();
return snap.docs.map((doc) => ({
id: doc.id,
name: doc.data().name ?? null,
region: doc.data().region,
mrr: doc.data().mrr ?? 0,
lastActivity: doc.data().lastActivity?.toDate()?.toISOString() ?? null,
}));
}
DynamoDB access patterns are defined at table design time, not query time. You query by partition key and optionally filter by sort key. Scans are expensive and slow. Design DynamoDB tools around the table's access patterns: if the table is partitioned by customerId with a sort key of timestamp, build tools that query by customer. Do not build a "scan all records" tool. If Gemini needs cross-partition queries, point it at a Global Secondary Index or a read replica with a SQL interface.