@@ -202,8 +202,13 @@ def get_nested_fields(model: Type[BaseModel]):
202
202
def create_nested_pipeline (model : Type [BaseModel ], prefix = "" ):
203
203
nested_fields = get_nested_fields (model )
204
204
pipeline = {}
205
+ match_conditions = {}
205
206
206
207
for field_name , field_type in model .__fields__ .items ():
208
+ if field_name == "timestamp" :
209
+ pipeline [field_name ] = f"${ prefix } timestamp"
210
+ continue
211
+
207
212
lookup_field = (
208
213
model .collection_name () if hasattr (model , "collection_name" ) else model .__name__
209
214
)
@@ -212,21 +217,36 @@ def create_nested_pipeline(model: Type[BaseModel], prefix=""):
212
217
213
218
if field_name in nested_fields :
214
219
if get_origin (field_type .type_ ) is List :
220
+ nested_pipeline , nested_match = create_nested_pipeline (
221
+ nested_fields [field_name ], "$$item."
222
+ )
215
223
pipeline [field_name ] = {
216
224
"$map" : {
217
- "input" : f"${ full_field_name } " ,
225
+ "input" : {
226
+ "$filter" : {
227
+ "input" : f"${ full_field_name } " ,
228
+ "as" : "item" ,
229
+ "cond" : nested_match ,
230
+ }
231
+ },
218
232
"as" : "item" ,
219
- "in" : create_nested_pipeline ( nested_fields [ field_name ], "$$item." ) ,
233
+ "in" : nested_pipeline ,
220
234
}
221
235
}
236
+ match_conditions [full_field_name ] = {"$exists" : True , "$ne" : []}
222
237
else :
223
- pipeline [ field_name ] = create_nested_pipeline (
238
+ nested_pipeline , nested_match = create_nested_pipeline (
224
239
nested_fields [field_name ], f"{ full_field_name } ."
225
240
)
241
+ pipeline [field_name ] = nested_pipeline
242
+ match_conditions .update (
243
+ {f"{ full_field_name } .{ k } " : v for k , v in nested_match .items ()}
244
+ )
226
245
else :
227
246
pipeline [field_name ] = f"${ full_field_name } "
247
+ match_conditions [full_field_name ] = {"$exists" : True }
228
248
229
- return pipeline
249
+ return pipeline , match_conditions
230
250
231
251
232
252
def create_model_instance (model : Type [BaseModel ], data : dict ):
@@ -360,16 +380,21 @@ def get_uniform_sample_pipeline(
360
380
if end_date is None :
361
381
end_date = datetime .utcnow ()
362
382
sampling_interval = timedelta (minutes = resolution )
363
- match_clause = get_initial_match_clause (device_ids , device_name , start_date , end_date )
364
383
365
- # Create a generalized project pipeline
366
- project_pipeline = create_nested_pipeline (response_model )
367
- project_pipeline ["timestamp" ] = "$timestamp"
384
+ # Create a generalized project pipeline and match conditions
385
+ project_pipeline , match_conditions = create_nested_pipeline (response_model )
368
386
369
- logger .info (f"Project pipeline for { response_model .__name__ } : { project_pipeline } " )
387
+ # Add timestamp and device metadata conditions to match_conditions
388
+ match_conditions .update (
389
+ {
390
+ "timestamp" : {"$gte" : start_date , "$lte" : end_date },
391
+ "metadata.device_id" : {"$in" : device_ids },
392
+ "metadata.name" : device_name ,
393
+ }
394
+ )
370
395
371
396
pipeline = [
372
- {"$match" : match_clause },
397
+ {"$match" : match_conditions },
373
398
{
374
399
"$addFields" : {
375
400
"group" : {
0 commit comments