3

I'm trying to implement Recommended Results feature with Sitecore lucene search for our website.

I'm thinking to implement a Tag field, and depending on the tags selected for a page item, boost the lucene content search results.

My questions are,

  • How can we boost the particular search result entry on indexing time, when we indexing to lucene index ?
  • if we achieve above point, how can be a particular search result entry be boosted only for a given search wording ?

Thank you.

8

If you want to boost field during the indexing time, you can use the "boost" property of field in the index configuration. For example:

lucene boosting field

Below is another solution how you can boost an item based on keywords, which user entered:

I guess you are going to use multilist type for the Tags field. The multilist field is a reference field and contains IDs of selected items. First of all, we need to implement a computed field which would store a tag title instead of ID:

    using System.Linq;
    using Sitecore.ContentSearch;
    using Sitecore.ContentSearch.ComputedFields;
    using Sitecore.Data.Items;


    namespace SearchBoosting
    {
        public class ItemTagsComputedField
        {
            public class MediaDownloadCenterGroupComputedField : IComputedIndexField
            {
                public object ComputeFieldValue(IIndexable indexable)
                {
                    Item item = indexable as SitecoreIndexableItem;
                    if (item != null)
                    {
                        //I guess the tags field will have a multilist typle. 
                        Sitecore.Data.Fields.MultilistField field = item.Fields["Item Tags"]; //Name of field with tags

                        if (field != null)
                        {
                            var items = field.GetItems();

                            return items.Select(q => q.DisplayName).ToList(); //You can use some field for getting title of tag.
                        }
                    }

                    return null;
                }

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

Then we need to add them to the index configuration. Just add the following row to the section. It will look like below:

multilist computed field

The next step is to add a search model:

using System.Collections.Generic;
using System.ComponentModel;
using Sitecore.ContentSearch;
using Sitecore.ContentSearch.Converters;
using Sitecore.ContentSearch.SearchTypes;

namespace SearchBoosting
{
    public class BoostingExampleSearchResultItem : SearchResultItem
    {
        [IndexField("item_tags")]
        [TypeConverter(typeof(IndexFieldEnumerableConverter))]
        public virtual IEnumerable<string> Tags { get; set; }
    }
}

Now we are ready to use this field for boosting:

using System.Collections.Generic;
using System.Linq;
using Sitecore.ContentSearch;
using Sitecore.ContentSearch.Linq;
using Sitecore.ContentSearch.Linq.Utilities;
using Sitecore;


namespace SearchBoosting
{
    public class SearchBoosting
    {
        protected virtual string SearchIndexName
        {
            get
            {
                return "your_search_index";
            }
        }

        private ISearchIndex _index;
        private ISearchIndex Index
        {
            get { return _index ?? (_index = ContentSearchManager.GetIndex(SearchIndexName)); }
        }

        public SearchResults<BoostingExampleSearchResultItem> ApplySearch(List<string> keywords)
        {

            using (IProviderSearchContext searchContext = Index.CreateSearchContext())
            {
                var query = searchContext.GetQueryable<BoostingExampleSearchResultItem>(new CultureExecutionContext(Context.Language.CultureInfo));

                var predicateRoots = PredicateBuilder.True<BoostingExampleSearchResultItem>();

                if (keywords != null && keywords.Any())
                {
                    foreach (var keyword in keywords)
                    {
                        //If we want just boost some items without theirs filtering, we need to process both conditions:
                        //if item contains a tag which is equals to entered word and if it doesn't:

                        predicateRoots = predicateRoots.Or(itm => (itm.Tags.Contains(keyword)).Boost(5f));
                        predicateRoots = predicateRoots.Or(itm => (!itm.Tags.Contains(keyword)).Boost(1f));
                    }
                }

                var results = query.Where(predicateRoots).GetResults();

                return results;
            }
        }
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.