Prioritizing CF_TITLE in a Verity result set
I have a request from a client who wants to be able to prioritize their product SKU in the search results. The SKU is in the defined key CF_TITLE. I'm not very good with verity and the documentation isn't great out there. I manag开发者_Go百科ed to modify it to find only the CF_TITLE but it affected the rest of the results. I'm also not sure the current criteria is correct either since it doesn't really follow any example syntax I've found.
So how can I modify the criteria so we can prioritize an exact match for "CF_TITLE" in the results without effecting the rest of the results?
This is their current search tag:
<cfsearch
collection="company"
name="SearchResults"
criteria="(<NOT> CF_KEY <MATCHES> #SearchKeywords#)
AND (#SearchKeywords#)"
status="Info">
Since Verity determines relevance largely based on the number of occurrences of the criteria, one way to "prioritise" results would be to artificially append the SKU multiple times to the "body" when indexing the collection.
You could do this either in your original SQL query, or you could use ColdFusion to massage the resultset to pad it with the SKUs before passing it to Verity. Here's an example of the latter option:
<!--- Get the product data--->
<cfquery name="qProducts" datasource="blog">
SELECT
ID
,SKU
,title
,description
FROM
products
</cfquery>
<!--- Massage the data to prioritise the SKU by creating a new query from the original --->
<cfset qProductsForIndex = QueryNew( "ID,title,body","Integer,VarChar,VarChar" )>
<cfloop query="qProducts">
<cfset QueryAddRow( qProductsForIndex )>
<cfset QuerySetCell( qProductsForIndex,"ID",qProducts.ID )>
<cfset QuerySetCell( qProductsForIndex,"title",qProducts.title )>
<!--- Add the SKU 5 times, separated by a semi-colon --->
<cfset QuerySetCell( qProductsForIndex,"body",qProducts.description & ";" & RepeatString( qProducts.SKU & ";",5 ) )>
</cfloop>
<!--- Pass the massaged query to Verity --->
<cfindex action="REFRESH"
collection="products"
type="CUSTOM"
query="qProductsForIndex"
key="ID"
title="title"
body="body">
Note the semi-colon separating the the extra SKUs, this ensures Verity will match them as separate occurrences.
I've used 5 as an example number, but you might start with just 2 and tune it upwards until you see the results you want.
Do the SKUs have a predictable format? If so then you could perhaps change the form of the criteria that's passed to verity if an SKU is detected. For example if your SKUs all began with 3 letters followed by 3 numbers:
<cfscript>
// forced example; replace this with actual keywords from the search form
searchKeyWords = "ABC123";
// RegEx to detect SKUs according to their format
if( REFind( "^\w{3,3}\d{3,3}$",searchKeyWords ) )
request.criteria = "CF_TITLE <CONTAINS> #searchKeyWords#";
else
request.criteria = searchKeyWords;
</cfscript>
<cfsearch
collection="company"
name="SearchResults"
criteria="#request.criteria#">
So if an SKU was detected verity would search just the title field. Otherwise it would do a normal search on the whole index. You'd probably need to vary the above according to how strictly things need to match, but you get the idea.
精彩评论