Search AEM Content index in Elasticsearch

In the last blog post I gave a brief introduction into the integration of Elasticsearch1 into AEM.

This followup will explain how the indexed data can be used in a search application in AEM. Although you can use every Elasticsearch client you want (e.g. the Java REST Client2), an easy way is the usage of one of the two Searches implemented in this package.

Both Search classes (Search.java3 and PageSearch.java4) require an instance of the ElasticSearchService5. Usually you would inject it using the @Reference Annotation6. Furthermore you have to choose, which index to use.

Search search = new Search(myElasticSearchService, "myIndex");

Search

Generic searches on Elasticsearch Documents are implemented in the Search3 class.

Query

The most important part of a request is the query7. Currently basic querying is supported8, the syntax for most queries is similar. Usually the base for a query is a Bool Query9 that supports the following types:

TypeDescription
mustquery must appear in the matching documents
shouldquery is optional
must_notquery must not appear in the matching documents
filterquery must appear in the matching documents but does not contribute to the score, see Filter
// Simple query in field 'foo' for the term 'bar'
search.query().bool().must().term("foo","bar");

// Advanced query that requires two fields to match
Query must = search.query().bool().must();
must.terms("cq:template", "/apps/foo", "/apps/bar");
must.match("foo", "bar");

Filter

Filter10 are a special type of query as they also influence the results but do not change the score. The syntax is similar to a query:

// A search for all results where 'foo'= 'bar' which is filtered so all results
// also have 'ipsum' = 'lorem' or 'ipsum' = 'dolor'
Query must = search.query().bool().must();
must.query().term("foo", "bar");
must.filter().terms("ipsum","lorem", "dolor");

Limit the results

The following example constructs a search, which will include the first 10 results which have at least a score of 2.0.

search.size(10).minScore(2.0);

Another option is from which can be used for paging.

Sorting

If you want to sort11 the results by a field, you can use the sort methods.

Sort sort = search.sort();
// Sort field 'foo' in descending order
sort.byField("foo").order(SortConstant.SortOrderConstant.DESC);
// Sort field 'bar' in ascending order
sort.byField("bar").order(SortConstant.SortOrderConstant.ASC);
// Sort field '_score' by default order
sort.byField("_score");

Highlighting

You can add one or more fields to the highlight12 section. This will allow you, to show excerpts from the results.

Highlight highlight = search.highlight();
// highlight the 'foo' field
highlight.field("foo");

By default, all highlights are wrapped in <em> tags you can replace:

// use <span class="foobar"> instead of <em>
highlight.tags("<span class=\"foobar\">", "</span>");

PageSearch

As most searches require a similar base set, the PageSearch extends a Search with some AEM Page specific methods.

PageSearch pageSearch = new PageSearch(myElasticSearchService, "myIndex");
// Filter templates
pageSearch.templates("/apps/foo/bar/template", "/apps/foo/bar/template2");

// Search only pages with the given basepath
pageSearch.path("/content/foo/bar");

// Search by Page Title
pageSearch.title("My Page");

// Get newest pages first
pageSearch.newestFirst(true);

Footnotes

Related Posts