SaaS CMS has officially launched! Learn more now.

Jonas Bergqvist
Apr 3, 2018
  5539
(8 votes)

Find 13: New language routing

In order to optimize indexing performance, and increase query precision, indexing documents should be done by specifying language routing. The use of language routing, when indexing, does not require any changes when querying. The only effect language routing has on querying is that it increases query precision. This is done by reducing the number of false positive matches, as documents only are analyzed for a specific language. Previously, all documents were analyzed for all available languages supported, sometimes causing noise when stemming rules for one language collided with stemming rules for another.

Adding language routing on any type of object

Adding language routing for any type of object can be done in different ways.

LanguageRoutingAttribute

One option is to use LanguageRoutingAttribute on the property, and set it to the desired language when initializing the object.

public class WithLanguageRoutingAttribute
{
     [Id] 
     public string Id { get; set; } 
     [LanguageRouting] 
     public LanguageRouting LanguageRouting { get; set; } 
} 
var indexedObject = new WithLanguageRoutingAttribute()

{ 
     Id = "123", 
     LanguageRouting = new LanguageRouting(Language.Swedish) 
}; 

Conventions

Another option is to use the conventions API in Find.

client.Conventions.ForInstancesOf<WithLanguageRouting>().LanguageRoutingIs(x => x.LanguageRouting);

CMS integration

The Find CMS integration automatically adds language routing support for content implementing ILocale. Most content base type, like PageData, ProductContent, NodeContent, and VariationContent, all implements ILocale. The behavior can be changed by either using conventions, or by overriding LanguageRoutingFactory.

Conventions

The following example changes the behavior for all content implementing ILocale, to store the documents in the old way. It’s not recommended to do this, because it prevents the performance improvements.

client.Conventions.ForInstancesOf<ILocale>().LanguageRoutingIs(x => null);

This example changes the behavior only for MediaData. You might want to do this for some specific content types, if it’s necessary to analyze the content using all analyzers.

client.Conventions.ForInstancesOf<MediaData>().LanguageRoutingIs(x => null);

LanguageRoutingFactory

A LanguageRoutingFactory is, by default, used for all ILocale content, to create language routing for content that implements ILocale. It’s possible to change the default behavior by creating your own factory that inherits from LanguageRoutingFactory, and override any of the protected virtual methods. You also need to register your language routing factory using a configurable module.

[InitializableModule]
[ModuleDependency(typeof(IndexingModule))]
public class MyFindInitializationModule : IConfigurableModule
{
     public void Initialize(InitializationEngine context)
     {
     }
     public void Uninitialize(InitializationEngine context)
     {
     }
     public void ConfigureContainer(ServiceConfigurationContext context)
     {
         context.Services.AddSingleton<LanguageRoutingFactory, MyLanguageRoutingFactory>();
     }
}
The following example changes the behaviour, to use all analyzers instead of the “standard” analyzer, for all content which uses a language we can’t map to any analyzer.
public class MyLanguageRoutingFactory : LanguageRoutingFactory
{
     public override LanguageRouting CreateLanguageRouting(ILocale locale)
     {
         var languageRouting = base.CreateLanguageRouting(locale);
         if (languageRouting.FieldSuffix == Language.None.FieldSuffix)
         {
             return null;
         }
         return languageRouting;
     }
}

Reindex the site after upgrade to Find 13

The changes in the language routing make it necessary to reindex the site after upgrading to Find 13. The site will work directly when you start the site, before the content has been reindexed. It will work because queries will still hit the content that hasn’t been indexed using the language routing.

The problem (if site isn’t reindexed) will occur when content is reindexed after being triggered from a content event. The content might be stored in a different way as before, which might make the old content continue to exist. You can end up having the same content stored twice, but in different versions.

Conclusion: After upgrading to Find 13, reindex the whole site as soon as possible.

Apr 03, 2018

Comments

K Khan
K Khan Apr 3, 2018 07:48 PM

Cool!

K Khan
K Khan Apr 3, 2018 07:52 PM

Am i Correct in understanding? that conventions can be used with Commerce objects also as Products and Variants?

Apr 4, 2018 07:33 AM

K Khan, You are correct. Commerce objects like products and variants implements ILocale, and will use language routing by default. You can override the behaviour if needed.

Magnus Rahl
Magnus Rahl Apr 4, 2018 08:43 AM

A Find 13 compatible EPiServer.Find.Commerce is in the making, hopefully it can be released next week. Then you will be able to use Find 13 in applications using Find.Commerce as well.

Cristi Rusu
Cristi Rusu May 11, 2018 11:39 AM

I tried using "client.Conventions.ForInstancesOf().LanguageRoutingIs(x => null);" but the indexing job throws "Object reference not set to an instance of an object.".

Did anyone have better luck using it?

dada
dada May 21, 2018 09:38 AM

This doesn't throw an error but does it do what I expect?
client.Instance.Conventions.ForInstancesOf().LanguageRoutingIs(x => new LanguageRouting(Language.None));


karthik
karthik Aug 20, 2018 04:39 PM

indexItem.LanguageRouting = new LanguageRouting(findclient.Settings.Languages.GetSupportedLanguage(language));

I try to index my custom model after setting the languagerouting it throws an error 

"Object reference not set to an instance of an object".

stacktrace:

  at EPiServer.Find.ClientConventions.CompositeLanguageRoutingConvention.GetLanguageRouting(Object instance)
   at EPiServer.Find.Client.Index(Object objectToIndex, Action`1 commandAction)
   at EPiServer.Find.Client.Index(Object objectToIndex)

Son Do
Son Do Aug 22, 2018 07:05 AM

I moved Karthikeyan's question to related Forum thread https://world.episerver.com/forum/developer-forum/EPiServer-Search/Thread-Container/2018/8/searchclient-instance-index-throws-error.

Apr 18, 2019 07:36 AM

Does this use the sharding functionality from Elastic Search? The reason I'm wondering is that I first expected to only get search hits from a single language back when using language routing, but I'm seeing results for multiple languages and I need to add a filter for it. Which I don't mind, but I thought the language routing feature was using the sharding in Elastic Search to only have to care about a single language.

Please login to comment.
Latest blogs
Optimizely Graph – Faceting with Geta Categories

Overview As Optimizely Graph (and Content Cloud SaaS) makes its global debut, it is known that there are going to be some bugs and quirks. One of t...

Eric Markson | Jul 22, 2024 | Syndicated blog

Integration Bynder (DAM) with Optimizely

Bynder is a comprehensive digital asset management (DAM) platform that enables businesses to efficiently manage, store, organize, and share their...

Sanjay Kumar | Jul 22, 2024

Frontend Hosting for SaaS CMS Solutions

Introduction Now that CMS SaaS Core has gone into general availability, it is a good time to start discussing where to host the head. SaaS Core is...

Minesh Shah (Netcel) | Jul 20, 2024

Optimizely London Dev Meetup 11th July 2024

On 11th July 2024 in London Niteco and Netcel along with Optimizely ran the London Developer meetup. There was an great agenda of talks that we put...

Scott Reed | Jul 19, 2024