You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Target: Azure Cosmos DB (MongoDB API). IMPORTANT — Cosmos does NOT support `let` or `pipeline` inside `$lookup`. Only the plain `localField`/`foreignField` form works. Never emit `let` or a `pipeline` array inside `$lookup` — it will fail with `CommandNotSupported`.
79
+
- Produce ONE aggregate() pipeline. Pick the most-filtering collection as the driver.
80
+
- Use the Inferred Relationships block above to choose join fields. Do NOT invent field names that are not in the schema or relationships.
81
+
- TYPE-MISMATCH HANDLING (this is the #1 reason $lookup returns empty arrays on Cosmos): if one side is an ObjectId and the other is a string, you MUST pre-convert with an `$addFields` stage BEFORE `$lookup`, then $lookup on the converted field. Do not rely on $lookup to coerce types.
82
+
- String → ObjectId: `{"$addFields": {"<field>_oid": {"$toObjectId": "$<field>"}}}` (or `$map` over an array of strings).
- After $lookup, $unwind the joined array (use `preserveNullAndEmptyArrays: True` for LEFT-JOIN semantics) before filtering on joined fields, OR filter with `joined.field` dotted notation.
85
+
- Always include a $limit (<=50) unless the user explicitly asks for all rows.
86
+
87
+
Example A — simple equality join (same field type on both sides):
Previous Evaluation Feedback (if this is a retry):
147
+
Previous Attempt (if this is a retry — DO NOT repeat the same query verbatim):
148
+
{previous_query}
149
+
150
+
Previous Evaluation Feedback (if this is a retry):
85
151
{evaluation}
86
152
87
153
Instructions:
88
-
1. Write ONLY the PyMongo query code.
154
+
0. If a Previous Attempt is shown above, your new query MUST be materially different — change the join form, fields, types, or stages in response to the critique. Producing the same query (or a trivial reformat) is a failure. If the previous $lookup returned empty arrays for every input doc, the cause is almost always a type mismatch on the join key: add an `$addFields` stage BEFORE the `$lookup` that applies `$toObjectId` (string→OID) or `$toString` (OID→string), then $lookup on the converted field. NEVER use `let` or `pipeline` inside `$lookup` — Cosmos rejects both with CommandNotSupported.
155
+
1. Write ONLY the PyMongo query code.
89
156
2. Use variables appropriately (e.g., db['collection_name'].find(...) or db['collection_name'].aggregate(...)).
90
157
3. Do not include markdown formatting or explanations, just return the code, but you can use ```python if you must.
91
158
4. If the user is asking for a visualization, ensure the query retrieves the necessary data format.
92
159
5. You are allowed to use both find() and aggregate() pipelines. If using aggregate(), be mindful of the resulting data size and include $limit stages if applicable.
160
+
{cross_collection_guidance}
93
161
"""
94
162
95
163
EVALUATE_PROMPT="""
@@ -105,6 +173,12 @@ class AgentState(TypedDict):
105
173
Determine if this query successfully answers the user's request based on the code and the result.
106
174
If there is an error in the query result, or if it clearly does not match the intent, it is NOT valid.
107
175
If it is a write action, we cannot test the result, but you should evaluate if the code looks correct for the user's intent.
176
+
If the query uses $lookup, specifically verify (target is Azure Cosmos DB MongoDB API):
177
+
- The query does NOT use `let` or `pipeline` inside `$lookup` — Cosmos rejects both with `CommandNotSupported`. If you see either, it is NOT valid; recommend pre-converting the type with an `$addFields` stage and then using plain `localField`/`foreignField`.
178
+
- The `localField`/`foreignField` reference fields that actually exist on each side.
179
+
- When the joined array is empty for every input doc, suspect a type mismatch (ObjectId vs string). The query is NOT valid; recommend an `$addFields` stage BEFORE `$lookup` that applies `$toObjectId` (string→OID) or `$toString` (OID→string), and a `$map` if the local field is an array of strings.
180
+
- Do not rationalize an empty result with "maybe no such records exist" when the filter is on a field inside the joined array — empty joined arrays will make the downstream $match drop everything; treat that as a join-correctness failure unless the join itself is clearly populated.
181
+
- The driving collection is the right one (smallest filtered set first).
108
182
109
183
Respond in JSON format:
110
184
{{
@@ -117,13 +191,22 @@ class AgentState(TypedDict):
0 commit comments