DevLearningTools

MODULE 14 · LESSON 10

cfsearch

Querying an indexed collection with cfsearch: relevance-ranked results, the full result-column reference (score, summary, key, and more), and highlighting matched terms with contextHighlightBegin/End.

New lessons are added one at a time as the course gets built out — a graded quiz for each lesson is still on the way.

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

Tag Syntax
<cfsearch name="results" collection="productDocs" criteria="wireless headphones" maxrows="20">

<cfoutput query="results">
    <h3>#title# (score: #score#)</h3>
    <p>#summary#</p>
</cfoutput>
CFScript
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>");
}
NOTE

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

ColumnContains
scoreRelevance ranking for this result
titleThe document or row's indexed title
summaryAn excerpt of matched content, with highlighting applied
keyThe unique identifier set when it was indexed
urlThe indexed URL, if one was set
custom1 / custom2Any custom data attached during indexing
recordCountTotal number of matching results
currentRowThe current row's position in the result set
recordsSearchedHow 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.

CFScript
cfsearch(
    name = "results",
    collection = "productDocs",
    criteria = "wireless headphones",
    contextHighlightBegin = "<mark class='hit'>",
    contextHighlightEnd = "</mark>",
    contextPassages = 2,
    contextBytes = 200
);
NOTE

contextPassages controls how many separate excerpts appear in summary, contextBytes caps how long each one can be.

Paginating Results

CFScript
pageSize = 10;
currentPage = 2;

cfsearch(
    name = "results",
    collection = "productDocs",
    criteria = "wireless headphones",
    maxrows = pageSize,
    startrow = ((currentPage - 1) * pageSize) + 1
);
NOTE

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.