Skip to content

Commit 7dbb95c

Browse files
committed
Attempt to fix the relays projection in a generic way.
1 parent 0af5ce2 commit 7dbb95c

File tree

1 file changed

+19
-19
lines changed

1 file changed

+19
-19
lines changed

opensensor/collection_apis.py

+19-19
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from fastapi_pagination.default import Params as BaseParams
99
from fief_client import FiefUserInfo
1010
from pydantic import BaseModel
11+
from pydantic.fields import ModelField
1112

1213
from opensensor.collections import (
1314
CO2,
@@ -197,9 +198,19 @@ def get_nested_fields(model: Type[BaseModel]) -> Dict[str, Type[BaseModel]]:
197198
return nested_fields
198199

199200

201+
def is_list_of_models(field: ModelField) -> bool:
202+
if field.shape != 2: # 2 represents a list shape in Pydantic
203+
return False
204+
args = field.sub_fields[0].type_.__args__
205+
return args and is_pydantic_model(args[0])
206+
207+
208+
def get_list_item_type(field: ModelField) -> Type[BaseModel]:
209+
return field.sub_fields[0].type_.__args__[0]
210+
211+
200212
def create_nested_pipeline(model: Type[BaseModel], prefix=""):
201213
logger.debug(f"Creating nested pipeline for model: {model.__name__}, prefix: {prefix}")
202-
nested_fields = get_nested_fields(model)
203214
match_conditions = {}
204215
pipeline = {
205216
"timestamp": "$timestamp",
@@ -218,24 +229,13 @@ def create_nested_pipeline(model: Type[BaseModel], prefix=""):
218229
unit_field_name = f"{prefix}{mongo_field}_unit"
219230
pipeline["unit"] = f"${unit_field_name}"
220231
match_conditions[unit_field_name] = {"$exists": True}
221-
elif field_name in nested_fields:
222-
nested_type = nested_fields[field_name]
223-
if get_origin(field.type_) is List:
224-
# Handle array of nested objects
225-
nested_pipeline, nested_match = create_nested_pipeline(nested_type, "")
226-
pipeline[field_name] = {
227-
"$map": {
228-
"input": f"${full_mongo_field_name}",
229-
"as": "item",
230-
"in": nested_pipeline,
231-
}
232-
}
233-
match_conditions[full_mongo_field_name] = {"$exists": True, "$ne": []}
234-
else:
235-
# Handle nested object
236-
nested_pipeline, nested_match = create_nested_pipeline(nested_type, "")
237-
pipeline[field_name] = nested_pipeline
238-
match_conditions.update({f"{field_name}.{k}": v for k, v in nested_match.items()})
232+
elif is_list_of_models(field):
233+
item_model = get_list_item_type(field)
234+
nested_pipeline, nested_match = create_nested_pipeline(item_model, "")
235+
pipeline[field_name] = {
236+
"$map": {"input": f"${full_mongo_field_name}", "as": "item", "in": nested_pipeline}
237+
}
238+
match_conditions[full_mongo_field_name] = {"$exists": True, "$ne": []}
239239
else:
240240
# Handle simple field
241241
pipeline[field_name] = f"${full_mongo_field_name}"

0 commit comments

Comments
 (0)