Category Filter list with Smart Search

Brenden Kehren asked on February 6, 2015 16:50

I'd like to create a checkbox list of categories for filtering a smart search result. The category list must only be a list of the categories found in the documents returned in the search. In my case, the user will always search from a different page and be sent to the results page after. The results page will have the category filter on it but instead of displaying all 20 or 30 categories, I only want to display the categories that are assigned to the documents found in the search results.

Is this a custom filter control or can I use the predefined smart search filter webpart?

Recent Answers


Drew Robison answered on February 9, 2015 07:28

It seems like that will have to be a custom filter control. I have created something fairly similar, which I can share with you if you want. I don't know of anything that will get you where you want to be in terms of configuring a pre built webpart.

0 votesVote for this answer Mark as a Correct answer

Trevor Fayas answered on August 9, 2015 18:16

Another option Brenden, is to add Categories to the Smart Search index, and then use a Smart Search Text Filter webpart on it (coupled with some javascript to write the write filter text in it).

1st: Either create a duplicate Smart Search results that returns the result's categories, or add a hidden input tag with the categories values so you can (through javascript) gather all the categories in the returned results.

2: Use that list to build a Option List with the categories that were in the results

3: On "Search" Grab the values from the drop down, and then popoulate the hidden Smart Search Text field as such: Categories:("FirstCategory" "SecondCategory" "Etc")

You can add a + or - to the Categories to enforce it has to or simply to weigh higher if it does.

To add Category Names to the Smart Search, use the below code:

using CMS.Base;
using CMS.DocumentEngine;
using CMS.Membership;
using System.Collections.Generic;

[SmartSearchContentLoader]
public partial class CMSModuleLoader
{
    /// <summary>
    /// Attribute class for assigning event handlers.
    /// </summary>
    private class SmartSearchContentLoaderAttribute : CMSLoaderAttribute
    {
        /// <summary>
        /// Called automatically when the application starts.
        /// </summary>
        public override void Init()
        {
            // Assigns a handler to the GetContent event for pages
            DocumentEvents.GetContent.Execute += OnGetPageContent;
        }

        private void OnGetPageContent(object sender, DocumentSearchEventArgs e)
        {
            // Gets an object representing the page that is being indexed
            TreeNode indexedPage = e.Node;

            // Checks that the page exists
            if (indexedPage != null)
            {

                // Add category names to a searchable field "Categories" for filtering / weighing.
                List<string> joinedCategories = new List<string>();
                foreach (CMS.Taxonomy.CategoryInfo cat in e.Node.Categories)
                {
                    joinedCategories.Add(cat.CategoryName);
                }

                e.SearchDocument.AddGeneralField("Categories", string.Join("|", joinedCategories.ToArray()), true, true);

                // Gets the user object of the page owner
                UserInfo pageOwner = UserInfoProvider.GetUserInfo(indexedPage.NodeOwner);

                if (pageOwner != null)
                {
                    // Adds the value of the "Description" field from the owner's user settings into the indexed content
                    // Spaces added as separators to ensure that typical search index analyzers can correctly tokenize the index content
                    //e.Content += " " + pageOwner.UserDescription + " ";
                }
            }
        }
    }
}
0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on August 10, 2015 03:37

I was thinking on that same line Drew. Either that or a custom search index. Thanks for that suggestion Trevor, good idea.

1 votesVote for this answer Mark as a Correct answer

Jan Mudrák answered on July 9, 2016 23:51

Thanks for great answer!

It works just fine with one small exception: you shouldn't use '|' as a separatator. Use space character instead. (For example 'Category1|Category2|Category3' will be taken as one word by Lucene.)

0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.