Can you use a computed field in another computed field?

I am curious whether one can use a computed field in a $project stage, to calculate another computed field.

For example using db.solarSystem in the aggregation DB, can we do an aggregation, with a project stage, where we create two computed fields (one calculated based on the other), like below?

db.solarSystem.aggregate([
    {
            $project:{
                "_id": 0,
                "name": 1,
                "computed_field_01": { 
                     $divide: [ "$gravity.value", 5 ]
                },
                "computed_field_02": { 
                    $multiply : [ "$computed_field_01", 10 ]}
            }

    }
    
])

or do we always have to break into two stages, like this:

db.solarSystem.aggregate([
    {
            $project:{
                "_id": 0,
                "name": 1,
                "computed_field_01": { 
                     $divide: [ "$gravity.value", 5 ]
                }
            }

    },
    {
            $project:{
                "_id": 0,
                "name": 1,
                "computed_field_01":1,
                "computed_field_02": { 
                $multiply : [ "$computed_field_01", 10 ]}
        }

}
    
])

Also just let me mention that I have tried a few syntax variations on the “combined” stage but to no avail.

Thank you in advance for your help.

Disappointingly the only way I can see is this:

db.solarSystem.aggregate([
	{
		$project:{
			"_id": 0,
			"name": 1,
			"computed_fields": {
				$let: {
					vars: {
						"div_gravity": {$divide: ["$gravity.value", 5]}
					},
					in: {
						"a": "$$div_gravity",
						"b": {$multiply : ["$$div_gravity", 10]}}
					}
				}
			}
		}
    }
])

I say “disappointingly” for two reasons:

  1. I find the $let operator to be unnecessarily and frustratingly verbose
  2. You will end up with sub-documents, computed_fields.a and computed_fields.b.

I’m sure you already realise that for this simple use case you could just duplicate the computation.

Curriculum Support Engineers:
It would have been so much easier and succinct to do something like this:

{
   $let: [
      var_1: {$add: ["$field1", 5]},
      var_2: {$multiply: [$$var_1, 10]}
   ],
   sepFields: true | false
}

… with an option to have the result as individual fields or as sub-documents.

1 Like

I would say it is as expected, the same is applicable on any SQL db, it would just make parsing of query much more complicated, it would require a lot of things, resolving dependencies, cycles.

I would add just one more stage or repeat the code, I would not expect such functionality to be able to handle this.

To that I say let the Architects and Developers handle the Generics Programming required to achieve simplicity from a user’s perspective. To be clear, I’m not complaining about the why, I’m complaining specifically about $let and it’s verbose syntax.

MongoDB is a new product in comparison to SQL variants and if this is called Variable assignment, then it’s more verbose than SQL or any other language I can think of. A variable assignment is usually a simple right to left or left to right assignment. Not a two-stage assignment.

Imagine trying to write a simple mathematical model that has a few variable dependencies using $let… it would be a nightmare.