2 replaced http://stackoverflow.com/ with https://stackoverflow.com/
source | link
1
source | link

It's worth bearing in mind that you'll always have the ID of the item in the Index, so you would still be able to generate a URL at runtime once you have your search result. This may also be preferable on cutting down the complexity of your solution.

However, to address your question:

With Lucene, the URL should be populated by default in the index. However I believe this only works for the default "website" site. This is the code that Sitecore uses for the SearchResultItem.Url property which is connected to the urllink field in the index:

public class UrlLink : AbstractComputedIndexField
  {
    public override object ComputeFieldValue(IIndexable indexable)
    {
      Item item = (Item) (indexable as SitecoreIndexableItem);

      if (item == null)
        return (object) null;

      if (item.Paths.IsMediaItem)
        return (object) MediaManager.GetMediaUrl((MediaItem) item);

      UrlOptions defaultUrlOptions = LinkManager.GetDefaultUrlOptions();
      defaultUrlOptions.Site = SiteContextFactory.GetSiteContext("website");

      return (object) LinkManager.GetItemUrl(item, defaultUrlOptions);
    }
  }

As you can see, the site context of "website" is hardcoded in. For items in that website, the URL should be fine. Other sites will be incorrect however and result in URLs such as /en/sitename/Home....

If you are in a multi-site environment (and your question suggests you are), you will need an alternate method that determines what is the correct Site based on the item, and then sets that .Site in the URL options.

You can use an extension method such as this for getting the site based on an item:

public static SiteInfo GetSite(this Item item)
{
    var siteInfoList = Sitecore.Configuration.Factory.GetSiteInfoList();

    SiteInfo currentSiteinfo = null;
    var matchLength = 0;
    foreach (var siteInfo in siteInfoList)
    {
        if (item.Paths.FullPath.StartsWith(siteInfo.RootPath, StringComparison.OrdinalIgnoreCase) && siteInfo.RootPath.Length > matchLength)
        {
            matchLength = siteInfo.RootPath.Length;
            currentSiteinfo = siteInfo;
        }
    }

    return currentSiteinfo;
}

Combined with the above, this would allow you to update your computed index field with:

defaultUrlOptions.Site = new SiteContext(item.GetSite());

Credit for the extension method goes to zhankezk in the answer to this StackOverflow question - http://stackoverflow.com/questions/14200864/how-to-find-out-with-which-sitecore-site-an-item-is-associated