Querying by nested references values in mongodb / doctrine2 odm - mongodb

Hello ive got the following code:
$primer = function($dm, $className, $fieldName, $ids, $hints) {
$repository = $dm->getRepository($className);
$qb = $repository->createQueryBuilder()
->field('id')->in($ids)
->field('images')->prime(true);
$query = $qb->getQuery();
$query->execute()->toArray();
};
$qb = $followRepo
->createQueryBuilder()
->field('isActive')->equals(true)
->field('target')->prime($primer)
->field('follower')->references($return['user'])
->field('target.$ref')->equals('boards')
->field('target.createdBy.type')->equals('user') // here i dont know how to handle this
->sort('created', 'desc')
Is it even possible in mongo to query via target.createdBy.type?
target.createdBy is also ref.

Yes, it is possible to query on sub document properties using the dot notation, as per
the official documentation. I am pretty sure it wont work with a referencing in 1 step though.

Related

how to use Querybuilder in symfony 3.4 with mongodb doctrine?i have issue i try but this is not give data. this is code and display page

this is my code:
$role_id = $this->get('session')->get('role_id');
$em = $this->get('doctrine_mongodb')->getManager()->getRepository('AdminBundle:Rolemaster');
$role = $em->createQueryBuilder()->field('rolename')->notEqual('admin')->getQuery()->execute();
var_dump($role);exit; `
this is the image of output:
Outputimage
Please help me
This is the expected behavior as executing a query for Doctrine MongoDB query builder, returns a cursor for you to iterate over the results. You can refer to the documentation here.
If you want to get the result as an array you have to use toArray() on the cursor:
$role = $em->createQueryBuilder()
->field('rolename')
->notEqual('admin')
->getQuery()->execute()->toArray();

Doctrine MongoDB Query Builder addOr query not returning any results

I'm working on super simple search across multiple fields in a document to see if any of them has a single value. (Note: some fields are using regex to search if value is contained in string). Using query builder I constructed the following.
public function search($value, $limit, $offset=0, $orderby = '', $order='' )
{
$regexVal = new \MongoRegex('/^.*(\b'.str_replace(' ', '\s', $value).'\b).*?$/i');
$query = $this->repository->createQueryBuilder();
$query->addOr($query->expr()->field('location')->equals($regexVal));
$query->addOr($query->expr()->field('mappedData.name')->equals($regexVal));
$query->addOr($query->expr()->field('mappedData.first_name')->equals($regexVal));
$query->addOr($query->expr()->field('mappedData.last_name')->equals($regexVal));
$query->addOr($query->expr()->field('mappedData.email')->equals($value));
$query->addOr($query->expr()->field('email')->equals($value));
$query->addOr($query->expr()->field('organization')->equals($value));
$query->limit($limit)
->skip($offset);
if( ! empty($orderby) && $order ){
$query->sort($orderby, $order);
}
return $query->getQuery()->execute();
}
If I dump out the constructed query values I get the following array in this gist. https://gist.github.com/jchamb/04a0400c989cd28b1841 The extra association field in there is being added by a Doctrine Filter.
Through Query builder I don't get any results, however if I construct the query myself and run it in an admin app like genghis, I get the expected single document result.
Actual written mongodb string looks like this. https://gist.github.com/jchamb/ce60829480576a88290d
This project is a zend2 app that was already using doctrine and mongo. I'm not much of an expert with mongo in general so I'm not sure what i'm doing wrong inside of Query Builder that i'm not getting the same result as executing the query directly. I can't find any info on stack or the query builder docs that gives any extra clues for the multiple addOrs syntax either.
Any help or direction would be really appreciated, in the most basic form I need query builder to get a document where association = x and ( field1 = val or field2 = value).
Thanks!
Really unsure what the exact issue was with the above, but after playing around, switching the order of query builder around fixes the problem.
public function search($value, $limit, $offset=0, $orderby = '', $order='' )
{
$regexVal = new \MongoRegex('/^.*(\b'.str_replace(' ', '\s', $value).'\b).*?$/i');
$query = $this->repository->createQueryBuilder()
->find()
->limit($limit)
->skip($offset);
$query->addOr($query->expr()->field('location')->equals($regexVal));
$query->addOr($query->expr()->field('mappedData.name')->equals($regexVal));
$query->addOr($query->expr()->field('mappedData.first_name')->equals($regexVal));
$query->addOr($query->expr()->field('mappedData.last_name')->equals($regexVal));
$query->addOr($query->expr()->field('mappedData.email')->equals($value));
$query->addOr($query->expr()->field('email')->equals($value));
$query->addOr($query->expr()->field('organization')->equals($value));
if( ! empty($orderby) && $order ){
$query->sort($orderby, $order);
}
return $query->getQuery()->execute();
}
Would love to still hear some feedback about why this works and the above didn't if anyone know more about the internals of query builder.

Laravel 5 Eloquent with MongoDB - get array of column names from document

this is becoming frustrating beyond imagination.
I need to get the column names from a table using Eloquent ORM in Laravel 5 combined with MongoDB. I have found some examples, but none of them is working for me as they are probably made for SQL specifically. I tried this and this without success, any idea?
Thanks!
It would be best to use the raw() method in this case and use the native MongoCollection methods like find() to iterate over the collection and get the keys in the documents array:
// Returns an array of field names from a collection of User models.
$keys = DB::collection('users')->raw(function($collection)
{
$cursor = $collection->find();
$array = iterator_to_array($cursor);
$fields = array();
foreach ($array as $k=>$v) {
foreach ($v as $a=>$b) {
$fields[] = $a;
}
}
return array_values(array_unique($fields));
});
MongoDB doesn't have columns or tables - the whole point is that it's schemaless therefore there are no columns for you to get the names of.
Because every document can be different, you'd need to get all documents in your collection and build an array of unique keys that each document contains.
See this answer:
MongoDB Get names of all keys in collection

Out of memory exception thrown on basic Doctrine MongoDB

I have about 60k documents in my database and I cannot query for them. The only way I have been able to successfully retrieve them is with the hydrate(false) option.
I have tried both:
$dm = $this->get('doctrine_mongodb')->getManager();
$qb = $dm->createQueryBuilder('BConwayWebsiteBundle:Business')
->eagerCursor(true);
$query = $qb->getQuery();
$results = $query->execute();
and
$dm = $this->get('doctrine_mongodb')->getManager();
$qb = $dm->createQueryBuilder('BConwayWebsiteBundle:Business');
$query = $qb->getQuery();
$results = $query->execute();
If I dump $results->isInitialized() it is false. I believe that is because I have not utilized it yet at that point. Any accesing I try to do causes the memory issue though. Even something as basic as $results->count().
[2013-10-01 23:54:55] doctrine.INFO: MongoDB query: {"find":true,"query":[],"fields":[],"db":"ClosedForTheHoliday","collection":"businesses"} [] []
[2013-10-01 23:54:55] doctrine.INFO: MongoDB query: {"limit":true,"limitNum":null,"query":[],"fields":[]} [] []
[2013-10-01 23:54:55] doctrine.INFO: MongoDB query: {"skip":true,"skipNum":null,"query":[],"fields":[]} [] []
[2013-10-01 23:54:55] doctrine.INFO: MongoDB query: {"sort":true,"sortFields":[],"query":[],"fields":[]} [] []
[2013-10-01 23:54:56] emergency.EMERGENCY: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes) {"type":1,"file":"/media/sf_sites/cfth_com/vendor/doctrine/mongodb/lib/Doctrine/MongoDB/Cursor.php","line":237} []
UPDATE: If I limit my results to 2000, it works. Furthermore, if I select only the two fields that I am going to use after the query, I can limit it to 15000 and have success. When I limit it to 2000 the dev debug bar says that the query used 120MB of memory. I need to be able to iterate through all of the results, and it cannot be paginated. It seems like that should be possible without having 100MB+ queries...
I only needed distinct data from two fields, so this is what I ended up doing:
$dm = $this->get('doctrine_mongodb')->getManager();
// Get organization name from all businesses (distinct)
$organizations = $dm->createQueryBuilder('BConwayWebsiteBundle:Business')
->distinct('organization')
->getQuery()
->toArray();
// Get business name from all businesses (distinct)
$names = $dm->createQueryBuilder('BConwayWebsiteBundle:Business')
->field('organization')->equals('')
->field('organization')->equals(null)
->distinct('name')
->getQuery()
->toArray();
// Create new array from results of both queries
$businesses = array_merge($organizations, $names);
// Filter out any null or empty values
$businesses = array_filter($businesses, function($item) {
return (!is_null($item) && strlen($item) > 0);
});
// Filter out any duplicates
array_unique($businesses);
// Sort array case-insensitive
sort($businesses, SORT_STRING | SORT_FLAG_CASE);
Since Doctrine MongoDB ODM is a persistence manager (likewise with Doctrine ORM 2.x for relational databases), references to hydrated objects are stored internally and will not be recovered by PHP's garbage collection as easily as if you were iterating over non-hydrated array results that quickly leave scope.
For any batch operations in Doctrine, you'll want to either periodically clear() the object manager of all managed objects, or manually detach() individual objects. A periodic clear() would probably be easiest in your case, as you could do it every X iterations through the results. You can find some code examples and a discussion of this solution in this blog post. Although it's written from the perspective of the ORM and its EntityManager class, ODM's DocumentManager implements the same ObjectManager interface from the Doctrine Common library, which is where you'll find the detach() and clear() methods.

how to write query for mongodb to pass in knp paginator in symfony2

i am using knp paginator bundle for pagination.
i know to use knp paginator for doctrine. but i don't know in mongodb.
below code which show for doctrine ORM query which pass to knp paginator.
$em = $this->get('doctrine.orm.entity_manager');
$dql = "SELECT a FROM AdwindBannerBundle:Banner a";
$query = $em->createQuery($dql);
$pagination = $this->get('knp_paginator')->paginate($query,$page,10);
same way i want to use for ODM (mongoDB).
but i have confusion that what kind of query i have to use for ODM(mongodb) to pass in knp paginator?
Maybe
$dm = $this->get('doctrine_mongodb')->getManager();
$qb = $dm->createQueryBuilder('AcmeDemoBundle:User');
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate(
$qb,
$this->get('request')->query->get('page', 1)/*page number*/,
10/*limit per page*/
);