Modify Commerce backoffice catalogue search? [12.6]

Vote:
 

Hi!

I Episerver you can search the catalogue. It gives you maximum 4 hits.
Is there anyway to modify this internal search? Both to give you more than 4 hits and to show more data?

Thanks!

/Kristoffer

#204132
May 20, 2019 13:26
Vote:
 

Do you mean this 

It surely gives you more than 4 hits, but it's not trivial to show more data

#204146
May 20, 2019 22:08
Vote:
 

Yes, exactly. Can I modify the result? Our customer has difficulties finding there products and I would like to add the code in the result like "12345 - Puma Yellow Sneakers".
Is that possible?

/Krisotffer

#204159
May 21, 2019 8:36
Vote:
 

I agree that it is a reasonable request. I will add a story to the backlog for the Commerce team and let them handle it 

#204160
May 21, 2019 8:57
Vote:
 

You can try and attempt to replace the search provider and override the Search function.

The SearchResult contains a MetaData dictionary, if it contains the code you can append it to the title of the search results and return that.

Warning: Off-hand and untested, but it should look like something like this:

[SearchProvider]
public class CustomCatalogSearchProvider : EPiServerSearchProviderBase<CatalogContentBase, ContentType>, ISortable
{
    private readonly LocalizationService _localizationService;

    public override string Area => "Commerce/Catalog";

    public int SortOrder => 500;

    public override string Category => _localizationService.GetString("/Commerce/Edit/Provider/SearchProductCatalog/Category");

    protected override string IconCssClass => "epi-resourceIcon epi-resourceIcon-page";

    public CustomCatalogSearchProvider(LocalizationService localizationService, ISiteDefinitionResolver siteDefinitionResolver, IContentTypeRepository<ContentType> contentTypeRepository, EditUrlResolver editUrlResolver, ServiceAccessor<SiteDefinition> currentSiteDefinition, IContentRepository contentRepository, ILanguageBranchRepository languageBranchRepository, SearchHandler searchHandler, ContentSearchHandler contentSearchHandler, SearchIndexConfig searchIndexConfig, UIDescriptorRegistry uiDescriptorRegistry, LanguageResolver languageResolver, UrlResolver urlResolver, TemplateResolver templateResolver) : base(localizationService, siteDefinitionResolver, contentTypeRepository, editUrlResolver, currentSiteDefinition, contentRepository, languageBranchRepository, searchHandler, contentSearchHandler, searchIndexConfig, uiDescriptorRegistry, languageResolver, urlResolver, templateResolver)
    {
        _localizationService = localizationService;
    }

    public override IEnumerable<SearchResult> Search(Query query)
    {
        var resultList = base.Search(query).ToList();
        foreach (var result in resultList)
        {
            result.Title = $"{result.Metadata["Code"]} - {result.Title}";
        }
        return resultList;
    }
}
#204179
May 21, 2019 16:55
Vote:
 

@Erik, almost!

It overrides the search but the metadata does not contain "code", any idea why?

Thanks!

/Kristoffer

#204201
May 22, 2019 14:39
Vote:
 

It should be "code" instead of "Code" - Metadata might be case sensitive 

I raised the request(s) to our UX designer and she is looking into it 

#204202
May 22, 2019 14:53
Vote:
 

Ok. Neither Code or code exists in the metadat. I did an ugly workaround for now but it does the job:

foreach (var result in resultList)
{
    if(result.Metadata["Id"].Contains("__CatalogContent"))
    {
        var catalogContentBase = _contentLoader.Get<CatalogContentBase>(new ContentReference(result.Metadata["Id"]));
        if (catalogContentBase is VariationContent content)
        {
            result.Title = $"{content.Code} - {result.Title}";
        }
    }
}
return resultList;

Works for now, but of course if you can add something by default that would be nicer.

Or maybe I just need to configure something to get the Code in the metadata?

/Kristoffer

#204203
Edited, May 22, 2019 15:14
Vote:
 

I see, you are inheriting from the base CMS class, not the "Commerce" one. That is why Metadata does not contain code.

The commerce search provider is now in Commerce.Shell assembly, so it is not exactly public APIs

#204207
May 22, 2019 15:12
Vote:
 

Ok. Well the code above help our customers alot so they are fine with that for now.

Thanks Quan!

/Kristoffer

#204208
May 22, 2019 15:16
Vote:
 

@Quan so are you saying if we replace EPiServerSearchProviderBase<CatalogContentBase, ContentType> in the code above with ProductSearchProvider it will work directly from the MetaData without any need to use the ContentLoader?

#204211
May 22, 2019 15:33
Vote:
 

@Kristoffer As Quan pointed out this search provider is based on the CMS instead of the commerce which means it is using a different Lucene search index in the background.

See my blog for more details: How to enable cms search for catalogs

Especially read the comments as my colleague Johan Book posted a much better solution to set the title.

#204213
May 22, 2019 15:50
Kristoffer Lindén - May 22, 2019 21:07
Thanks!
The override of CreateSearchResult does not get exceuted though? If I override Search that code will run but not the CreateSearchResult.
Any ideas?

/Kristoffer
Erik Norberg - May 23, 2019 15:19
Afraid not, as far as I know all code paths from Search calls CreateSearchResult before returning as long as it has hits. :(
Vote:
 

Almost. i'd say go with ProtectedProductSearchProvider

#204214
May 22, 2019 15:51
Erik Norberg - May 22, 2019 15:53
By the way, why on earth call it Protected-Product-SearchProvider if it is used for all entries? :)
Quan Mai - May 22, 2019 16:05
it is "protected", so it searches for expired/not yet public products as well. the non protected one skips that
Erik Norberg - May 22, 2019 17:20
Very good to know, but i was wondering why it was called -Product- when it handles all entry types.