cfcollection created the container, cfindex filled it with data. cfsearch is the payoff: querying that collection and getting back relevance-ranked results, with the matched text highlighted, in a single tag.
Learning Objectives
After completing this lesson, you'll be able to:
- Run a basic search against a collection with cfsearch.
- Read every column a search result carries: score, summary, key, and more.
- Highlight matched search terms in a result summary.
- Paginate search results with maxrows and startrow.
A Basic Search
<cfsearch name="results" collection="productDocs" criteria="wireless headphones" maxrows="20">
<cfoutput query="results">
<h3>#title# (score: #score#)</h3>
<p>#summary#</p>
</cfoutput>cfsearch(name = "results", collection = "productDocs", criteria = "wireless headphones", maxrows = 20);
for (row in results) {
writeOutput("<h3>#row.title# (score: #row.score#)</h3><p>#row.summary#</p>");
}cfsearch's result behaves like a normal CFML query object, loop over it, reference it with query-of-queries, or output it with cfoutput query="..." exactly like a database query result.
Every Column a Result Carries
| Column | Contains |
|---|---|
| score | Relevance ranking for this result |
| title | The document or row's indexed title |
| summary | An excerpt of matched content, with highlighting applied |
| key | The unique identifier set when it was indexed |
| url | The indexed URL, if one was set |
| custom1 / custom2 | Any custom data attached during indexing |
| recordCount | Total number of matching results |
| currentRow | The current row's position in the result set |
| recordsSearched | How many indexed documents were actually searched |
Highlighting Matched Terms
The summary column already gets the matched search terms wrapped in HTML by default, contextHighlightBegin and contextHighlightEnd control exactly what that wrapping HTML actually is.
cfsearch(
name = "results",
collection = "productDocs",
criteria = "wireless headphones",
contextHighlightBegin = "<mark class='hit'>",
contextHighlightEnd = "</mark>",
contextPassages = 2,
contextBytes = 200
);contextPassages controls how many separate excerpts appear in summary, contextBytes caps how long each one can be.
Paginating Results
pageSize = 10;
currentPage = 2;
cfsearch(
name = "results",
collection = "productDocs",
criteria = "wireless headphones",
maxrows = pageSize,
startrow = ((currentPage - 1) * pageSize) + 1
);startrow is 1-based, not 0-based, the first result is row 1, not row 0.
Common Beginner Mistakes
Searching a collection that hasn't been indexed with cfindex yet
cfcollection alone creates an empty, searchable-but-empty collection. Nothing comes back from cfsearch until cfindex has actually populated it with data.
Assuming startrow is 0-based
It isn't, the first row is startrow=1. Treating it as 0-based skips the first real result on every page.
Not setting maxrows on a large collection
Without it, cfsearch returns every matching row, potentially a very large result set. Adobe's own documentation recommends keeping maxrows at 300 or lower for performance.
Best Practices
- Always set maxrows explicitly, rather than returning every match on a large collection.
- Use contextHighlightBegin/End with real HTML (like <mark>) so matched terms are visually obvious in results.
- Remember cfsearch's result behaves exactly like a normal query object, all the usual query tools (cfoutput, Query of Queries, looping) work on it directly.
Interview Questions
What does the score column in a cfsearch result actually represent?
A relevance ranking for how well that particular document matched the search criteria, higher generally means a stronger match. It's what lets results be sorted by relevance rather than an arbitrary order.
How would you show matched search terms highlighted in a results page?
Set contextHighlightBegin and contextHighlightEnd to whatever HTML should wrap a match (commonly <mark>...</mark>), then output the summary column, which already contains the highlighted excerpt.
Walk through the full workflow to make a set of database records searchable.
cfcollection action="create" makes the collection. cfindex type="custom" with a query object indexes the rows, mapping key/title/body to columns. cfsearch then queries that collection with a criteria string and returns ranked, highlighted results, exactly as a normal query object.
Summary
In this lesson, you searched a collection with cfsearch, read every column a result carries (score, summary, key, and more), highlighted matched terms with contextHighlightBegin/End, and paginated results with maxrows and startrow. Together with the previous two lessons, that's the complete cfcollection → cfindex → cfsearch workflow for full-text search in ColdFusion.
What's Next?
That completes Module 14: APIs & Modern Development. The next module covers security: SQL injection prevention, XSS prevention, password hashing, encryption, and secure sessions.