views:

63

answers:

2

I'm using CodeIgniter for a classifieds website. Here's a specific example of what I'm trying to achieve:

On page http://www.example.com/browse/Real-Estate all the Real Estate classifieds are listed. I'm using CI's Pagination Class to paginate the results.

On the leftbar, a set of filters are shown that correspond to each db column of the "Real Estate Classifieds" table. For example:

Type : House, Apartment Bedrooms : 1,2,3,4... Furnished: Yes, No etc.

Each time the user selects a value, a query runs and the results are updated with Ajax.

However, since the selecting of a value corresponds to an additional "WHERE" clause in the initial query, I was wondering which would be the best way to filter the already available results without re-running the query.

+1  A: 

Why are you opposed to running an additional query? If the user starts with a broad query with no filters, filtering it down would mean iterating over the result set and performing filter checks on every row. If the user starts with a narrow query with filters, changing or removing filters would require a new query anyway, and adding filters would require iteration over the result set.

If I were you, I'd build a filter system that works in all conditions, sends information to the server to be built into a query, builds a view with the query results, and returns the HTML as a string to the browser where you can use jQuery (or whatever) to insert it into your results box. Doing this would save you the most time, allow you to write the least amount of Javascript, and, I think, make your application appear quite snappy (as opposed to using Javascript to iterate over large result sets).

treeface
Actually, what you described is exactly what I have right now. I should have stated that the initial query is always SELECT * FROM TABLE LIMIT 20, and then the user narrows down the results. An idea would be to cache the queries into files and when building the html view, inject the values of the filters into the class of each result, like <div class="apartment 2bedrooms ..."> . Then on filtering, use jQuery selectors to hide the results that don't match.
Zack
That's a possibility. Playing with classes like that could cause you headaches down the road if ever you call some element "apartment" or add a new filter. Still though, you say you limit your query results to 20, so when a filter is added, you want to run the filter on only those 20 results? How would you fill out the rest of the list? It just seems like...you'd be adding way more headaches than you need, unless you really have very serious CPU constraints on the server.
treeface
Here is what I meant: Run a cron job every hour that queries "SELECT * FROM table" (no limit) and cache the results div box. On the "Browse" page, jQuery handles the pagination. When filtering, jQuery hides the irrelevant results and re-arranges the list so that it fills the page. But most probably you are right, I'm adding more headaches for perhaps a small increase in performance.
Zack
Ah interesting. Yeh, I suppose that's a possibility, but then you have to worry about what happens when the data changes. This would work quite well if you have persistent data, but if you see any changes, things could start getting wonky. Ah well, suffice it to say, I'm not exactly a database expert, so my advice is perhaps not the best. Still, I'd go for what is easiest for you. Start worrying about the minor performance issues when they become problems.
treeface
A: 

Basically at the beginning you can bring all the results by -

select * from TABLE

Then when user selects any specific criteria you can use ajax to post that criteria.

The ajax will be calling a controller function -

function update_criteria(){
//Here you can call an another function say aply_criteria as follows.

array_walk('your actual result array','apply_criteria');

//finally parse the html with new filtered result throuh ajax.

 echo $this->parser->parse('view_name','data array',TRUE);

//catch the above html in the sucess callback function of ajax and replace it in the 
//previous html page.

Note :- the parser i have used above is an library in an codigniter so make sure you load it before using.

}

function apply_criteria(){

//Actual logic to unset the specific key value pair 
//(which does not satisfy the  criteria depending on the post data) from array.

}

array_walk documentation - http://www.php.net/manual/en/function.array-walk.php

Alpesh
I haven't understand in the above from where does update_criteria() gets the results array? I mean in this line: array_walk('your actual result array','apply_criteria');
Zack
Initially when you are getting all results you have to save that result in the session and from session you have to get that everytime. But dont save the filtered result in the session.
Alpesh
That's a nice idea. However storing in session is not an option, since the size of the array might be as large as 8000 x 12. That could cause performance issues. I think I'm sticking with the "re-query" solution. I 'll see how it goes, and maybe try your solution, and perhaps cache the initial query results instead of storing them in session.
Zack