Frank Vèssia Posted September 10, 2013 Share Posted September 10, 2013 Maybe it's a stupid question but I'm wondering what's the best selector between $pages->get($pageID); $pages->get("template=book,id=$pageID"); Assuming i have thousands of pages it's better to filter also by template (or other fields) or not, in terms of performance ? Link to comment Share on other sites More sharing options...
Martijn Geerts Posted September 10, 2013 Share Posted September 10, 2013 The first one. Keep in mind that getting pages by ID if difficult to read. (needs comments most of the time) If it are your own pages & the page is deleted, your script won't work anymore. 2 Link to comment Share on other sites More sharing options...
adrian Posted September 10, 2013 Share Posted September 10, 2013 Martijn's points are very valid, but I would also argue that the advantage to getting by ID rather than name, is that the client can change the name of the page if they want and the selector will still work, so it is a bit of a trade-off. I agree that the second makes no sense. Any selector together with ID will always be meaningless as only one page can have that ID anyway. See Soma's post below. 1 Link to comment Share on other sites More sharing options...
Soma Posted September 10, 2013 Share Posted September 10, 2013 Both the same and since you specify a id explicit, it will just get that page and the template wouldn't be required. But actually there's a difference in it: $pages->get($pageID); Will get the page even if unpublished, in trash, hidden or user would have no access! It isn't doing a real "find" and it's much like getting a row from DB no matter what. It's like a shortcut PW is doing in this case not doing a usual page finder search. $pages->get("template=book,id=$pageID"); This will convert the previous into a "page finder search" much like when using a find("template=book, title=Mytitle"), thus behave different. It will not return a page if unpublished or hidden or in trash or the user has no access. EDIT: In fact in the last one, it will even get the page even if the template isn't correct! So the id=id is the key here. Any selector will get ignored. So doesn't really make sense to add selector if you got the ID. Page ID is one of the things that's unique an always the same untill you delete it. 4 Link to comment Share on other sites More sharing options...
adrian Posted September 10, 2013 Share Posted September 10, 2013 I didn't know that Soma - thanks for the correction! Link to comment Share on other sites More sharing options...
kongondo Posted September 10, 2013 Share Posted September 10, 2013 If you want to read more about what Soma is saying (and have the time )+ some of the thinking behind it, check out this long thread, maybe from post #19 http://processwire.com/talk/topic/3217-field-set-to-unique-in-table/ Link to comment Share on other sites More sharing options...
Soma Posted September 10, 2013 Share Posted September 10, 2013 Also maybe worth noting is that if you specify multiple id's... $pages->get(" id=1001|1004|2003|3233,template=book,title=Mytitle"); This will be again different since it's not explicit anymore, and additional selectors will again be validated. Link to comment Share on other sites More sharing options...
Frank Vèssia Posted September 10, 2013 Author Share Posted September 10, 2013 Thanks guys for the replies, i was thinking about performance in terms of time for getting the page, maybe using "template" or other fields in addition to the ID was faster for PW to get that page because its' like: don't search in all pages to find that ID but search only in the pages having that template....but i got the point Link to comment Share on other sites More sharing options...
Soma Posted September 10, 2013 Share Posted September 10, 2013 It's not like that PW need to step through a forest to look for tree with a number on it. It has google earth showing it with a bubble "here I am". 4 Link to comment Share on other sites More sharing options...
ryan Posted September 14, 2013 Share Posted September 14, 2013 Sevarf2, you are correct about something here in that theoretically, supplying the template to the find() call should enable it to run faster. ProcessWire needs to know the template for a page before it starts loading it. So it'll query the DB for the page's template if it doesn't already know it. However, we don't have that optimization in place for $pages->find() at present, so your $pages->get("id=123, template=book"); doesn't benefit from that. But you can take advantage of that optimization by using the $pages->getById() method. It would technically be the fastest way to retrieve a page, but it's rare that I would be up for using it when developing a site (I only use it for core development). But it may be worth trying if you are trying to optimize a large amount of page retrievals. I'm not sure it'll make much difference in the end, but it's worth a shot. $template = $templates->get('book'); $page = $pages->getById($page_id, $template)->first(); The getById() method is really meant for retrieving multiple pages, which is why it returns a PageArray. If you have multiple pages using the same template, you can retrieve all of them here: $pageArray = $pages->getById(array(123,456,789), $template); If you can also supply a parent_id to the method (meaning, you already know all the provided page IDs have the same template and parent), it can use that for a little further optimization: $pageArray = $pages->getById(array(123,45,789), $template, $parent_id); Btw, the purpose of $pages->getById() method is as a support for all the other get(), find() and children() methods in ProcessWire (or anything else that returns a Page or PageArray from the DB). All pages loaded from the database are loaded by the getById() method, so all the other get/find methods are actually front-ends to it. getById() was never intended to be part of the public API though. 7 Link to comment Share on other sites More sharing options...
Soma Posted September 14, 2013 Share Posted September 14, 2013 Ryan in my tests, this doesn't work as in your examples. $template = $templates->get('basic-page'); $p = $pages->getById(1386, $template)->first(); The page 1386 has the template "basic-page" but the query doesn't return it. But it does find it when using this: $template = $templates->get('basic-page'); $p = $pages->getById(array(1386), $template)->first(); BUT it also returns the page when I specify a wrong template $template = $templates->get('custom'); $p = $pages->getById(array(1386), $template)->first(); I'm not sure what all about it when using id's to retrieve a page how would a template be of any benefit? 1 Link to comment Share on other sites More sharing options...
onjegolders Posted September 14, 2013 Share Posted September 14, 2013 Sometimes I prefer getting pages by template if appropriate, it means the name can be changed yet the "about" template or "contact" template is unlikely to. 1 Link to comment Share on other sites More sharing options...
ryan Posted September 15, 2013 Share Posted September 15, 2013 The page 1386 has the template "basic-page" but the query doesn't return it. Sorry, writing in browser, I forgot the quotes around the value. It expects an array or a csv string, but maybe I should update it to support a single integer as well. But currently any of these should work: $p = $pages->getById("123", $template)->first(); $p = $pages->getById("123,456,789", $template)->first(); $p = $pages->getById(array(123), $template)->first(); $p = $pages->getById(array(123,456,789), $template)->first(); BUT it also returns the page when I specify a wrong template This may be possible (though not yet sure how). But it assumes you are specifying a template because you know what template it should use. This is why it can increase performance: because it doesn't have to go determine that for itself. It may give you a frankenstein page by specifying the wrong template. There is a reason why this function is not meant for the public API–it's low-level and really meant to be accessed through the other API functions. So if you use it, and aren't certain of the template already, then it's best not to specify the template. Most of PW's internal calls (resulting from a find or a get) do use this optimization, passing the template and the parent to getById(). I'm not sure what all about it when using id's to retrieve a page how would a template be of any benefit? It needs to know the template in order to know which fields are contained by the template's fieldgroup. This is so that it can determine which fields should be joined with the main page loading query (autojoin). A few years into this, I find that I don't really need to use autojoin fields all that much (perhaps MySQL has gotten faster), so we may be able to change or get rid of this down the road. Link to comment Share on other sites More sharing options...
Frank Vèssia Posted September 16, 2013 Author Share Posted September 16, 2013 thanks Ryan, I will implement this solution and let you know about performance 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now