I'm working on customizing OOTB AEM 6.0 search component. I need to pass in multiple paths instead of one path to the search object. Has anyone already tried that? Also when I set search properties to include 'hideInNav' it doesn't filter the pages properly. In other words, the result page still includes those which are set as hide in navigation. Please let me know how to get around this issue. Many thanks in advance.
3 Answers
You can add custom indexing configuration in “indexing_config.xml” to limit the scope of search. Reference URL : https://helpx.adobe.com/experience-manager/kb/SearchIndexingConfig.html. Which you have already done.
When you hide the page in navigation then value of hideInNav will be set to true.
In the search.jsp file you can put the condition if the 'hideInNav' = true then don't show the same on search result.
Custom component You can write custom search component to query the repository using SQL2 and wherein you can define multiple path.
You are able to use multifield(documentation) with a some count of pathfield.
And process entered path's using Query Builder API. Here is example with multipath search and how to sue Query Builder Api
Or you are able to process path's using jcr Query interface
We got this working by duplicating the stock search component code, changed the searchIn path to be a List instead of just a String, and updated the dialog to accept multiple paths. We used the Query Builder API example as cited by cylinder.y to verify our queries.
dialog.xml
<searchPaths
jcr:primaryType="cq:Widget"
fieldLabel="Search Path"
name="./searchPaths"
xtype="multifield">
<fieldConfig
jcr:primaryType="nt:unstructured"
xtype="pathfield"/>
</searchPaths>
search.jsp - MultiSearch is our new component that we duped
MultiSearch search = new MultiSearch(slingRequest);
String[] searchPaths = properties.get("searchPaths", new String[]{});
List<String> searchPathsList = Arrays.asList(searchPaths);
search.setSearchIn(searchPathsList);
impl
public SearchResult getResult() throws RepositoryException {
if (this.result == null) {
String queryString = getQuery();
if ((queryString.length() == 0) && (this.customPredicates.size() == 0)) {
return null;
}
Map<String, String> map = new HashMap();
map.put("group.p.or", "true"); //Search "or" condition on groups (paths / properties)
map.put("fulltext", queryString); //query
List<String> searchPaths = getSearchIn();
int searchPathsLen = searchPaths.size();
int searchPropertiesLen = this.searchProperties.size();
boolean typeOverwrite = false;
for (Predicate p : this.customPredicates) {
if ("type".equals(p.getName())) {
typeOverwrite = true;
break;
}
}
if (!typeOverwrite) {
map.put("type", "nt:hierarchyNode");
}
if (queryString.startsWith("related:")) {
for (int i = 0; i < searchPathsLen; i++){
String searchPath = searchPaths.get(i);
map.put("group." + i + "_path", searchPath);
}
String path = queryString.substring("related:".length());
map.put("similar", path + "/" + "jcr:content");
map.put("similar.local", "jcr:content");
} else {
for (int i = 0; i < searchPathsLen; i++){
String searchPath = searchPaths.get(i);
for (int j = 0; j < searchPropertiesLen; j++){
String prop = searchProperties.get(j);
int counter = i * searchPropertiesLen + j;
map.put("group." + counter + "_path", searchPath);
StringBuffer path = new StringBuffer();
path.append("jcr:content");
if (!prop.equals(".")) {
String[] segments = Text.explode(prop, 47);
for (int k = 0; k < segments.length; k++) {
path.append("/");
if (k == segments.length - 1) {
path.append("@");
}
path.append(segments[k]);
}
}
map.put("group." + counter + "_fulltext.relPath", path.toString());
}
}
}
Query query = this.builder.createQuery(PredicateGroup.create(map), getSession());
for (Predicate p : this.customPredicates) {
query.getPredicates().add(p);
}
query.setExcerpt(true);
query.setStart(this.start);
query.setHitsPerPage(this.hitsPerPage);
this.result = query.getResult();
}
return this.result;
}