Omnisearch in AEM 6.2 - Search All the Things

Preview:

Citation preview

#evolverocks

SEARCH ALL THE THINGS:OMNISEARCH IN AEM 6.2JUSTIN EDELSON & OSCAR BOLAÑOS

August 31st, 2016

#evolverocks

#evolverocks 3

ABOUT US

Twittertwitter.com/justinedelson

Linkledinlinkedin.com/in/justinedelson

Justin EdelsonTeam Lead

Linkledinlinkedin.com/in/orbolanos

Oscar BolañosProject Lead

#evolverocks4

What is Omnisearch and How do I use it?ExtensibilityWriting a new OmniSearchHandlerUI Implementation

AGENDA

#evolverocks5

Unified Author-Side Content SearchingConsistent User ExperienceConsistent AccessConsole/Tool Access

WHAT IS OMNISEARCH?

#evolverocks6

1.OpenSlash KeySearch Icon2.Start Typing

HOW TO USE OMNISEARCH?

#evolverocks7

CROSS-CONTENT TYPE SEARCHES

#evolverocks8

LOCATIONS

#evolverocks9

#evolverocks10

PREDICATES

#evolverocks11

GO TO…

12#evolverocks

CONSOLE FILTERS

#evolverocks

DEMO

13

14#evolverocks

LET’S SEE SOME CODE

#evolverocks15

Locations Map 1:1 to implementations of OmniSearchHandler

ADDING A LOCATION

#evolverocks16

getID()Return unique identifier for the search handler

getModuleConfig()Return a Resource with the configuration of the handler

CONFIGURATION METHODS

#evolverocks17

@Component@Servicepublic final class ContentFragmentOmniSearchHandler

implements OmniSearchHandler {

@Overridepublic Resource getModuleConfig(ResourceResolver resourceResolver) { return resourceResolver.getResource("/apps/aem-omnisearch-content-fragments/content/metadata");}

@Overridepublic String getID() { return "custom-cfm";

}}

START OF IMPLEMENTATION

#evolverocks18

getResults()Return the actual search results

getSuggestions()Return a Query to get the list of suggestions

getSpellCheck()Return a Query to get the list of spell check suggestions

getPredicateSuggestions()Get a list of predicate suggestions based on a search term

SEARCH METHODS

19#evolverocks

Requires configuration of Lucene indexese.g. /oak:index/damAssetLucene

Properties can have these two flags:useInSuggestuseInSpellcheck

Suggestion list is updated every 10 minutes by default, but configurable.

Path restriction support is limitedProperty restriction support is non-existing

OAK SUGGESTIONS & SPELL CHECKA BRIEF DIGRESSION

#evolverocks20

@Overridepublic SearchResult getResults(ResourceResolver resourceResolver,

Map<String, Object> predicateParameters, long limit, long offset) { Map<String, String> predicates = new HashMap<String, String>(); predicates.put("path", DamConstants.MOUNTPOINT_ASSETS); predicates.put("type", DamConstants.NT_DAM_ASSET); predicates.put("property", "jcr:content/contentFragment"); predicates.put("property.value", "true");

if (predicateParameters.containsKey("fulltext")) { String[] ft = (String[]) predicateParameters.get("fulltext"); predicates.put("fulltext", ft[0]); }

PredicateGroup predicatesGroup = PredicateGroup.create(predicates); com.day.cq.search.Query query = queryBuilder.createQuery(predicatesGroup,

resourceResolver.adaptTo(Session.class)); if (limit != 0) { query.setHitsPerPage(limit); } if(offset != 0) { query.setStart(offset); } SearchResult queryResult = query.getResult(); return queryResult;}

SEARCH METHODTHE NAÏVE VERSION

21#evolverocks

boolean addedPath = false;boolean addedType = false;for (Map.Entry<String, Object> param : predicateParameters.entrySet()) { if (param.getValue() instanceof String[]) { String[] values = (String[]) param.getValue(); if (values.length == 1) { if ((param.getKey().equals("path") || param.getKey().endsWith("_path")) && values[0].length() > 0) { addedPath = true; } if (param.getKey().equals("type") || param.getKey().endsWith("_type")) { addedType = true; } predicates.put(param.getKey(), values[0]); } }}if (!addedPath) { predicates.put("path", DamConstants.MOUNTPOINT_ASSETS);}if (!addedType) { predicates.put("type", DamConstants.NT_DAM_ASSET);}predicates.put("999_property", "jcr:content/contentFragment");predicates.put("999_property.value", "true");

SEARCH METHODTHE REAL VERSION

22#evolverocks

public Query getSuggestionQuery(ResourceResolver resourceResolver, String term) { String queryStr = "SELECT [rep:suggest()] FROM [dam:Asset] as s " + " WHERE SUGGEST($term) AND ISDESCENDANTNODE([/content/dam])"; try { Query query = createQuery(resourceResolver, term, queryStr); return query; } catch (RepositoryException e) { log.error("Unable to create suggestions query", e); return null; }}

SUGGESTIONS METHOD

23#evolverocks

@Overridepublic List<PredicateSuggestion> getPredicateSuggestions( ResourceResolver resourceResolver, I18n i18n, String term) { List<PredicateSuggestion> matchedPredicates = new ArrayList<PredicateSuggestion>(); List<PredicateSuggestion> allPredicateSuggestions = getAllPredicateSuggestions(resourceResolver); for (PredicateSuggestion suggestion : allPredicateSuggestions) { if (suggestion.getOptionTitle().toLowerCase(). contains(term.toLowerCase())) { matchedPredicates.add(suggestion); } } return matchedPredicates;}

PREDICATE SUGGESTIONS

#evolverocks24

• Control the UI of the search module• Each handler needs to have one• Default ones are at /libs/granite/omnisearch/content/metadata

MODULE CONFIGURATION NODES

#evolverocks25

jcr:titleThe display title of the search location

listOrderThe order of the location

cardPathThe resource type used to render results in the card view

listItemPathThe resource type used to render results in the list view

clientlibsAny custom clientlib that needs to be loaded when the location is shown. This is typically used to handle custom actions when an item is selected.

MODULE CONFIG NODE PROPERTIES

#evolverocks26

actions/selectionActions that are loaded once an item from that location is selected. Different actions could be enabled during the Omnisearch here, as opposed to the console.

views/listView configuration that is used while in list view. This is specially important for the List View because allows to configure the columns that are shown.

MODULE CONFIG NODE CHILD NODES

#evolverocks27

<coral-card data-sly-use.data="data.js" class="foundation-collection-navigator" data-foundation-collection-navigator-href="${data.navigationHref}" itemscope="itemscope" itemtype="http://schema.org/WebPage" colorhint="#ffffff"> <coral-card-asset> <img src="${data.thumbnailUrl}"> </coral-card-asset> <coral-card-content> <coral-card-context>FRAGMENT</coral-card-context> <coral-card-title class="foundation-collection-item-title" value="${data.title}">${data.title}</coral-card-title> </coral-card-content> <coral-card-propertylist></coral-card-propertylist> <!-- see next slides --> <link rel="properties" href="${data.navigationHref}"> <meta class="foundation-collection-quickactions" data-foundation-collection-quickactions-rel=""> <coral-quickactions></coral-quickactions> <!-- see next slides --></coral-card>

CARD COMPONENT

#evolverocks28

<coral-card-propertylist data-sly-test=${data.lastModified}> <coral-card-property icon="edit"> <time datetime="${data.lastModified}"> ${data.formattedRelativeTime} </time> </coral-card-property></coral-card-propertylist>

CARD COMPONENT CONTINUED

#evolverocks29

<coral-quickactions target="_prev" alignmy="left top" alignat="left top"> <coral-quickactions-item icon="check” class="foundation-collection-item-activator"> Select </coral-quickactions-item> <coral-quickactions-item icon="edit” class="foundation-anchor” data-foundation-anchor-href="${data.navigationHref}"> Edit </coral-quickactions-item> <coral-quickactions-item icon="infoCircle" class="foundation-anchor” data-foundation-anchor-href="${data.propertiesHref}” data-contextpath = "/assetdetails.html"> View Properties </coral-quickactions-item></coral-quickactions>

CARD COMPONENT CONTINUED

30#evolverocks

<tr data-sly-use.data="data.js" data-item-title="${data.title}" data-foundation-collection-navigator-href="${data.navigationHref}” data-foundation-collection-item-id="${data.path}" class="foundation-collection-item foundation-collection-navigator" is="coral-tr"> <td is="coral-td" coral-tr-select> <img class="foundation-collection-item-thumbnail" src="${data.thumbnailUrl}" alt="${data.title}"> </td> <td class="foundation-collection-item-title" is="coral-td">${data.title}</td> <td is="coral-td"> <time datetime="${data.lastModified}"> <coral-icon icon="edit" size="xs"></coral-icon> ${data.formattedRelativeTime}</time> </td> <td is="coral-td">${data.description} <meta class="foundation-collection-quickactions" data-foundation-collection-quickactions-rel=""> </td></tr>

ROW ITEM COMPONENT

#evolverocks

DEMO

31

32#evolverocks

https://github.com/justinedelson/aem-omnisearch-cfm

CODE

#evolverocks33

• Wizard support• i.e. “Create” -> “Create Page” (suggestion) -> Create Page Wizard

• Tags as Global Predicate• Recent Search Support• Improved Save Search Support

FUTURE CONCEPTS

#evolverocks

THANK YOU!

Recommended