I am searching in Hybris using Solr. There are certain facet values for category that I want to exclude from that specific(those categories need to be visible to other searches) search. My Solr query is as following:
q=*:*&spellcheck=true&spellcheck.dictionary=en&spellcheck.collate=true&spellcheck.q=&fq={!tag=fk6}(type\-facet_string:ANSI)&fq=(((catalogId:"ProductCatalog") AND (catalogVersion:Online)))&start=0&rows=100&facet=true&facet.field=allCategories_string_mv&facet.field={!ex=fk0}productLine_string_mv&facet.field={!ex=fk8}style-facet_string&facet.field={!ex=fk5}price_usd_string&facet.field={!ex=fk4}allPromotions_string_mv&facet.field={!ex=fk6}type-facet_string&facet.field={!ex=fk1}size-facet_string&facet.field=categoryPath_string_mv&facet.field={!ex=fk9}availableInStores_string_mv&facet.field=category_string_mv&sort=name_sortable_en_sortabletext asc,score desc&facet.mincount=1&facet.limit=-1&facet.sort=count
I don't have the ability to use raw query. All I can use is Hybris native SearchStateData and SearchQueryData. Category facet can be included in the search but I need to exclude from it i.e CategoryA and CategoryB. Right now my code just sets the value in SearchQueryData as a String in a following way:
":type-facet:" + type; or ":category:" + category
I have tried :category:(-\"CategoryA\"); but it does not end up in the final Solr query. Can anyone point me in the right direction?
In the backoffice of hybris you can install the Commerce Search Perspective with the extension backofficesolrsearch.
In this perspecetive you can enable or disable facets for searching in frontend. Is this what you are looking for?
Here is the belongig hybris wiki page to it.
Refer SearchResponseFacetsPopulator and you can override its method by creating custom populator
MySearchResponseFacetsPopulator :
public class MySearchResponseFacetsPopulator<FACET_SEARCH_CONFIG_TYPE, INDEXED_TYPE_TYPE, INDEXED_PROPERTY_TYPE, INDEXED_TYPE_SORT_TYPE, ITEM>
extends
SearchResponseFacetsPopulator<FACET_SEARCH_CONFIG_TYPE, INDEXED_TYPE_TYPE, INDEXED_PROPERTY_TYPE, INDEXED_TYPE_SORT_TYPE, ITEM>
{
#Override
public void populate(
final SolrSearchResponse<FACET_SEARCH_CONFIG_TYPE, INDEXED_TYPE_TYPE, INDEXED_PROPERTY_TYPE, SearchQuery, INDEXED_TYPE_SORT_TYPE, SearchResult> source,
final FacetSearchPageData<SolrSearchQueryData, ITEM> target)
{
super.populate(source, target);
}
#Override
protected List<FacetData<SolrSearchQueryData>> buildFacets(final SearchResult solrSearchResult,
final SolrSearchQueryData searchQueryData, final IndexedType indexedType)
{
// Do your stuff here
}
}
xml :
<alias name="defaultMyCommerceSearchResponseFacetsPopulator" alias="commerceSearchResponseFacetsPopulator" />
<bean id="defaultMyCommerceSearchResponseFacetsPopulator" class="com.my.facades.populators.MySearchResponseFacetsPopulator"
parent="defaultCommerceSearchResponseFacetsPopulator" />
Related
We have a requirement wherein we need to make boosting for a field dynamic. Let's say that we have an indexed property foo, we need to perform a mathematical calculation on foo to determine its boost value which would be different for every product.
Is this doable in Hybris Solr?
Note: I'm using SAP CX 2105 and Solr 8.9.0 with Dismax Query Parse.
And above requirement can be done in standalone Solr application as following.
#Resource
private SolrQuery solrQuery;
private void addBoosts()
{
solrQuery.add("boost", "sub(20, sqrt(field(foo)))");
}
In Hybris, I have tried following
#Resource
private SearchQuery searchQuery;
private void addBoosts()
{
searchQuery.addQuery("boost", "sub(20, sqrt(field(foo)))");
}
And also this
#Resource
private SearchQuery searchQuery;
private void addBoosts()
{
searchQuery.addQuery("boost", "sub(20, sqrt(field(foo)))");
}
Both don't affect search order of the result.
I have is this:
public class Product {
#Field("object_id")
private String objectId;
private List<MyObject> listOfMyObjects;
}
I use SolrJ to save the info. How can I make listOfMyObjects look like list of nested documents in Solr response. I can make the field multivalued, but I need the list to be list of documents.
I can see that this question is asked few times(e.g. Solrj Block Join Bean support ) but no answer. Solr supports nested documents, but how to make it happen using SolrJ with annotations and schema.xml.
I am using VS2012, .NET 4.5 and SolrNet. I am struggling with solrnet mappings. I've succesfully started Apache Solr with jetty on http://localhost:8983/solr. My class which I want to add to solr is:
public class Register
{
[SolrUniqueKey("id")]
public string Id { get; set; }
[SolrField("body")]
public string Body { get; set; }
}
I succesfully connect to solr, but I can't put my document into it:
Startup.Init<Register>(solrAddress);
Solr = ServiceLocator.Current.GetInstance<ISolrOperations<Register>>();
var reg = new Register
{
Id = "SP2514N",
Body = #"Dosel je prosel"
};
Solr.Add(reg);
Solr.Commit();
Here I receive error, that 'body' is unknown field. I've also used MappingManager, like this:
var mgr = new MappingManager();
var property = typeof(Register).GetProperty("Id");
mgr.Add(property, "id");
mgr.SetUniqueKey(property);
mgr.Add(typeof(Register).GetProperty("Body"), "body");
But, again, my field was not mapped. What am I doing wrong? Isn't the mapping to solr supposed to be done through code? Do I need a special xml file?
You need to confirm that you have a body field defined in your schema. If you are just using the default schema that comes with Solr, it does not include a body field. You can copy an existing similar entry in the schema.xml file, like description to get you going.
For more reference on configuring the Solr schema please refer to the following:
Solr Reference Guide - Overview of Documents, Fields and Schema Design
schema.xml - SolrTutorial.com
The Solr documentation for creating your own token and character filters says the following.
http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters#Specifying_an_Analyzer_in_the_schema
If you want to use custom CharFilters, Tokenizers or TokenFilters, you'll need to write a very simple factory that subclasses BaseTokenizerFactory or BaseTokenFilterFactory, something like this...
public class MyCustomFilterFactory extends BaseTokenFilterFactory {
public TokenStream create(TokenStream input) {
return new MyCustomFilter(input);
}
}
I cannot find the BaseTokenFilterFactory anywhere in the source code for Solr 4.
Here is the org.apache.solr.analysis package from Solr 3.6.1
http://svn.apache.org/viewvc/lucene/dev/tags/lucene_solr_3_6_1/solr/core/src/java/org/apache/solr/analysis/
And here is the same package for Solr 4.0.0
http://svn.apache.org/viewvc/lucene/dev/tags/lucene_solr_4_0_0/solr/core/src/java/org/apache/solr/analysis/
The documentation looks like it will work for Solr 3.6, but I need to know how to create custom filters using 4.0.
With solr 4.0 the BaseTokenFilterFactory is now org.apache.lucene.analysis.util.TokenFilterFactory, so you can check on this.
I am using Solrs TermsComponent to implement an autocomplete feature. My documents contain tags which I have indexed in a "tags" field. Now I can use TermsComponent to find out which tags are used in all the stored documents. This works pretty well so far.
However there is some additional requirement: Every document has an owner field which contains the ID of the user who owns it. The autocomplete list should only contain tags from documents, that the user who is requesting the autocomplete is actually owning.
I have tried to set the query parameter, however this seems to be ignored by the TermsComponent:
public static List<String> findUniqueTags(String beginningWith, User owner) throws IOException {
SolrParams q = new SolrQuery().setQueryType("/terms")
.setQuery("owner:" + owner.id.toString())
.set(TermsParams.TERMS, true).set(TermsParams.TERMS_FIELD, "tags")
.set(TermsParams.TERMS_LOWER, beginningWith)
.set(TermsParams.TERMS_LOWER_INCLUSIVE, false)
.set(TermsParams.TERMS_PREFIX_STR, beginningWith);
QueryResponse queryResponse;
try {
queryResponse = getSolrServer().query(q);
} catch (SolrServerException e) {
Logger.error(e, "Error when querying server.");
throw new IOException(e);
}
NamedList tags = (NamedList) ((NamedList)queryResponse.getResponse().get("terms")).get("tags");
List<String> result = new ArrayList<String>();
for (Iterator iterator = tags.iterator(); iterator.hasNext();) {
Map.Entry tag = (Map.Entry) iterator.next();
result.add(tag.getKey().toString());
}
return result;
}
So is there a way of limiting the tags returned by TermsComponent, or do I manually have to query all the tags of the user and filter them myself?
According to this and that post on the Solr mailing list, filtering on the terms component is not possible because it operates on raw index data.
Apparently, the Solr developers are working on a real autosuggest component that supports your filtering.
Depending on your requirements you might be able to use the faceting component for autocomplete instead of the terms component. It fully supports filter queries for reducing the set of eligible tags to a subset of the documents in the index.