Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • David Armitage 503 posts 2071 karma points
    Nov 29, 2020 @ 23:01
    David Armitage
    0

    Umbraco 8 Examine Search Filter Facets

    Hi Guys,

    Does anyone know how to achieve search filter facets with Examine in Umbraco 8.

    You know the ability to have filter categories with search total alongside each category like you see on e-commerce category filtering.

    That or does anyone know of any packages available. I know there used to be one for Umbraco 7 but I have failed to find anything for Umbraco 8.

    This is the one I found for Umbraco 7. https://our.umbraco.com/packages/developer-tools/umbraco-bobo-facets/

    Thanks in advance

    David

  • Joep 96 posts 698 karma points
    Nov 30, 2020 @ 14:24
    Joep
    101

    Hey,

    I think this package will help you: https://github.com/callumbwhyte/examine-facets

    -Joep

  • David Armitage 503 posts 2071 karma points
    Nov 30, 2020 @ 21:59
    David Armitage
    0

    Hi Joep,

    Yes this is exactly how I got it working. I was planning on updating the post with some bullet points.

    I just haven't had the change yet. I will add the steps involved here.

    It was pretty easy actually.

  • David Armitage 503 posts 2071 karma points
    Nov 30, 2020 @ 23:37
    David Armitage
    0

    Hi All,

    For anyone wanting to do this here are the steps....

    1. Install nuget package Install-Package Examine.Facets. Install this to both your core and web project if this is the setup you have.

    2. Install nuget package Install-Package Examine.Facets.BoboBrowse. Install this to both your core and web project if this is the setup you have.

    3. Create a component / composer for register a new examine searcher. Here is my code.

    using Examine;
    using System;
    using Umbraco.Core.Composing;
    using Umbraco.Core;
    using Examine.Providers;
    using Umbraco.Core.Logging;
    using Umbraco.Web;
    using Examine.LuceneEngine.Providers;
    using Examine.Facets.BoboBrowse;
    
    [RuntimeLevel(MinLevel = RuntimeLevel.Run)]
        public class ExamineComposerPublic : IUserComposer
        {
            public void Compose(Composition composition)
            {
                composition.Components().Append<ExamineComponents>();
            }
        }
    

    public class ExamineComponents : IComponent { private readonly IUmbracoContextFactory _umbracoContextFactory; private readonly IExamineManager _examineManager; private readonly ILogger _logger;

        public ExamineComponents(IUmbracoContextFactory umbracoContextFactory, IExamineManager examineManager, ILogger logger)
        {
            _umbracoContextFactory = umbracoContextFactory;
            _examineManager = examineManager ?? throw new ArgumentNullException(nameof(examineManager));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        }
    
        public void Initialize()
        {
            if (!_examineManager.TryGetIndex(Constants.UmbracoIndexes.ExternalIndexName, out IIndex index))
                throw new InvalidOperationException($"No index found by name {Constants.UmbracoIndexes.ExternalIndexName}");
    
            if (!(index is BaseIndexProvider indexProvider))
                throw new InvalidOperationException("Could not cast");
    
            if (index is LuceneIndex luceneIndex)
            {
                var searcher = new BoboFacetSearcher(
                    "FacetSearcher",
                    luceneIndex.GetIndexWriter(),
                    luceneIndex.DefaultAnalyzer,
                    luceneIndex.FieldValueTypeCollection
                );
    
                _examineManager.AddSearcher(searcher);
            }
        }
    
        public void Terminate() { }
    }
    
    1. Add the search code. Here is an example of my code.

          if (!_examineManager.TryGetSearcher("FacetSearcher", out ISearcher facetSearcher))
              throw new InvalidOperationException($"No searcher by name FacetSearcher");
      
      
      
      var facetCriteria = facetSearcher.CreateQuery(IndexTypes.Content, BooleanOperation.And);
      var facetQuery = facetCriteria.NodeTypeAlias("whatDocTypeAliasYouWantCheckFacetsFor");
      facetQuery.And().Facet("fieldAliasOnThatDocType");
      var facetResults = facetQuery.Execute().GetFacet(taxonomyFacetSearch.FieldName);
      

    Hope this helps someone.

    Regards

    David

  • David Armitage 503 posts 2071 karma points
    Dec 02, 2020 @ 01:57
    David Armitage
    0

    Hi,

    I did get this working to some degree but I can an issue with multiple selected facets.

    You know like a blog article that can be related to more than one blog category.


    I am hoping this is a config issue or search issue. I have managed to get the facets return data and worked really well and quite easy to get setup.

    I then noticed that some of the totals were not correct. I tracked this down to my facet field is a multiselect selecting form Umbraco nodes I use for taxonomy.

    I noticed that if only one item (category) was selected this gets included in the total. If I selected more than one item (category) then both of the selected values are not included in the total.

    So for example I have 5 blog articles

    Blog 1 - Category = 'Test Blog Category 1' Blog 2 - Category = 'Test Blog Category 1' Blog 3 - Category = 'Test Blog Category 2' Blog 4 - Category = 'Test Blog Category 3' Blog 5 - Category = 'Test Blog Category 1 and Test Blog Category 2'

    The facet total for 'Test Blog Category 1' would be 2 when it should be 3. The facet total for 'Test Blog Category 2' would be 1 when it should be 2.

    Because the data in Blog 5's category selection would not be included in the facet search results.

    Here is my search code. I am hoping there is an extra setting I can enable to make this function as required.

    var facetCriteria = facetSearcher.CreateQuery(IndexTypes.Content, BooleanOperation.And);
    var facetQuery = facetCriteria.NodeTypeAlias("blogDetailsPage");//considering blog pages only in the search
    
    facetQuery.And().Facet("categories");
    var facetResults = facetQuery.Execute().GetFacet("categories");
    

    Kind Regards

    David

  • David Armitage 503 posts 2071 karma points
    Dec 03, 2020 @ 00:00
    David Armitage
    0

    Hi Guys,

    I figured this out.

    So it seems to the way the facet search is working is a facet field is split into a string of values separated with a " ". It looks as though using a multitree picker and then using this as the facet search field doesn't really work well. My guess is the string of selected items is not formatted in a nice client way which the facet searching is expecting.

    I managed to get around this after some pointers from Callum Whyte https://github.com/callumbwhyte/examine-facets/issues/6

    As I already do to make multi tree pickers searchable I was able to add a custom field in the search index and then use this new field as the field I use for the facet search.

    I take the tree picker, check the selected items, join the selected guids (keys) into a string selected items with a " ". I then use this custom field as the facet field when searching.

    Eg.

    var searchableCategoryGuids = string.Empty;
    if (contentNode.Value("categories") is List<IPublishedContent> categories)
    {
        foreach (IPublishedContent category in categories)
            searchableCategoryGuids += (" " + category.Key.ToString());
    }
    e.ValueSet.Set("searchableCategoryGuids", searchableCategoryGuids);
    

    So the field "searchableCategoryGuids" is what I would use inside the facet search instead of "categories".

    This works perfectly. It also allows us to customize the facet data in any wacky way we feel like. For instance you might want to join the category name instead of the id. This would work too. There is a reason I use the Guid though. This is related to something I need to do later on.

    Kind Regards

    David

Please Sign in or register to post replies

Write your reply to:

Draft