diff --git a/opensensor/collection_apis.py b/opensensor/collection_apis.py index 96e3537..ca34300 100644 --- a/opensensor/collection_apis.py +++ b/opensensor/collection_apis.py @@ -207,7 +207,7 @@ def create_nested_pipeline(model: Type[BaseModel], prefix="", pipeline=None): "timestamp": "$timestamp", } - for field_name, field_type in model.__fields__.items(): + for field_name, _ in model.__fields__.items(): if field_name == "timestamp": continue lookup_field = ( @@ -220,32 +220,17 @@ def create_nested_pipeline(model: Type[BaseModel], prefix="", pipeline=None): unit_field_name = f"{prefix}{mongo_field}_unit" pipeline["unit"] = f"${unit_field_name}" match_conditions[unit_field_name] = {"$exists": True} + elif field_name in nested_fields: + nested_model = nested_fields[field_name] + nested_prefix = f"{full_mongo_field_name}." + nested_pipeline, nested_match = create_nested_pipeline(nested_model, nested_prefix) + pipeline[field_name] = nested_pipeline + for k, v in nested_match.items(): + match_conditions[f"{nested_prefix}{k}"] = v else: pipeline[field_name] = f"${full_mongo_field_name}" match_conditions[full_mongo_field_name] = {"$exists": True} - if field_name in nested_fields: - if get_origin(field_type.type_) is List: - nested_pipeline, nested_match = create_nested_pipeline( - nested_fields[field_name], "" # Empty prefix for list items - ) - pipeline[field_name] = { - "$map": { - "input": f"${full_mongo_field_name}", - "as": "item", - "in": { - k: f"$$item.{v.replace('$', '')}" for k, v in nested_pipeline.items() - }, - } - } - match_conditions[full_mongo_field_name] = {"$exists": True, "$ne": []} - else: - nested_pipeline, nested_match = create_nested_pipeline( - nested_fields[field_name], f"{full_mongo_field_name}.", pipeline - ) - pipeline[field_name] = nested_pipeline - match_conditions.update({f"{field_name}.{k}": v for k, v in nested_match.items()}) - logger.debug(f"Field: {field_name}, Full mongo field name: {full_mongo_field_name}") logger.debug(f"Resulting pipeline part: {pipeline[field_name]}") @@ -255,11 +240,11 @@ def create_nested_pipeline(model: Type[BaseModel], prefix="", pipeline=None): def create_model_instance(model: Type[BaseModel], data: dict, target_unit: Optional[str] = None): nested_fields = get_nested_fields(model) + instance_data = {} - for field_name, _ in model.__fields__.items(): + for field_name, field in model.__fields__.items(): if field_name == "timestamp": - continue - if field_name in nested_fields: + instance_data[field_name] = data.get(field_name) continue lookup_field = ( @@ -270,41 +255,24 @@ def create_model_instance(model: Type[BaseModel], data: dict, target_unit: Optio # Special handling for the unit field if field_name == "unit": unit_field = f"{mongo_field}_unit" - if unit_field in data: - data[field_name] = data[unit_field] - continue - - # Handle temperature unit conversion if applicable - if mongo_field in data: - data[field_name] = data[mongo_field] - elif field_name in data: - # If the field_name exists in data, use it - data[field_name] = data[field_name] - elif field_name.lower() in data: - # If the field_name (lowercase) exists in data, use it - data[field_name] = data[field_name.lower()] - else: - # If neither the mongo_field nor the field_name exists, log an error - logger.error( - f"Field '{mongo_field}' or '{field_name}' not found in data for model {model.__name__}" - ) - logger.error(f"Available fields in data: {list(data.keys())}") - # You might want to set a default value or raise an exception here - - for field_name, nested_model in nested_fields.items(): - if field_name in data: - if isinstance(data[field_name], list): - data[field_name] = [ + instance_data[field_name] = data.get(unit_field) + elif field_name in nested_fields: + nested_model = nested_fields[field_name] + if isinstance(field.type_, List): + instance_data[field_name] = [ create_model_instance(nested_model, item, target_unit) - for item in data[field_name] + for item in data.get(field_name, []) ] else: - data[field_name] = create_model_instance( - nested_model, data[field_name], target_unit + nested_data = data.get(field_name, {}) + instance_data[field_name] = create_model_instance( + nested_model, nested_data, target_unit ) + else: + instance_data[field_name] = data.get(mongo_field) or data.get(field_name) - logger.debug(f"Creating instance of {model.__name__} with data: {data}") - result = model(**data) + logger.debug(f"Creating instance of {model.__name__} with data: {instance_data}") + result = model(**instance_data) if isinstance(result, Temperature) and target_unit: convert_temperature(result, target_unit) return result