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.
You can install the package via NuGet.
PM> Install-Package Cairngorm
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.
- Install the Cairngorm package to your project.
- 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>
- Deploy the project with the configurations.
- 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 ...; } }
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 |
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.
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>
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>
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.
- Takumi Yamada (xirtardauq@gmail.com)
Cairngorm is licensed under the MIT license. See LICENSE.txt.