I'm using a geoNear() to calculate distances between objects in my Mongo database.
The query works perfectly, even with addition field filters such as ->field('name')->equals($name) etc...
This automatically populates a mapped field #ODM\Distance on the object.
$this->getQueryBuilder()
->geoNear((float) $query['near_longitude'], (float) $query['near_latitude'])
->spherical(true)
->distanceMultiplier(self::EARTH_RD_KM);
If I add an ->field('id')->in($array) however this distance is suddenly 0.
I'm not really sure where the information is lost.
Is this a limitation on how $in works on MongoDB?
You need to use "maxDistance" function
like this;
$this->getQueryBuilder()
->geoNear((float) $query['near_longitude'], (float)$query['near_latitude'])
->spherical(true)
->maxDistance(self::YOUR_DESIRED_KM_RADIUS / self::EARTH_RD_KM)
->distanceMultiplier(self::EARTH_RD_KM);
That way it sets a radius for your query.
Related
I am trying to extract from my php laravel some data like this:
$x = Carbon::now()->timestamp;
$data=Notifications->where('happened_at','>',$x)
->where('id_user',Auth::user()->getAuthIdentifier());
If I enter this sql statement in my oracle database directly it works perfectly:
select * from notifications where happened_at > '10-06-2017 00:11:12,000000000';
^ this returns correct, however in my php laravel it doesn't return the good rows(returns all the rows from the database)
Later Edit: The where is the problem, I just want to compare the timestamp location in my DB('happened_at') with the current time...I don't know how though
Let's break down your model call code.
// first, you retrieve all notifications and assign them to $data
$data = Notifications::all()
// then, you try to start a new query
->where('happened_at','>',$x)
// then, you continue the new query
->where('id_user',Auth::user()->getAuthIdentifier())
// and finally, you finish the call
;
So basically, you already get all rows at the beginning, and then you try to start building a query that you never execute. (But you can't, since all() returns a collection.)
Remove the all() and finish up with ->get() at the end, and it should work. (Although I don't know anything about Oracle timestamps.)
I have table (~150 columns with ~150k records) and project on Symfony 3 with Doctrine. In project is clasic filter to show results.
If you submit form i collect data in object $selectedInputOptions and build query looks like:
$query = $repository
->createQueryBuilder('t')
->select('t.idkatcountry', 't.idkatlocality', 't, MIN(t.price) AS priceFrom'......);
if(count($selectedInputOptions->getCountry()) > 0)
$query->andWhere('t.idkatcountry IN (:idkatcountry )')->setParameter('idkatcountry ', $selectedInputOptions->getCountry());
if(count($selectedInputOptions->getLocality()) > 0)
$query->andWhere('t.idkatlocality IN (:idkatlocality )')->setParameter('idkatlocality ', $selectedInputOptions->getLocality());
price column have decimal(15,2) datatype
Before i have in $repository->select('t.price') and everything was OK but after change this to 't, MIN(t.price) AS priceFrom' query execution time was increased +40% and in few cases (any input in form be blank = checks all records) +900%.
So my questions:
How i can cut execution time? (Is there some idexes for this?, Will help change datetype range let's say to decimal(6,2)?)
And bonus question :) Table has ~150columns but query for filtering using ~10-15 columns can i set some type of index for quicker selects?
EDIT:
changed column price to ineger - did not help
added index to column pricte - did not help
SOLUTION!
It was little mistake in select parameter using MIN().
Insted of:
't, MIN(t.price) AS priceFrom'
I used:
'MIN(t.price) AS priceFrom')'
Because t takes ALL columns (~150 in my case) and I didn't notice this... So now is everything OK and time is normal.
Here you can do one thing, stop loading unwanted data in entity, by using unset in jsonSerialize() method.
I'm lost at this point.
Here is what i have:
$criteria = new \EMongoCriteria();
$criteria->userId = new \MongoID($userId);
$criteria->expiresAt = array('>' => new \MongoDate(time()));
Then I'm running this:
$model->count($criteria);
And it always returns 0 when i know that there are documents that meet this criteria.
Any ideas?
UPDATE
findAllByAttributes() with the same criteria works perfectly. But I don't need those documents i need to count them.
When setting criteria field as property it uses simple comparision (field == value). You should set this criteria by calling field, like that:
$criteria->expiresAt('>', new \MongoDate(time()));
NOTE: Passing criteria to findAllByAttributes in wrong, it is not intended to work with EMongoCriteria, but with simple array. If you want to use criteria object pass it to findAll method.
$dm = $this->get('doctrine.odm.mongodb.document_manager');
$query = $dm->createQueryBuilder('MyBundle:Listing')
->select('title')
->field('coordinates')->geoNear(
(float)$longitude,
(float)$latitude
)->spherical(true);
$classifieds_array = $classifieds->toArray();
$data = array('success'=>true,'classifieds' => $classifieds_array,
'displaymessage' => $classifieds->count(). " Search Results Found");
Even though I am selecting just one field, for my result set, I am getting every thing back in collection along with title. Is this a bug?
NOTE: I commented out the ->field('coordinates')->geoNear((float)$longitude, (float)$latitude)->spherical(true) line and now the select seems to work. This is crazy.
The geoNear command in MongoDB doesn't seem to support filtering result fields, according to the documentation examples. Only a query option is supported to limit matched documents.
In your case, it also looks like mixing up the geoNear() and near() builder methods in Doctrine. Since you're operating on the coordinates field, the appropriate syntax would be near(). geoNear() is a top-level method to tell the builder you wish to use the command, which doesn't require a field name since it uses the one and only geospatial index on the collection.
For usage examples, I would advise looking at the query and builder unit tests in the Doctrine MongoDB library.
I have the following query:
$this->select()
->where("`name` LIKE ?",'%'.mysql_escape_string($name).'%')
Now I have the Zend_Paginator code:
$paginator = new Zend_Paginator(
// $d is an instance of Zend_Db_Select
new Zend_Paginator_Adapter_DbSelect($d)
);
$paginator->getAdapter()->setRowCount(200);
$paginator->setItemCountPerPage(15)
->setPageRange(10)
->setCurrentPageNumber($pag);
$this->view->data = $paginator;
As you see I'm passing the data to the view using $this->view->data = $paginator
Before I didn't had $paginator->getAdapter()->setRowCount(200);I could determinate If I have any data or not, what I mean with data, if the query has some results, so If the query has some results I show the to the user, if not, I need to show them a message(No results!)
But in this moment I don't know how can I determinate this, since count($paginator) doesn't work anymore because of $paginator->getAdapter()->setRowCount(200);and I'm using this because it taks about 7 sec for Zend_Paginator to count the page numbers.
So how can I find If my query has any results?
Why would you setRowCount() to a magic number? If whatever method Z_P is using to discover the total number of rows is taking a long time, you might want to override it that way, but you'd want to compute the actual value, wouldn't you?
In most cases, Z_P ought to automatically get the right number (internally, via a subquery). If that subquery is taking too long, you can try building your own Zend_Db_Select to perform the count, and pass that to setRowCount().