Writing an optimised and efficient search engine with mySQL and ColdFusion
- by Mel
I have a search page with the following scenarios listed below. I was told there was a better way to do it, but not how, and that I am using too many if statements, and that it's prone to causing an error through url manipulation:
Search.cfm will processes a search made from a search bar present on all pages, with one search input (titleName).
If search.cfm is accessed manually (through URL not through using the simple search bar on all pages) it displays an advanced search form with three inputs (titleName, genreID, platformID) or it evaluates searchResponse variable and decides what to do.
If simple search query is blank, has no results, or less than 3 characters it displays an error
If advanced search query is blank, has no results, or less than 3 characters it displays an error
If any successful search returns results, they come back normally.
The top-of-page logic is as follows:
<!---SET DEFAULT VARIABLE--->
<cfparam name="variables.searchResponse" default="">
<!---CHECK TO SEE IF SIMPLE SEARCH A FORM WAS SUBMITTED AND EXECUTE SEARCH IF IT WAS--->
<cfif IsDefined("Form.simpleSearch") AND Len(Trim(Form.titleName)) LTE 2>
<cfset variables.searchResponse = "invalidString">
<cfelseif IsDefined("Form.simpleSearch") AND Len(Trim(Form.titleName)) GTE 3>
<!---EXECUTE METHOD AND GET DATA--->
<cfinvoke component="myComponent" method="simpleSearch" searchString="#Form.titleName#" returnvariable="simpleSearchResult">
<cfset variables.searchResponse = "simpleSearchResult">
</cfif>
<!---CHECK IF ANY RECORDS WERE FOUND--->
<cfif IsDefined("variables.simpleSearchResult") AND simpleSearchResult.RecordCount IS 0>
<cfset variables.searchResponse = "noResult">
</cfif>
<!---CHECK IF ADVANCED SEARCH FORM WAS SUBMITTED--->
<cfif IsDefined("Form.AdvancedSearch") AND Len(Trim(Form.titleName)) LTE 2>
<cfset variables.searchResponse = "invalidString">
<cfelseif IsDefined("Form.advancedSearch") AND Len(Trim(Form.titleName)) GTE 2>
<!---EXECUTE METHOD AND GET DATA--->
<cfinvoke component="myComponent" method="advancedSearch" returnvariable="advancedSearchResult" titleName="#Form.titleName#" genreID="#Form.genreID#" platformID="#Form.platformID#">
<cfset variables.searchResponse = "advancedSearchResult">
</cfif>
<!---CHECK IF ANY RECORDS WERE FOUND--->
<cfif IsDefined("variables.advancedSearchResult") AND advancedSearchResult.RecordCount IS 0>
<cfset variables.searchResponse = "noResult">
</cfif>
I'm using the searchResponse variable to decide what the the page displays, based on the following scenarios:
<!---ALWAYS DISPLAY SIMPLE SEARCH BAR AS IT'S PART OF THE HEADER--->
<form name="simpleSearch" action="search.cfm" method="post">
<input type="hidden" name="simpleSearch" />
<input type="text" name="titleName" />
<input type="button" value="Search" onclick="form.submit()" />
</form>
<!---IF NO SEARCH WAS SUBMITTED DISPLAY DEFAULT FORM--->
<cfif searchResponse IS "">
<h1>Advanced Search</h1>
<!---DISPLAY FORM--->
<form name="advancedSearch" action="search.cfm" method="post">
<input type="hidden" name="advancedSearch" />
<input type="text" name="titleName" />
<input type="text" name="genreID" />
<input type="text" name="platformID" />
<input type="button" value="Search" onclick="form.submit()" />
</form>
</cfif>
<!---IF SEARCH IS BLANK OR LESS THAN 3 CHARACTERS DISPLAY ERROR MESSAGE--->
<cfif searchResponse IS "invalidString">
<cfoutput>
<h1>INVALID SEARCH</h1>
</cfoutput>
</cfif>
<!---IF SEARCH WAS MADE BUT NO RESULTS WERE FOUND--->
<cfif searchResponse IS "noResult">
<cfoutput>
<h1>NO RESULT FOUND</h1>
</cfoutput>
</cfif>
<!---IF SIMPLE SEARCH WAS MADE A RESULT WAS FOUND--->
<cfif searchResponse IS "simpleSearchResult">
<cfoutput>
<h1>Search Results</h1>
</cfoutput>
<cfoutput query="simpleSearchResult">
<!---DISPLAY QUERY DATA--->
</cfoutput>
</cfif>
<!---IF ADVANCED SEARCH WAS MADE A RESULT WAS FOUND--->
<cfif searchResponse IS "advancedSearchResult">
<cfoutput>
<h1>Search Results</h1>
<p>Your search for "#Form.titleName#" returned #advancedSearchResult.RecordCount# result(s).</p>
</cfoutput>
<cfoutput query="advancedSearchResult">
<!---DISPLAY QUERY DATA--->
</cfoutput>
</cfif>
Is my logic a) not efficient because my if statements/is there a better way to do this? And b) Can you see any scenarios where my code can break? I've tested it but I have not been able to find any issues with it. And I have no way of measuring performance. Any thoughts and ideas would be greatly appreciated.
Many thanks