Skip to content

Commit d93a9e1

Browse files
committed
attempt to generalize the collection projection
1 parent 8e9f278 commit d93a9e1

File tree

1 file changed

+35
-10
lines changed

1 file changed

+35
-10
lines changed

opensensor/collection_apis.py

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,13 @@ def get_nested_fields(model: Type[BaseModel]):
202202
def create_nested_pipeline(model: Type[BaseModel], prefix=""):
203203
nested_fields = get_nested_fields(model)
204204
pipeline = {}
205+
match_conditions = {}
205206

206207
for field_name, field_type in model.__fields__.items():
208+
if field_name == "timestamp":
209+
pipeline[field_name] = f"${prefix}timestamp"
210+
continue
211+
207212
lookup_field = (
208213
model.collection_name() if hasattr(model, "collection_name") else model.__name__
209214
)
@@ -212,21 +217,36 @@ def create_nested_pipeline(model: Type[BaseModel], prefix=""):
212217

213218
if field_name in nested_fields:
214219
if get_origin(field_type.type_) is List:
220+
nested_pipeline, nested_match = create_nested_pipeline(
221+
nested_fields[field_name], "$$item."
222+
)
215223
pipeline[field_name] = {
216224
"$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+
},
218232
"as": "item",
219-
"in": create_nested_pipeline(nested_fields[field_name], "$$item."),
233+
"in": nested_pipeline,
220234
}
221235
}
236+
match_conditions[full_field_name] = {"$exists": True, "$ne": []}
222237
else:
223-
pipeline[field_name] = create_nested_pipeline(
238+
nested_pipeline, nested_match = create_nested_pipeline(
224239
nested_fields[field_name], f"{full_field_name}."
225240
)
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+
)
226245
else:
227246
pipeline[field_name] = f"${full_field_name}"
247+
match_conditions[full_field_name] = {"$exists": True}
228248

229-
return pipeline
249+
return pipeline, match_conditions
230250

231251

232252
def create_model_instance(model: Type[BaseModel], data: dict):
@@ -360,16 +380,21 @@ def get_uniform_sample_pipeline(
360380
if end_date is None:
361381
end_date = datetime.utcnow()
362382
sampling_interval = timedelta(minutes=resolution)
363-
match_clause = get_initial_match_clause(device_ids, device_name, start_date, end_date)
364383

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)
368386

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+
)
370395

371396
pipeline = [
372-
{"$match": match_clause},
397+
{"$match": match_conditions},
373398
{
374399
"$addFields": {
375400
"group": {

0 commit comments

Comments
 (0)