Search code examples
pythonmongodbpipelineaggregationmongodb4.0

Pass an aggregate intermediate result field as python function argument in Pymongo


Using MongoDB 4.0 I have to compute a new field basing on existing field. An example of documents in mycollection:

{
    _id: ...,
    f1: 'a',
    f2: 'b'
}

My python code, after connecting to DB:

Please note that myJoin is here just for example. In real use scenario this function is quite complex (custom cryptographic calculations and bytes manipulations).

def myJoin(left, right):
  return left+'-myDelimiter-'+right


myPipeline = [
    {
        '$match': {
            'f1': {
                '$exists': True
            }
        }
    }, {
        '$addFields': {
            'f3': myJoin('$f1', '$f2')
        }
    }
]

mydb.mycollection.aggregate(myPipeline)

However in DB I see:

{
    _id: ...,
    f1: 'a',
    f2: 'b',
    f3: '$f1-myDelimiter-$f2'
}

But I want:

{
    _id: ...,
    f1: 'a',
    f2: 'b',
    f3: 'a-myDelimiter-b'
}

For the moment I am using pipeline aggregations. But other strategies are welcome.


Solution

  • You can use $concat operator to concat fields with delimiters,

    {
      '$addFields': {
        'f3': { '$concat': ['$f1', '-myDelimiter-', '$f2'] }
      }
    }
    

    I used myJoin just for example. My custom function perform a series of cryptographic computations and bytes manipulations.

    I don't think it is possible to integrate into a query for python lang in current MongoDB v4.4,

    There is a $function operator starting from MongoDB 4.4, There you can write javascript code and execute in query, but, it's expensive for query performance.

    I would suggest you to do this operation after the query on the result.