Enhancing AEM Lucene Search: Advanced Techniques for Improved Search Functionality- Part 1

Kiran Mayee N
Activate AEM
Published in
4 min readJun 26, 2024

Hey there, AEM users!

Ever get frustrated when you can’t find what you’re looking for on your AEM site? You type in a search term, but nothing quite hits the mark. That’s where we come in — to supercharge your AEM search experience!

This series of blog posts is all about taking your AEM search to the next level. We’ll be exploring some cool features that will make finding content a breeze. Think real-time search suggestions as you type, lightning-fast results, and even highlighting keywords to pinpoint what you need in a flash.

First up: Search Suggestion Servlets!

Imagine this: you’re typing a search query, and suggestions pop up instantly, guiding you towards the content you crave. That’s the magic of search suggestion servlets! They not only boost user engagement but also make finding information on your AEM site a walk in the park.

But wait, there’s more!

This series is just getting started. In the coming weeks, we’ll be diving into:

So, stay tuned for some seriously awesome AEM search optimization tips!

Behind the Magic: Search Suggestion Servlets

Imagine typing a query into a search bar and getting helpful suggestions popping up as you type. That’s autocomplete in action — assisting users by predicting search terms, streamlining the search process, and improving efficiency. In the past, implementing autocomplete in AEM was a daunting task, requiring the indexing of every possible word combination, which was both cumbersome and resource-intensive. However, with the advent of AEM 6.1 and the Lucene Suggest module, a more optimized approach has emerged.

The Lucene Suggest module revolutionizes autocomplete by introducing a specialized data structure. This structure enables the engine to provide autocomplete and search suggestions without the need to index every conceivable word combination. Instead, Lucene efficiently loads completion values from indexed data using an analyzer called AnalyzingInfixSuggester. It then constructs an optimized in-memory structure for rapid query lookup, significantly enhancing performance and resource utilization.

Implementation Steps:

To implement autocomplete and search suggestions in AEM using Lucene, follow these steps:

  1. Define a Lucene index:
  • Create a custom Lucene index and specify the properties to be utilized for suggesting queries to users. For example, you can define an index named “testindex” and designate the “title” property for suggestion queries.
  • Referring to AEM Cloud Service Indexing Docs can aid in adding, updating, or removing index definitions.

2. Configure suggestion update frequency:

  • Define the frequency at which indexed suggestions are updated by setting the property “suggestUpdateFrequencyMinutes.” This ensures that suggestions remain relevant and up-to-date, mitigating performance issues arising from frequent property updates.

3. Enable compatVersion:

  • Set the compatVersion of the index definition node to 2 to ensure compatibility with Lucene index usage for search suggestions.

4. Execute suggestion queries:

  • Utilize Lucene queries to retrieve suggestions based on user input. Path restrictions can be employed to filter search data and enhance query efficiency.

Query Examples:

Below are examples of Lucene queries for retrieving search suggestions:

  • Using index name:
SELECT [rep:suggest()] FROM [nt:unstructured] WHERE SUGGEST('aer') OPTION(INDEX NAME [testindex])
  • Applying path restriction:
SELECT [rep:suggest()] FROM [nt:unstructured] WHERE SUGGEST('aer') AND ISDESCENDANTNODE('/content/sampledata')

Sample Lucene Suggestion Index:

Referencing the provided index structure, ensure that properties relevant to suggestion queries are appropriately configured for analysis and inclusion in suggestions.

<jcr:root xmlns:oak="http://jackrabbit.apache.org/oak/ns/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
xmlns:nt="http://www.jcp.org/jcr/nt/1.0" xmlns:rep="internal"
jcr:primaryType="oak:QueryIndexDefinition"
async="async"
codec="Lucene46"
compatVersion="{Long}2"
includePaths="[/content/kiran-sample/content/articles,/content/kiran-sample/blogs]"
indexPath="/oak:index/luceneSuggestion"
type="lucene">
<indexRules jcr:primaryType="nt:unstructured">
<nt:base
jcr:primaryType="nt:unstructured">
<properties jcr:primaryType="nt:unstructured">
<title
jcr:primaryType="nt:unstructured"
analyzed="{Boolean}true"
name="title"
ordered="{Boolean}false"
propertyIndex="{Boolean}true"
type="String"
useInSuggest="{Boolean}true" />
<summaryText
jcr:primaryType="nt:unstructured"
analyzed="{Boolean}true"
name="summaryText"
ordered="{Boolean}false"
propertyIndex="{Boolean}true"
type="String"
useInSuggest="{Boolean}true" />
</properties>
</nt:base>
</indexRules>
<suggestion
jcr:primaryType="nt:unstructured"
suggestUpdateFrequencyMinutes="{Long}30"
suggestAnalyzed="{Boolean}true" />
<tika jcr:primaryType="nt:unstructured">
<config.xml />
</tika>
</jcr:root>

Search Suggestion Servlet:

The SearchSuggestionServlet facilitates the retrieval of search suggestions based on user input. It interacts with the Lucene index and utilizes the SearchSuggestion interface for suggestion retrieval.

import com.day.cq.search.suggest.Suggester;

// ... other imports

private Suggester suggester;

// ... other class members

public List<String> retrieveSuggestions(String searchTerm, int maxSuggestions, ResourceResolver resolver) {
// ... rest of the logic

// Fetch suggestions using the provided suggester
for (final String suggestion : suggester.getSuggestions(session, “oak-nt:base”, searchTerm, enableSpellCheck)) {
counter++;
suggestionsList.add(suggestion);
if (counter == maxSuggestions) {
break;
}
}
// ... rest of the logic
return suggestionsList;
}

Hitting this Servlet like below as the user keeps typing should provide the Suggestions based on the Properties analyzed as per the Index we defined earlier.

Happy searching! And stay tuned for the next article on “Optimizing Search with AEM Indexing Management”.

--

--