A full-text search shall match whole words. For example, a full-text search on comments that contain “perform a search” or “text search” or “text” will return a comment that contains “I want to perform a text search in AEM”.
To implement the same in AEM6, I have used QueryBuilder API which is a service for building Queries for searching the Java Content Repository and is easily extensible.
Demonstration with code:
Populate in a map all the predicates with the values.
Fulltext contains the value of the searchKey which will be searched in the url and the content of the cq:page, under the specified path
String pageTitle, pagePath
Map params = [:]
params["path"] = path
params["type"] = "cq:Page"
params["fulltext"] = searchKey
params["orderby"] = "@jcr:score"
now use the Query interface to create a query object that will, in turn, use the builder object of Query Builder interface to build the query.
Query query = builder.createQuery(PredicateGroup.create(params), session)
//for pagination
query.setStart(startPage) // same as params["p.offset"] = startPage.toString()
query.setHitsPerPage(offset) // same as params["p.limit"] = offset.toString()
searchResult will contain the result of the JCR query. A hit represents a single search result that is adapted to a page so as to fetch the page title and page url for display.
SearchResult searchResult = query.result
Long totalHits = searchResult.getTotalMatches()
for (Hit hit : searchResult.hits) {
Page page = hit.resource.adaptTo(Page)
pageTitle = page.title
pagePath = page.path
searchHit = new JSONObject()
searchHit.put("totalHits", totalHits)
searchHit.put("path", pagePath)
if (!pageTitle) {
pageTitle = pagePath.substring(pagePath.lastIndexOf('/') + 1, pagePath.length())
}
searchHit.put("title", pageTitle)
resultArray.put(searchHit)
}
resultObject.put("data", resultArray)
return resultObject
The desired output looks like below:
Populate in a map all the predicates with the values.
Fulltext contains the value of the searchKey which will be searched in the url and the content of the cq:page, under the specified path
String pageTitle, pagePath
Map params = [:]
params["path"] = path
params["type"] = "cq:Page"
params["fulltext"] = searchKey
params["orderby"] = "@jcr:score"
now use the Query interface to create a query object that will, in turn, use the builder object of Query Builder interface to build the query.
Query query = builder.createQuery(PredicateGroup.create(params), session)
//for pagination
query.setStart(startPage) // same as params["p.offset"] = startPage.toString()
query.setHitsPerPage(offset) // same as params["p.limit"] = offset.toString()
searchResult will contain the result of the JCR query. A hit represents a single search result that is adapted to a page so as to fetch the page title and page url for display.
SearchResult searchResult = query.result
Long totalHits = searchResult.getTotalMatches()
for (Hit hit : searchResult.hits) {
Page page = hit.resource.adaptTo(Page)
pageTitle = page.title
pagePath = page.path
searchHit = new JSONObject()
searchHit.put("totalHits", totalHits)
searchHit.put("path", pagePath)
if (!pageTitle) {
pageTitle = pagePath.substring(pagePath.lastIndexOf('/') + 1, pagePath.length())
}
searchHit.put("title", pageTitle)
resultArray.put(searchHit)
}
resultObject.put("data", resultArray)
return resultObject
The desired output looks like below:
This much should be sufficient to design a working Site Search component in AEM that performs fulltext Search and displays paginated results. I will introduce advanced fulltext queries in my forthcoming post.
No comments:
Post a Comment
If you have any doubts or questions, please let us know.