In today word, as the ecommerce industry scope is increasing,business user/customer are coming up with unique feature to optimize the search result for there customer.
Lets take an example, When customer come on to storefront, he goes to search bar and search for some text, based upon that text he entered the auto suggestion keeps telling the relevant suggestion in drop down if auto suggestion feature is turn on in solr now there are two option customer can do :-
1. He select the text from the auto suggestion.
2. Or He add some random text or product name, description which he is faimilar and click on search.
So on both the case, your search page controller will get called and request mapping method signature will be request to full fill the customer request.
As the search is OOTB functionality, in Hybris OOTB/Commerce OOTB by default the free text word is searched across the entire Solr document and based upon relevancy the result is fetch in the form of solr document object which rather then populated in the response object and passed it to frontend with result.
Now How To Narrow Down the Solr Search Criteria?
When the request comes to SearchPageController which extends AbstractSearchPageController, the request textsearch method will get called DefaultSolrProductSearchFacade java class.
Please note : SAP Commerce/SAP Hybris use the Facade design pattern.
Now the facade will call service class from -> getProductSearchService().searchAgain(decodeState(searchState, null), pageableData)
But the return type of facade layer will be ProductSearchPageData Data Transfer Object.
Facade Layer will call Service Layer(DefaultSolrProductSearchService.java class) -> Service will call the strategy class,
productSearchStrategyFactory.getSearchStrategy().searchAgain(searchQueryData, pageableData);
The strategy class name is DefaultSolrFacetSearchProductSearchStrategy - Now strategy class will call DefautlfacetSearchStrategy.class file.
(above was all techincal to walkthrough the code)
Now there are two approach to solutionize this requirement -
Approch 1. We have the filter queries option, we can create the filter query on selected solr indexer attribute, on which business user want to have search and skip completed document search, becuase free text search have default free text search builder which will internally call factory class which are DisMaxFreeTextQueryBuilder.class, MultiFieldFreeTextQueryBuilder etc.
Now when you solutionize the requirement, with business user, who need to work closely with them and identify the attribute on which attribute they want search to happen,
Now again you have to check with client user,
How the search pattern should happen? is it EXACT Match, Or Wild Card Matchs, Or Phrase Matchs.
This depends on product modelling, SAP Commerce/SAP Hybris provide sufficient product attributes in OOTB, but as per client requirement, we have to create few custom attribute related to product which signifies the client product hireachy.
As when you are solutioning the requirement with client, you need to ask few more question like if end customer search for any text, how the search pattern should be, or you need to break the words and split it then do the search like [0] position word should be getting search in X attribute [1] position word should be getting search in Y attribute and later combine the result and pass it.
Approach 2: We two operator in Solr , which are OR, AND available in FilterQueryOperator, now with this operator there are combination for solr query.
1. ((code_string:textword^70.0) OR (description:textword^70.0) OR (application:textword^70.0) OR (name:textword^70.0))
OR - Operator -> Search the best case if the text word is find out in any attribute then show the result.
2. AND Operator - ((code_string:textword^70.0) AND (description:textword^70.0) AND (application:textword^70.0) AND (name:textword^70.0))
If the value is getting EXACT match for the solr indexer attribute like if you are search for text 'APPLE' then
((code_string:APPLE^70.0) AND (description:APPLE^70.0) AND (application:APPLE^70.0) AND (name:APPLE^70.0))
code_string : APPLE - if apple is exact match for code string the result will be returned.
so lets assume code_string give value 1, same for other -
((1) AND (1) AND (1)) - then result value is 1 document object.
3.OR in Inner Query AND in Outer Query -
Now hear you have to customize the free text query signature - so the query signature get formed in java class FacetSearchQueryBasicPopulator, sample code base -
This is the populater, where the searchQuery get formed.
public void populate(SearchQueryConverterData source, SolrQuery target) {
SearchQuery searchQuery = source.getSearchQuery();
List<String> queries = new ArrayList();
List<String> multiplicativeBoostQueries = new ArrayList();
List<String> additiveBoostQueries = new ArrayList();
this.generateQueryFieldQueries(searchQuery, queries);
this.generateFreeTextQuery(searchQuery, queries);
this.generateRawQueries(searchQuery, queries);
this.generateCoupledFieldQueries(searchQuery, queries);
this.generateBoostQueries(searchQuery, multiplicativeBoostQueries, additiveBoostQueries);
this.populateSolrQuery(target, searchQuery, queries, multiplicativeBoostQueries, additiveBoostQueries);
}
hear - this method you have to override, but if you observe here in the below method, OOTB is calling the free text query builder factory pattern which in turn is calling factory class, where the relevant factory bean get called.
protected void generateFreeTextQuery(SearchQuery searchQuery, List<String> queries) {
if (StringUtils.isNotBlank(searchQuery.getUserQuery())) {
FreeTextQueryBuilder freeTextQueryBuilder = this.getFreeTextQueryBuilderFactory().createQueryBuilder(searchQuery);
String freeTextQuery = freeTextQueryBuilder.buildQuery(searchQuery);
StringBuilder query = new StringBuilder();
query.append("_query_:\"");
query.append(this.escape(freeTextQuery));
query.append('"');
queries.add(query.toString());
}
}
Now we can over ride the OOTB factory and write the custom factory java, extending the OOTB factory class.
Or you over ride this method -
String freeTextQuery = freeTextQueryBuilder.buildQuery(searchQuery);
buildQuery - method and write custom method in ABCFacetSearchQueryBasicPopulator.java class and add the dependency in xml file so custom populator will get called.
you can modify the query and replace the symbol -
((code_string:textword^70.0) OR (description:textword^70.0) OR (application:textword^70.0) OR (name:textword^70.0)) AND ((code_string:textword^70.0) OR (description:textword^70.0) OR (application:textword^70.0) OR (name:textword^70.0))
4. AND in Inner Query OR in Outer Query -
((code_string:textword^70.0) AND (description:textword^70.0) AND (application:textword^70.0) AND (name:textword^70.0)) OR ((code_string:textword^70.0) AND (description:textword^70.0) AND (application:textword^70.0) AND (name:textword^70.0))
No comments:
Post a Comment