Searching multiple subsites within same index using #Episerver FIND UnifiedSearch

This guide shows you how you can index multiple episerver solutions within same index.

Published 4th of September 2017
Episever FIND 12.5 and CMS 10

Scenario:

One corporate site www.corp.com and a couple of subsites sub1.corp.com and sub2.corp.com, each site has their own solution.

The main search/resultpage is only displayed in top site www.corp.com/search

FIND Default behavior

  1. Default behavior for Episerver FIND (and the built in schedule task job called “EPiServer Find Content Indexing Job”) is that it removes packages/namespaces from index that is not included in the solution. Depending on FIND configuration it removes the other sites content from Index.
  2. By default, when searching with UnifiedSearch, it will build a request with the siteId of the site.

How to accomplish

  1. Configure same index in all solutions
  2. On subsites, fake the siteId in configuration
  3. Build your own Scheduled Job for indexing your subsite
  4. Remove the default scheduled job

Change siteId on subsite

By default, when searching with UnifiedSearch, it will build a request with the siteId of the site. FindInitialization:

[InitializableModule]
    public class FindInitialization : IInitializableModule
    {
        public void Initialize(InitializationEngine context)
        {
              SearchClient.Instance.Conventions.ForInstancesOf<PageData>().IncludeField(x => x.SiteId());
        }
    }

        public static string SiteId(this SitePageData content)
        {
            // your main site guid
            return "bc031fbd-dc8a-4672-9f76-891cdad23ac2"; 
        }

Indexing scheduled job

This job should be implemented on the subsites, and even possibly on main site.

    [ScheduledPlugIn(DisplayName = "Episerver FIND Content index job", 
    Description = "This indexing job is used to reindex all content without
    removing anything from the index. During normal operation changes to 
    content are being indexed as they are made without rerunning or 
    scheduling of this job. ")]
    public class FindIndexScheduledJob
    {
        public static string Execute()
        {
            Languages languages = SearchClient.Instance.Settings.Languages;
            var result = ContentIndexer.Instance.IndexFrom(
                    contentLink: ContentReference.StartPage,
                    includeRootPage: true,
                    cultures: languages.Select(lang => new CultureInfo(lang.FieldSuffix))).ToList();

                var str = string.Concat("Done indexing ", string.Join(", ", languages.Select(x => x.Name)),
            " with a total of ", 
             result.Count(x => !x.ExcludedByConventions), 
            " indexed items and ", 
             result.Count(x => x.ExcludedByConventions), " excluded items");

            return str;
        }
    }

Remove the default “EPiServer Find Content Indexing Job”

Go to admin/config tab/plug-in Manager/Episerver FIND CMS/Overview tab/untick and save

NOTICE

This works with different solutions with different namespaces, so no need to have object model implemented in all solutions.

In theory no need to do any configuration on top “search” site.

IMPORTANT

You need to have same FIND versions for the search to work. If the version is higher on subsite, the search will throw InvalidOperationException

The model item passed into the dictionary is of type ‘EPiServer.Find.ProjectionException’, but this dictionary requires a model item of type ‘System.Web.Mvc.HandleErrorInfo’.

This may be fixed with levering the bindings on Episerver.Find

<dependentAssembly>
<assemblyIdentity name="EPiServer.Find" publicKeyToken="8fe83dea738b45b7" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-15.0.0.0" newVersion="12.5.1.0" />
</dependentAssembly>

Resources:

SEO terms:

  • Use the same index for multiple sites
  • Using Find to index multiple sites
  • how to search content in different EPiServer websites
  • Indexing & searching multiple sites

 

Leave a Reply

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