Sitecore 7 & Solr – Why SearchResultItem.Url is always null?

Share Button

One essential thing that you will need to do in almost every search implementation is linking each search result item to their full (details) pages. The Sitecore content search provider for Solr doesn’t index the item url by default, here are the steps you need to get it working:

The Sitecore.ContentSearch.SearchTypes.SearchResultsItem base class contains the following property:

[IndexField("urllink")]
public virtual string Url {get; set;}

Consider the following sample code to get the urls of items located under a specific parent:

...
using(var context = index.CreateSearchContext())
{
  var query = context.GetQueryable<SearchResultItem>();
  var pageUrls = query.Where(i => i.Parent == new ID("<ParentItemIdHere>"))
                      .GetResults().Hits.Select(h => h.Document.Url).ToList();
}

As the Url property is not mapped by default, the pageUrls collection will contain null values.

To fix this issue, create the following computed field to return the item url:

namespace DevSolrSearchDemo.Search.ComputedFields
{
    public class ItemUrl : IComputedIndexField
    {
        public object ComputeFieldValue(IIndexable indexable)
        {
            var scIndexable = indexable as SitecoreIndexableItem;
            if (scIndexable != null)
            {
                var item = (Item)scIndexable;
                if (item != null)
                {
                    var opts = LinkManager.GetDefaultUrlOptions();
                    opts.Site = Sitecore.Sites.SiteContext.GetSite("website");
                    return LinkManager.GetItemUrl(item, opts);
                }
            }
            return null;
        }

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

The final step is to update the Sitecore.ContentSearch.Solr.Indexes.config include file to map your custom computed field to the”urllink” field in Solr as follows:

<fields hint="raw:AddComputedIndexField>
...
<field fieldName="urllink" returnType="string">DevSolrSearchDemo.Search.ComputedFields.ItemUrl, DevSolrSearchDemo</field>
</fields>

Now, your search code should return the items url.

2 Comments

  1. said:

    This will work in single site setup and where the site name is not changed from default website. One reason why Sitecore should have omitted is because of multi site implementation. When we have multi sites setup then context site plays a pivot role in creating the url using Link Manager.
    opts.Site = Sitecore.Sites.SiteContext.GetSite(“website”);

    December 10, 2015
    Reply
  2. Kyle said:

    Thanks for the post. This was the “heads up” I needed to get pointed in the right direction. Just wanted to let you know that it is not necessary to write the class to generate the value of the computed field. You can just use the standard implementation that Sitecore uses for Lucene. In that case you can just add the following line to your config file to map the field:

    Sitecore.ContentSearch.ComputedFields.UrlLink,Sitecore.ContentSearch

    February 9, 2016
    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *