2

I want to select one random document from MongoDB collection. If I'd used MySQL, my solution would be similar to this.

How can I select a random document from MongoDB Collection using Doctrine ODM query builder?

Community
  • 1
  • 1
Łukasz D. Tulikowski
  • 1,440
  • 1
  • 17
  • 36

4 Answers4

1

I've solved my problem in this way:

public function getRandomUser()
{
    $qb = $this->getDocumentManager()->createQueryBuilder('AppBundle:User');
    $count =  $qb->getQuery()->count();
    $skip_count = random_int(0, $count);
    $qb->skip($skip_count);

    return $qb->getQuery()->getSingleResult();
}
Łukasz D. Tulikowski
  • 1,440
  • 1
  • 17
  • 36
1
<?php

// Create Query Builder.
$dm = $this->getDocumentManager()->createQueryBuilder('Document');

// Count documents.
$count = $dm->getQuery()->execute()->count();

// Get random number not exceeding $count variable.
$random = mt_rand(0, $count);

// Query for document with skip.
$random_document = $dm->skip($random)
                      ->getQuery()
                      ->getSingleResult();
malcolm
  • 5,486
  • 26
  • 45
1

Since you Mongo server is 3.2 or later, you can use $sample aggregation command:

$ab = $this->dm->createAggregationBuilder(User::class);
$ab->sample($count);

return $ab->hydrate(User::class)->execute();

Keep in mind that result set can contains not unique elements, additional reading about $sample https://docs.mongodb.com/manual/reference/operator/aggregation/sample/#behavior

For old Mongo servers you should set random value to every document when persisting and use $lt-$gt query to fetch random set, please refer to Random record from MongoDB

George Novik
  • 153
  • 1
  • 10
0

Try this solution:

public function getRandomDocument()
{
    $qb = $this->getDocumentManager()->createQueryBuilder('YourBundle:TargetDocument');
    $count =  $qb->getQuery()->count();
    $skip_count = random_int(0, $count);
    $qb->skip($skip_count);

    return $qb->getQuery()->getSingleResult();
}