Wildcard Case Insensitive Search using AEM Query Builder API

Touseef Khan
2 min readSep 2, 2024

I have been struggling with a wildcard case insensitive search in query builder API so I thought of sharing its solution as searching for content in Adobe Experience Manager (AEM) can sometimes be challenging, especially when you need to perform case-insensitive searches with wildcard support. In this blog post, we’ll explore how to achieve this using the AEM Query Builder API with a custom predicate evaluator.

Introduction

Imagine you have a node structure in AEM like /content/mydata/stores, where each store node contains properties such as storeName. You want to search for stores by their names in a case-insensitive manner, allowing for partial matches. This is where a custom predicate evaluator comes in handy.

The Challenge

The default Query Builder API in AEM does not support case-insensitive searches with wildcards out of the box. To overcome this limitation, we need to create a custom predicate evaluator that extends the functionality of the Query Builder API.

Solution: Custom Predicate Evaluator

We’ll create a custom predicate evaluator named CaseInsensitiveLike that allows us to perform case-insensitive searches using the jcr:like function with the fn:lower-case function in XPath.

Step-by-Step Implementation

  1. Create the Custom Predicate Evaluator: First, we need to create a Java class that extends AbstractPredicateEvaluator and overrides the getXPathExpression method. This class will be annotated with @Component to register it as an OSGi component.
@Component(factory = "com.day.cq.search.eval.PredicateEvaluator/likeIgnoreCase")
public class CaseInsensitiveLike extends AbstractPredicateEvaluator {
private static final Logger log = LoggerFactory.getLogger(CaseInsensitiveLike.class);
static final String PREDICATE_PROPERTY = "property";

@Override
public String getXPathExpression(Predicate predicate, EvaluationContext context) {
String property = predicate.get(PREDICATE_PROPERTY);
String value = predicate.get("value").toLowerCase();
return "jcr:like(fn:lower-case(@" + property + "), '" + value + "')";
}
}

2. Register the Custom Predicate Evaluator: Ensure that the custom predicate evaluator is registered correctly in the OSGi container. This is done using the @Component annotation with the appropriate factory name.

3. Use the Custom Predicate in Your Search Query: Now that we have our custom predicate evaluator, we can use it in our search queries. Here’s an example of how to use it in a query map:

Map<String, String> queryMap = new HashMap<>();
queryMap.put("path", "content/mydata/stores");
queryMap.put("type", "nt:unstructured");
queryMap.put("likeIgnoreCase.property", "storeName");
queryMap.put("likeIgnoreCase.value", "%" + storeName.trim() + "%");

In this example, storeName is the search term provided by the user. The likeIgnoreCase.property and likeIgnoreCase.value parameters are used to specify the property to search and the value to match, respectively.

Conclusion

By creating a custom predicate evaluator, we can extend the AEM Query Builder API to support case-insensitive searches with wildcards. This approach provides a flexible and powerful way to search for content in AEM, making it easier to find the information you need. Feel free to customize the code and adapt it to your specific use case.

Sign up to discover human stories that deepen your understanding of the world.

Touseef Khan
Touseef Khan

Written by Touseef Khan

Experienced full-stack developer proficient in Java, AEM, & .NET. Let's connect: https://www.linkedin.com/in/touseef-khan-19214930/

Responses (1)

Write a response

Hi, How to do it for jcr:content/jcr;title property?