{"id":19545,"date":"2015-07-07T16:06:42","date_gmt":"2015-07-07T10:36:42","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=19545"},"modified":"2016-08-30T10:48:45","modified_gmt":"2016-08-30T05:18:45","slug":"full-text-search-in-aem-using-query-builder","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/full-text-search-in-aem-using-query-builder\/","title":{"rendered":"Full Text Search in AEM using Query Builder"},"content":{"rendered":"<p>The <em style=\"font-style: italic !important;\">full-text field search<\/em> allows you to look for a field anywhere in a webpage, be it the title, content, or the url of a webpage.<\/p>\n<p>A full-text search shall match whole words. For example, a full-text search on comments that contains \u201cperform search\u201d or \u201ctext search\u201d or \u201ctext\u201d will return a comment that contains \u201cI want to perform text search in AEM\u201d.<\/p>\n<p>To implement the <a title=\"AEM Consulting and Development\" href=\"http:\/\/www.tothenew.com\/wcm\/cq-aem-development-consulting\">same in AEM6<\/a>, I have used <a href=\"https:\/\/docs.adobe.com\/docs\/en\/aem\/6-0\/develop\/search\/querybuilder-api.html\">QueryBuilder<\/a> API which is a service for building Queries for searching the Java Content Repository and are easily extensible.<\/p>\n<p><strong>Demostration with code:<\/strong><\/p>\n<p>Populate in a map all the predicates with the values.<br \/>\nFulltext contains the value of the <em style=\"font-style: italic !important;\">searchKey<\/em> which will be searched in the url and the content of the <em style=\"font-style: italic !important;\">cq:page<\/em>, under the specified <em style=\"font-style: italic !important;\">path<\/em><\/p>\n<p>[java]<\/p>\n<p>String pageTitle, pagePath<br \/>\nMap params = [:]<br \/>\nparams[&quot;path&quot;] = path<br \/>\nparams[&quot;type&quot;] = &quot;cq:Page&quot;<br \/>\nparams[&quot;fulltext&quot;] = searchKey<br \/>\nparams[&quot;orderby&quot;] = &quot;@jcr:score&quot;<\/p>\n<p>[\/java]<\/p>\n<p>now use Query interface to create a query object that will in turn use builder object of Query Builder interface to build the query.<\/p>\n<p>[java]<\/p>\n<p>Query query = builder.createQuery(PredicateGroup.create(params), session)<br \/>\n\/\/for pagination<br \/>\nquery.setStart(startPage) \/\/ same as params[&quot;p.offset&quot;] = startPage.toString()<br \/>\nquery.setHitsPerPage(offset) \/\/ same as params[&quot;p.limit&quot;] = offset.toString()<\/p>\n<p>[\/java]<\/p>\n<p><em style=\"font-style: italic !important;\">searchResult<\/em> will contain the result of the JCR query. A <em style=\"font-style: italic !important;\">hit<\/em> represents a single search result which is adapted to a page so as to fetch the page title and page url for display.<\/p>\n<p>[java]<br \/>\n        SearchResult searchResult = query.result<br \/>\n        Long totalHits = searchResult.getTotalMatches()<br \/>\n        for (Hit hit : searchResult.hits) {<\/p>\n<p>            Page page = hit.resource.adaptTo(Page)<br \/>\n            pageTitle = page.title<br \/>\n            pagePath = page.path<br \/>\n            searchHit = new JSONObject()<br \/>\n            searchHit.put(&quot;totalHits&quot;, totalHits)<br \/>\n            searchHit.put(&quot;path&quot;, pagePath)<\/p>\n<p>            if (!pageTitle) {<br \/>\n                pageTitle = pagePath.substring(pagePath.lastIndexOf(&#8216;\/&#8217;) + 1, pagePath.length())<\/p>\n<p>            }<br \/>\n            searchHit.put(&quot;title&quot;, pageTitle)<\/p>\n<p>            resultArray.put(searchHit)<br \/>\n        }<br \/>\n        resultObject.put(&quot;data&quot;, resultArray)<br \/>\n        return resultObject<br \/>\n[\/java]<\/p>\n<p><span style=\"font-size: large;\">The desired output looks like below:<\/span><br \/>\n<a href=\"\/blog\/wp-ttn-blog\/uploads\/2015\/05\/Screenshot-from-2015-05-13-094316.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignleft wp-image-19555 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2015\/05\/Screenshot-from-2015-05-13-094316.png\" alt=\"Search Result\" width=\"406\" height=\"367\" \/><\/a><br \/>\nThis much should be sufficient to design a working <em>Site Search component<\/em> in AEM that performs\u00a0<em>f<\/em><em>ulltext Search\u00a0<\/em>and displays paginated results. I will introduce advanced <em>fulltext\u00a0<\/em>queries\u00a0in my forthcoming post.<\/p>\n<p>Stay tuned!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The full-text field search allows you to look for a field anywhere in a webpage, be it the title, content, or the url of a webpage. A full-text search shall match whole words. For example, a full-text search on comments that contains \u201cperform search\u201d or \u201ctext search\u201d or \u201ctext\u201d will return a comment that contains [&hellip;]<\/p>\n","protected":false},"author":191,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":359},"categories":[1],"tags":[4847,3783,1657],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/19545"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/191"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=19545"}],"version-history":[{"count":0,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/19545\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=19545"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=19545"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=19545"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}