on 06-24-2014 12:22 PM
We try to figure out how to implement/configure the Solr fulltext search to fit the following requirement: If the the customer puts in the search term e.g. "pants red" the search should only find all the products where each term has been found in any of the fields but not the products where only one of the terms match a field (current implementation).
On Solr query level we do want to have a query like this:
(
field1_text_en:pants
OR
field2_en_string_mv:pants
OR
field3_text_en_mv:pants
)
AND
(
field1_text_en:red
OR
field2_en_string_mv:red
OR
field3_text_en_mv:red
)
rather then the current solution:
(
(field1_text_en:pants OR red)
OR
(field2_en_string_mv:pants OR red)
OR
(field3_text_en_mv:pants OR red)
)
As far as we can see de.hybris.platform.solrfacetsearch.search.SearchQuery
is not allowing this via its API since it only holds a List
of de.hybris.platform.solrfacetsearch.search.QueryField
s which will be reused on multiple calls of searchInField
and will be then translated to the Solr query above.
Since the current solution depends that much on de.hybris.platform.solrfacetsearch.search.SearchQuery
we don't see a solution how to implement/configure this requirement with existing framework.
Cheers,
Tino
It is not really a solution, but I think it is the only solution for your case. You should override the method 'convertSolrQuery' in the 'DefaultSolrQueryConverter'. There you can change the query of the SolrQuery.
It is something we did also, because we need always to filter on B2BUnit and that was the best solution. (Also with a different AND/OR notation). I have added an example without the B2BUnit logic:
public class CustomSolrQueryConverter extends DefaultSolrQueryConverter
{
private UserService userService;
@Override
public SolrQuery convertSolrQuery(final SearchQuery searchQuery) throws FacetSearchException
{
final SolrQuery res = super.convertSolrQuery(searchQuery);
final UserModel user = userService.getCurrentUser();
if (user instanceof B2BCustomerModel)
{
//Custom filter logic based on B2BUnit (Logic Removed)
final String B2BUnitQueryString = "";
final String query = res.getQuery();
final StringBuilder queryWithFilter = new StringBuilder();
if (StringUtils.isNotBlank(query))
{
queryWithFilter.append("(").append(query).append(") AND ").append(B2BUnitQueryString);
}
else
{
queryWithFilter.append(B2BUnitQueryString);
}
res.setQuery(queryWithFilter.toString());
}
return res;
}
/**
* @param userService
* the userService to set
*/
public void setUserService(final UserService userService)
{
this.userService = userService;
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Danny!
Your problem could be solved by introducing a SolrQueryPostProcessor.
For instance to show only products that are on stock:
public class InStockSolrQueryPostProcessor implements SolrQueryPostProcessor
{
@Override
public SolrQuery process(final SolrQuery solrQuery, final SearchQuery searchQuery)
{
solrQuery.addFilterQuery("inStockFlag_boolean:true");
return solrQuery;
}
}
Hi Tino, Did you get any solution for this issue. I am also facing the same issue.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Oh this is simple. Your customer's requirements are wrong. They will realise this when they come to test it for themselves on their live site.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Tino,
you can extend DefaultFreeTextQueryBuilder class and replace the OR operator with AND for example .
searchQuery.searchInField(field, ClientUtils.escapeQueryChars(value) + suffixOp + boost, SearchQuery.**Operator.AND**);
you get the following Query.
(field1_text_en:pants AND red) OR (field2_en_string_mv:pants AND red) OR (field3_text_en_mv:pants AND red) )
And i think its fulfill your requirement.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
It does definitely not fulfill our requirements. If you think of just 2 indexed fields "color" and "name" and the customer searches for "red pants" then we only want to find documents having "red" as a color and "pants" in the name attribute. Your solution would only find documents having both terms in one of the fields. In my example it would find zero documents.
Please see:
https://experts.hybris.com/questions/4089/making-use-of-the-extendeddismax-for-solr-searches.html
I think you could make use of the edismax that supports lucene like queries out of the box. The only problem is, that hybris does not support this right out of the box.
We are currently working on introducing this in our project and I was asking if there are already experiences with it.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Stefan! Thanks for your reply.
As far as I can see hybris already uses edismax since this is set in the request to the Solr server via defType=edismax
.
As already mentioned in my initial question we think that the API of de.hybris.platform.solrfacetsearch.search.SearchQuery
just doesn't allow to create the query we want...
User | Count |
---|---|
5 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.