doctrine/DoctrineMongoDBBundle

I need to figure it out how to use AggregationBuilder with allowDiskUse for my native query

shubaivan opened this issue · 3 comments

I need to figure it out how to use AggregationBuilder and example with QueryBuilder whould be great reproduce too for my native query

db.getCollection('AwinProduct').find(
   { $text: { 
       $search: "Sko Nike Classic Cortez för män -Svart",
       $language: 'sv' 
   } },
   { score: { $meta: "textScore" } }
).sort( { score: { $meta: "textScore" }, aw_product_id: 1 } ).skip(2).limit(2)

in src/DocumentRepository/AwinProductRepository.php I executed successful query exactly what I need by two approach, like this:

    $client = $this->getDocumentManager()->getClient();

    $connection = $client->getManager();

    $filter = ['$text' => ['$search' => "Sko Nike Classic Cortez för män -Svart", '$language' => 'sv']];


    $options = [
        'skip' => 2,
        'limit' => 2,
        'projection' => [
            'score' => ['$meta' => 'textScore']
        ],
        'sort' => [
            'score' => ['$meta' => 'textScore']
        ]
    ];

    $query = new \MongoDB\Driver\Query($filter, $options);
    $rows = $connection->executeQuery('symfony.AwinProduct', $query);
    $toArray = $rows->toArray();

    $collection = $client->symfony->AwinProduct;
    $cursor = $collection->find(
        ['$text' => ['$search' => 'Sko Nike Classic Cortez för män -Svart', '$language' => 'sv']],
        [
            'skip' => 2,
            'limit' => 2,
            'projection' => [
                'score' => ['$meta' => 'textScore']
            ],
            'sort' => [
                'score' => ['$meta' => 'textScore'], 'aw_product_id' => 1
            ]
        ]
    );

but missunderstandig how to use for that AggregationBuilder because in my case, when I have db with million rows and using sort and limit with skip in the same time I need use allowDiskUse' => true, this ooportunity available in AggregationBuilder

     $purchase = $builder->execute(['allowDiskUse' => true]);

I'm not sure why you would use the aggregation builder for this, as you're running a regular query. Using the query builder, you'd do this similar to this:

$builder = $dm->createQueryBuilder(AwinProduct::class);
$builder
    ->text('Sko Nike Classic Cortez för män -Svart')
    ->language('sv')
    ->selectMeta('score', 'textScore')
    ->sortMeta('score', 'textScore')
    ->sort('aw_product_id', 1)
    ->skip(2)
    ->limit(2);

You can retrieve the built query using getQuery() and receive an iterator by calling getIterator() on the query. The resulting query should be identical with the native query you've created above.

For the sake of completeness, allowDiskUse is an option for the aggregate command to work around the 100 MB memory limit for aggregation pipeline stages. The option allows using temporary files to do memory-intensive things (e.g. like an external sort). The query system does not have these limitations, which is why you don't need the option there.

stale commented

This issue has been automatically marked as stale because it has not had any recent activity. It will be closed in a week if no further activity occurs. Thank you for your contributions.

Closing due to lack of feedback. @shubaivan please report back if the above helped you.