How to replace usage of group() & reduce() deprecated ODM query methods into Symfony code

240 Views Asked by At

I am using Symfony Doctrine Mongodb-odm 1.2 library in the project. group() & reduce() methods are deprecated and no longer available with MongoDB 4.2. My existing code has used these methods to group and pull the MongoDB records using custom reduce logic on the query. Refer the following query:

$customers = $this->createQueryBuilder($business)
            ->field('pay_status')->equals('unpaid')
            ->group(['contact' => 0], ['total' => 0])
            ->reduce(
                'function (obj, prev) {
                     prev.total += obj.total.amount;
                     prev.contact_data  = obj.contact_data;
                     if (obj.contact) {
                        prev.contact  = obj.contact.$id.str;
                    }
                     return prev;
                }'
            )
            ->limit(5)

            ->getQuery()
            ->execute()
            ->toArray(false);

This works completely fine with MongoDB 4.0 and returns the result set with top 5 unpaid customers list. Now, I am struggling to find out the replacement for this query using aggregation pipeline which is recommended for MongoDB 4.2.

Can anyone help with the replacement query using aggregation builder methods? I know how to group the result using aggregation stage but not sure how to pull the top 5 customers without reduce() method here. Thanks in advance.

1

There are 1 best solutions below

0
Somnath Pawar On

I guess I found the way to query & retrieve the expected result set using aggregation builder without reduce method:

$customers = $this->createAggregationBuilder($business)
            ->hydrate(false)
            ->match()
            ->field('pay_status')->equals('unpaid')
            ->group()
                ->field('_id')->expression(['contact_data'=>'$contact_data','contact'=>'$contact'])
                ->field('total')->sum('$total.amount')
            ->project()
                ->field('total')->expression('$total')
                ->field('contact')->expression('$_id.contact')
                ->field('contact_data')->expression('$_id.contact_data')
                ->field('_id')->expression('$$REMOVE')
            ->sort(['total' => 'desc'])
            ->limit(5)
            ->getQuery()
            ->execute()
            ->toArray(false);