Projecting Fields & Changing Names Based On User Context

I have a case, where I have a collection of documents that have several fields that are either have duplicate field names with slightly different allowed values, or fields that are the same value, but with a different field name based on the version the user is requesting. I’d like to identify the fields by their version by appending _V1 or _V2 to the end of the field for ease of reading the data in the database, but I’d like to remove remove the _V1 or _V2 when the user queries the data.

Here is an example document:

{
    "id" : "A",
    "province_V1" : "CA",
    "province_V2" : "CAL",
    "units" : [
        {
            "id" : "UA",
            "capabilities_V1" : [
                "REMOTE_START",
                "REMOTE_STOP"
            ],
            "capabilities_V2" : [
                "REMOTE_START",
                "REMOTE_STOP",
                "HEALTH_CHECK"
            ],
            "connectors" : [
                {
                    "id" : "CA",
                    "voltage_V1" : 90.0,
                    "amperage_V1" : 120.0,
                    "max_voltage_V2" : 90.0,
                    "max_amperage_V2" : 120.0
                }
            ]
        }
    ]
}

With the document above I’d like to show of a specific version based on the user’s request and remove the _V1 appended to each fields name. This is the query I’m attempting to do this with:

db.getCollection("test").find({}, {
    id: 1,
    province: '$province_V1',
    'units.capabilities': '$units.capabilities_V1',
    'units.connectors.voltage': '$units.connectors.voltage_V1',
    'units.connectors.amperage': '$units.connectors.amperage_V1'
})

This works for top level fields such as province. When I query this data the province field is added and is either 'CA' or 'CAL', based on $province_V1 or $province_V2

I have an issue with fields in the nested units and connectors array. The values are returning properly, but they are nested within another array.

Here are the results that I’m getting:


{
    "id" : "A",
    "units" : [
        {
            "connectors" : [
                {
                    "voltage" : [
                        [
                            90.0
                        ]
                    ],
                    "amperage" : [
                        [
                            120.0
                        ]
                    ]
                }
            ],
            "capabilities" : [
                [
                    "REMOTE_START",
                    "REMOTE_STOP"
                ]
            ]
        }
    ],
    "province" : "CA"
}

I’d like 'units.capabilities' to be an array, but my projection is creating a nested array. And for voltage and amperage, I’d like these fields to be a number, but my projection is also creating a nested array.

Can a simple projection handle this? If not, which method do you think would be better to handle this use case? Would an aggregation be more suited?

I was able to solve this issue by using $map in my $project for each nested array, like so:

db.getCollection("test").find({}, {
    id: 1,
    province: '$province_V1',
    units: {
        $map: {
            input: '$units',
            as: 'unit',
            in: {
                capabilities: '$$unit.capabilities_V1,
                connectors: {
                    $map: {
                        input: '$$unit.connectors',
                        as: 'connector',
                        in: {
                            voltage: '$$connector.voltage_V1',
                            amperage: '$$connector.amperage_V1'
                        }
                    }
                }
            }
        }
    }
})
1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.