Doctrine2 ODM Limit doesn't work / mongodb - php

I'm trying to skip and limit results, but I don't even get it to limit the results.
here's my code
$limit=5;
$fooQueryBuilder = $this->mongo->getManager()->createQueryBuilder('CustomCoreBundle:Foo');
$foos=$fooQueryBuilder->limit($limit)->getQuery()->execute();
var_dump(count($foos));
exit;
and the var_dump returns
int(321235)
and that's equal to all entities in the database, what am I doing wrong ?
$this->mongo->getManager()
is instance of
Doctrine\ODM\MongoDB\DocumentManager
and the builder is instance of
Doctrine\ODM\MongoDB\Query\Builder"
I just don't understand what's wrong, thanks for any hint

So, I found out the answer myself
it is working !
and I learned:
when you count() a cursor, no matter what the query, it returns the amount of all entities in database.
So my check to count the cursor to see if the limit is working was simply wrong

use count($result->toArray()) that solved my issue
count($result->toArray())

You can use $result->count($foundOnly = true)

Related

PHP Atlas.ORM returns always the same result

I want to load data from a SQLite database in PHP using Atlas.Orm.
When I run the following snippet, I get a set of 1773 results, but each result is the same!
$atlas = Atlas::new('sqlite:[Path To Database]');
$result = $atlas->select(Stop::class)->fetchRecords();
Can anyone tell me whats wrong here?
After several hours of desperation, I found the issue by myself. The ORM needs the PRIMARY_KEY constant in the corresponding *Table class to be set, otherwise fetching records will fail like this.

Laravel: How to get last N entries from DB

I have table of dogs in my DB and I want to retrieve N latest added dogs.
Only way that I found is something like this:
Dogs:all()->where(time, <=, another_time);
Is there another way how to do it? For example something like this Dogs:latest(5);
Thank you very much for any help :)
You may try something like this:
$dogs = Dogs::orderBy('id', 'desc')->take(5)->get();
Use orderBy with Descending order and take the first n numbers of records.
Update (Since the latest method has been added):
$dogs = Dogs::latest()->take(5)->get();
My solution for cleanliness is:
Dogs::latest()->take(5)->get();
It's the same as other answers, just with using built-in methods to handle common practices.
Dogs::orderBy('created_at','desc')->take(5)->get();
You can pass a negative integer n to take the last n elements.
Dogs::all()->take(-5)
This is good because you don't use orderBy which is bad when you have a big table.
You may also try like this:
$recentPost = Article::orderBy('id', 'desc')->limit(5)->get();
It's working fine for me in Laravel 5.6
I use it this way, as I find it cleaner:
$covidUpdate = COVIDUpdate::latest()->take(25)->get();
Ive come up with a solution that helps me achieve the same result using the array_slice() method. In my code I did array_slice( PickupResults::where('playerID', $this->getPlayerID())->get()->toArray(), -5 ); with -5 I wanted the last 5 results of the query.
The Alpha's solution is very elegant, however sometimes you need to re-sort (ascending order) the results in the database using SQL (to avoid in-memory sorting at the collection level), and an SQL subquery is a good way to achieve this.
It would be nice if Laravel was smart enough to recognise we want to create a subquery if we use the following ideal code...
$dogs = Dogs::orderByDesc('id')->take(5)->orderBy('id')->get();
...but this gets compiled to a single SQL query with conflicting ORDER BY clauses instead of the subquery that is required in this situation.
Creating a subquery in Laravel is unfortunately not simply as easy as the following pseudo-code that would be really nice to use...
$dogs = DB::subQuery(
Dogs::orderByDesc('id')->take(5)
)->orderBy('id');
...but the same result can be achieved using the following code:
$dogs = DB::table('id')->select('*')->fromSub(
Dogs::orderByDesc('id')->take(5)->toBase(),
'sq'
)->orderBy('id');
This generates the required SELECT * FROM (...) AS sq ... sql subquery construct, and the code is reasonably clean in terms of readability.)
Take particular note of the use of the ->toBase() function - which is required because fromSub() doesn't like to work with Eloquent model Eloquent\Builder instances, but seems to require a Query\Builder instance). (See: https://github.com/laravel/framework/issues/35631)
I hope this helps someone else, since I just spent a couple of hours researching how to achieve this myself. (I had a complex SQL query builder expression that needed to be limited to the last few rows in certain situations).
For getting last entry from DB
$variable= Model::orderBy('id', 'DESC')->limit(1)->get();
Imagine a situation where you want to get the latest record of data from the request header that was just inserted into the database:
$noOfFilesUploaded = count( $request->pic );// e.g 4
$model = new Model;
$model->latest()->take($noOfFilesUploaded);
This way your take() helper function gets the number of array data that was just sent via the request.
You can get only ids like so:
$model->latest()->take($noOfFilesUploaded)->puck('id')
use DB;
$dogs = DB::select(DB::raw("SELECT * FROM (SELECT * FROM dogs ORDER BY id DESC LIMIT 10) Var1 ORDER BY id ASC"));
Dogs::latest()->take(1)->first();
this code return the latest record in the collection
Can use this latest():
$dogs = Dogs::latest()->take(5)->get();

Zend modification. Adding MySQL FORCE INDEX hint

I am trying to extend the Zend library in order to get queries like this one:
SELECT * FROM item i **force index(ix)** ORDER BY date LIMIT 100;
I am working arround with this Zend forum issue solution: http://framework.zend.com/issues/browse/ZF-7570
However I have a problem. Look at the code below.
$select->forceIndex('index');
echo $select->assemble();
// I get the right SELECT query with the force index hint
$this->fecthAll($select);
// The server execute a wrong SELECT query without the force index hint
Some help?
I am not pretty sure why, but if I remove the echo clause, fetchAll executes the right query...
So that's the answer, remove echo
In my opinion, the patch you are using is broken. If you check the source, it unsets the FORCE INDEX parts when creating the query the first time.
If you check it, $select->assemble() == $select->assemble() should give false.

How do you work with a single ORM query result in FuelPHP?

I have a query that is returning a single result and I'm wondering if there's a way to access the properties of that result without having to loop through it since I am limiting it to a single result.
Here is my query:
$user = Model_User::find()
->where('email_address', Input::post('email_address'))
->where('password', Input::post('password'))
->limit(1);
The only way I've found to access the results is to run the get() method on $user and loop through the result, but I figured I was missing something and that there was an easier way to return $user as a single object that I can work with since I am limiting it to a single result.
What's the most efficient way to do this?
Did you try
$user->get_one()?
You could also do
$user = Model_User::find_by_email_address_and_password(Input::post('email_address'), Input::post('password'));
Have a nice day :)
Uku Loskit ask you the right syntax.
If you want to retrieve always a single result, you can merge the code:
$user = Model_User::find()
->where('email_address', Input::post('email_address'))
->where('password', Input::post('password'))
->get_one();
An advice for you: be careful using directly Input::post('var_name'), it would be better to use a validation before saving variables.
Another way is to set the framework to perfrom some action, like htmlentities(), for every $_GET and $_POST variable.

Plain SQL to Codeigniter syntax

I am facing a little trouble with converting this sql to codeigniter syntax. I can use this plain sql and getting results but I have to use return $this->db->query($sql, array($param))->result(); which I guess doesn't return an array (Not sure though, but i keep getting a error "Cannot use object of type stdClass as array in...", and I have no idea if that query can be modified to return an array or any other workaround is available.) Anyway, I guess the best thing to do for me is to follow the CI syntax of query and then use a return $query->result_array(); to get a result array from the query. I know it may be very basic stuff , but somehow I am not able to figure out how to exactly convert this sql to CI syntax. Any help would be appreciated. Thanks. Here is the sql below.
SELECT dirmast.entryID,dirmast.entryTitle,dirmast.entryShortDesc,dirsec.dirsecRefID
FROM dirmast,dirsec
WHERE dirsec.drtext = 'something'
AND dirsec.dirsecRefID = dirmast.entryID
GROUP BY dirsec.dirsecRefID
I think this will do what you want:
$this->db->select('dirmast.entryID,dirmast.entryTitle,dirmast.entryShortDesc,dirsec.dirsecRefID');
$this->db->from('dirmast');
$this->db->join('dirsec','dirsec.dirsecRefID = dirmast.entryID');
$this->db->where('dirsec.drtext','something');
$this->db->group_by('dirsec.dirsecRefID');
If you want your results in an array, you do ->result_array(), if you want it as an object, you do ->result(). Either way, you can use both Active Records and query().

Categories