Chris Auer
Chris Auer

Reputation: 1435

How to facet on Sitecore Tags using ContentSearchManager

I understand how to use the ContentSearchManager to search for items and how to facet on fields. But I can't quite figure out how to facet on the tags that I have created in Sitecore. The UI facets on them by default, but in the index using the ContentSearchManager. Does anyone have knowledge of it? Thank you

FacetResults facets = new FacetResults();

facets = query.Where(x => x.Language.Equals(computedLanguage)
                          && (x.PageTitle.Contains(text)))
                         .FacetOn(facet => facet.tags).GetFacets();

Upvotes: 1

Views: 3164

Answers (1)

Matt Gartman
Matt Gartman

Reputation: 867

I am not sure where you have the "tags" property defined since it is not a property that is defined in the default SearchResultItem class provided by Sitecore and you don't show the declaration of "query". "Semantics" is actually the property you would want to use to access the GUIDs for the tags that are defined on your item.

There are two approaches to faceting on those Tags now. You could just facet on the Semantics property to get the faceting based on GUID. You would then look up the GUID in Sitecore to get the name of the Tag.

FacetResults facets = new FacetResults();

facets = query.Where(x => x.Language.Equals(computedLanguage)
                      && (x.PageTitle.Contains(text)))
                     .FacetOn(facet => facet.Semantics).GetFacets();

The other approach would be to actually store the Tag Names in your Search Index. This gives you the added benefit of allowing users to easily search by Tag name.

The computed field to store your Tags names in the index would look something like this:

public class TagsFacet : IComputedIndexField
{
    public object ComputeFieldValue(IIndexable indexable)
    {
        var indexableItem = indexable as SitecoreIndexableItem;

        if (indexableItem == null)
        {
            return null;
        }

        if (indexableItem.Item.Fields["__Semantics"] == null) return null;

        MultilistField tags = indexableItem.Item.Fields["__Semantics"];

        var tagNames = tags.GetItems().Select(tag => tag.Name).ToList();

        return tagNames;
    }

    public string FieldName { get; set; }
    public string ReturnType { get; set; }
}

You will need to add in the computed field to your Sitecore.ContentSearch.LuceneDefaultIndexConfiguration.config (assuming you are using Lucene) in the raw:AddComputedIndexField section:

<field fieldName="tagsfacet">SitecoreBase72.TagsFacet,SitecoreBase72</field>

You will then need to extend the SearchResultItem class to add the new field name:

public class CustomSearchModel : SearchResultItem
{
    [IndexField("tagsfacet")]
    public List<String> tagsFacet { get; set; } 

}

And finally you can facet on your tag fields (once you rebuild your index):

var searchIndex = ContentSearchManager.GetIndex("sitecore_master_index");

using (var context = searchIndex.CreateSearchContext())
{
    var myTagFacets = new FacetResults();

    myTagFacets = context.GetQueryable<CustomSearchModel>()                        
                  .FacetOn(facet => facet.tagsFacet)
                  .GetFacets();

    foreach (var facetCategories in myTagFacets.Categories)
    {
        foreach (var facet in facetCategories.Values)
        {
            Log.Info(string.Format("Facet:{0} Results:{1}",facet.Name,facet.AggregateCount),this);
        }

    }
}

Upvotes: 7

Related Questions