Count search criteria record based on search done

2020-03-05 03:26发布

问题:

I have a search form which provides searching properties for holiday in a specific country based on it's availability specific date. Search section has 2 sections "basic search" & "advance search".

Basic search contains country dropdown and date field. In advance search we have multiple filters for hotels like "Bedrooms" (1 bedroom, 2 bedroom etc) and then property type (apartment, villa, etc)

I want to show the search filter options with a count such as "1 bedroom (23 properties)" and same for other search filter options.

I am using php/mysql to create this application, so what comes first in my mind is to run multiple queries for all search filters and get the COUNT result from mysql and show it. I have about 10-12 different filters on my page. Also I have to show count records dynamically based on all search options (basic and advanced) selected.

Running multiple queries on the page will make it load forever and it will not show content due to multiple query load. Is there any better & faster way to do this?

Please help, thanks!

回答1:

I've tried to do this before, and it can get very slow depending on how many filters you allow and how many hotels you list, not to mention how you deal with duplicate hotels.

Ultimately though you will have very few filter options

  • Property type : normalise this in a separate table
  • Bedrooms : store this as a tinyint or smallint (either unsigned), can't imagine there being properties above 255 bedrooms, and definitely not above 65k
  • Location : normalise this in a separate table, ideally in a tree format to ensure relationships are noted
  • Star rating : this can be stored as a tinyint unsigned

Now your problem here is that if someone applies a filter for 3 bedrooms upwards, you still should be getting values for 2 bedrooms, 1 bedroom, as changing the filter back to that will yield results.

At the end of the day I addressed this using a very large memory table, some logic to build WHERE and JOIN statements, and an individual query counting up records within a set grouping. This was for doing similar to users holiday search results though, and as such the data was considered entirely transient. For your purposes a far smaller memory table is likely to be acceptable, however the principle is similar.



回答2:

Use the GROUP BY clause in conjunction with COUNT on your SELECT statement. For example, I defined a little test table such as

create table rooms (
rooms INT NOT NULL,
name VARCHAR(10)
)

And then ran the query

SELECT rooms,COUNT(*) FROM rooms GROUP BY rooms;

This gives you a result with each room count and the number of entries with that value.



回答3:

What you're trying to achieve is called faceted search.

This isn't a problem suited to a relational database like MySQL.

You can use ElasticSearch or AWS CloudSearch and their facet features.

Just remember that these are search servers and don't replace your main database. They only perform search operations that return the IDs that correspond to the actual records stored in your database. You still need MySQL (or MongoDB etc).