Skip to content

tackme31/Cairngorm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cairngorm

Cairngorm is an easy-to-use recommender library for Sitecore. This library has the following features:

  • Simple API.
  • Work with a small configuration.
  • No machine learning needed.
  • Customizable.

Warning: This repo is under development. The API is likely to change.

Installation

You can install the package via NuGet.

PM> Install-Package Cairngorm

Usage

The recommender searches recommended items based on "Tag", resolved from an item. The more "Tag"s an item contains, the more likely the item is recommended.

  1. Install the Cairngorm package to your project.
  2. Apply the following configuration patch.
    <configuration>
      <sitecore>
        <cairngorm>
          <configuration type="Cairngorm.Configurations.RecommenderConfiguration, Cairngorm">
            <recommenders hint="list:AddRecommender">
              <recommender name="sample" type="Cairngorm.Configurations.RecommenderSetting, Cairngorm">
                <!-- Specify recommender name. -->
                <param desc="name">$(name)</param>
    
                <!-- Add template name or ID to be the target of the recommender. -->
                <searchTemplates hint="list">
                  <SampleItem>{76036F5E-CBCE-46D1-AF0A-4143F9B557AA}</SampleItem>
                </searchTemplates>
    
                <!-- Add tag resolvers. In the following example, tags are contained in the "Tags" field, separated by '|'. -->
                <tagResolvers hint="raw:AddTagResolver">
                  <resolver type="Cairngorm.TagResolvers.TextFieldTagResolver, Cairngorm" fieldName="Tags" delimiter="|" />
                </tagResolvers>
              </recommender>
            </recommenders>
          </configuration>
        </cairngorm>
      </sitecore>
    </configuration>
  3. Deploy the project with the configurations.
  4. Now you can use the recommender like this:
    public class SampleRecommendationRepository
    {
        protected IRecommender SampleRecommender { get; }
    
        public SampleRecommendationRepository(IRecommenderFactory factory)
        {
            // Get the recommender by the name specified in the configuration.
            SampleRecommender = factory.GetRecommender(name: "sample");
        }
    
        public IModel GetModel()
        {
            // Get recommended items by the recommender.
            var recommendation = SampleRecommender.GetRecommendation(count: 5);
            return ...;
        }
    }

Configuration

You can see a sample configuration from here.

Property Name Type Description Default Value
SearchField string An index field name for search by tags. "_content"
SearchTemplates List<string> Template name or id to be the target of the recommender. Empty (All templates).
SearchScope string A root item where it's searched from (Path or ID). No scope.
TagResolvers List<TagResolverBase> Tag resolvers which resolve the tags from an item. See the Tag Resolver section for more information. No resolver.
ItemsStore ItemsStoreBase A store to keep context items. By default, the items are stored in a cookie. See the Items Store section. CookieItemsStore
WeightPerMatching float A value to be added to boosting when a tag is matched. 1.0
BoostGradually bool When enabled, gives higher weight to items retrieved from the ItemStore that are closer to the beginning. By default, newly added items to the cookie are weighted more heavily. false
FilterStoredItems bool When enabled, items contained in the ItemsStore will be excluded from the recommendation results. true
FilterContextItem bool When enabled, a context item is filtered from results. true

Items Store

By default, a context item is stored in a cookie. This behavior is due to the CookieItemsStore class, which has the following properties.

Property Name Type Description Default Value
StoredItemsCount int A length of items stored in the cookie. 10
CookieInfo CookieInfo Cookie's information used for recommendation. See the next table.

And the CookieInfo property has the following properties.

Property Name Type Description Default Value
Name string Cookie's name (required). "recommend_items"
MaxAge int A Cookie's lifetime used to set the Expires attribute. 2592000 (30 days)
Domain string A value of the cookie's Domain attribute. Empty.
Path string A value of the cookie's Path attribute. "/"
Secure bool A value of the cookie's Secure attribute. true
HttpOnly bool A value of the cookie's HttpOnly attribute. true

You can create a custom items store by implementing the ItemsStoreBase class.

Tag Resolver

There are three pre-defined resolvers:

Name Description
TextFieldTagResolver Tags are in the text field. When a delimiter is specified, the field value is split by it.
LinkFieldTagResolver Tags are in the item's field referred from the link field. When a delimiter is specified, the field value is split by it.
MultilistFieldTagResolver Tags are in the items' field referred from the multilist field. When a delimiter is specified, the field value is split by it.

The tag resolver can be added by implementing a class derived from the TagResolverBase class.

public class MetadataKeywordsTagResolver : Cairngorm.TagResolvers.TagResolverBase
{
    public MetadataKeywordsTagResolver (XmlNode node) : base(node)
    {
    }

    public override List<string> GetItemTags(Item item)
    {
        // Get tags from the Keyword field in the {item's path}/Data/Metadata item.
        var metadata = item.Children["Data"].Children["Metadata"];
        return metadata["Keywords"].Split(' ').ToList();
    }
}

And set the resolver to configuration's TagResolvers section.

<tagResolvers hint="raw:AddTagResolver">
  <resolver type="Namespace.To.MetadataKeywordsTagResolver, AssemblyName" />
</tagResolvers>

Search Filter

The recommender filters items that have non-context languages from results. If you want to add or change filters, override the DefaultRecommender.ApplyItemsFilter method.

public class MySearchResultItem : SearchResultItem
{
    public string MyProperty { get; set; }
}

public class MyRecommender : Cairngorm.Services.DefaultRecommender<MySearchResultItem>
{
    public MyRecommender(RecommenderSetting setting) : base(setting)
    {
    }

    // Apply additional filters.
    protected override IQueryable<MySearchResultItem> ApplyItemsFilter(IQueryable<MySearchResultItem> query) => base.ApplyItemsFilter(query)
        .Filter(item => item.MyProperty == "My Filter")
        .Filter(item => item.TemplateName == "My Template");
}

Then fix the recommender factory to return the custom recommender.

public class MyRecommenderFactory : Cairngorm.Services.DefaultRecommenderFactory<MySearchResultItem>
{
    public override Recommender GetRecommender(string name)
    {
        var setting = GetRecommenderSetting(name);
        return new MyRecommender(setting);
    }
}

Finally, replace the default factory to the customized one.

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <services>
      <register serviceType="Cairngorm.Services.IRecommenderFactory, Cairngorm">
        <patch:attribute name="implementationType">Namespace.To.MyRecommenderFactory, AssemblyName</patch:attribute>
      </register>
    </services>
  </sitecore>
</configuration>

Compatibility

This library is only tested on the following versions.

  • Sitecore XP 9.1.0
  • Sitecore XP 9.1.1
  • Sitecore XP 9.3.0
  • Sitecore XP 10.1.1

It should also work on Sitecore 9.x and 10.x, but if it doesn't please let me know.

Author

License

Cairngorm is licensed under the MIT license. See LICENSE.txt.