Strange Find results in multilanguage Alloy site


I've just installed the latest version of AlloyTech, running on Episerver 11.4 with Episerver Find 12.7.1. I've created a developer Find index for testing, and specified both Norwegian and English for this index. I've made the following changes to the site:

  1. Added Norwegian as a language
  2. Removed Swedish
  3. Translated a few items to Norwegian (the Start page, the Alloy Plan page, and the Jumbotron on the Start page).
  4. Re-indexed the site (of course)

My name ("Anders") and the word "møtes" (relexive of "to meet") both occur exactly ONCE among my translated items. But...

Searching for "møtes" on the site gives 0 hits:

Searcing for

Seaching for my name "Anders" is just as strange, this gives 17 hits:

The interresting thing, is that this does not correspone one-two-one with what I find in the Find index itself. 

Searching for "møtes" in the Find index gives exactly ONE hit, as it should:

Searcing for

Searching for "Anders" in the Find index also gives the single hit it should:

Why do I get this discrepancy between hits in the index and what I see on the Alloy page? I'm building a demo for a Norwegian customer, so it's kind of important that I can show them that searching in Norwegian works fine... :)

Mar 23, 2018 11:01

Can you post the code you are using on the front end for Find? I wonder if it's a caching issue?

Mar 23, 2018 15:54

As already stated, this is a plain Alloy Tech solution. I have done absolutely nothing to the code. Not even looked at it... :)

I'll take a look now, though...

Setting a breakpoint in the code gives the same problem (17 hits for "Anders", 0 hits for "møtes):


Searching for "anders"


Searching for "møtes"

File FindSearchPageController.cs (missing a plugin for code on this forum):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Mvc;
using EPiServer.Core;
using EPiServer.Find.Framework.Statistics;
using EPiServer.Find.Helpers.Text;
using EPiServer.Framework.Web.Resources;
using Epidemo.Models.Pages;
using Epidemo.Models.ViewModels;
using EPiServer.Find.UI;
using EPiServer.Find.UnifiedSearch;
using EPiServer.Globalization;
using EPiServer.Find;
using EPiServer.Find.Api.Querying.Queries;
using Epidemo.Controllers;
using EPiServer.Web;
using EPiServer.Find.Cms;
using Epidemo.Models.Pages;

namespace Epidemo.Controllers
public class FindSearchPageController : PageControllerBase<FindSearchPage>
private readonly IClient searchClient;
private readonly IFindUIConfiguration findUIConfiguration;
private readonly IRequiredClientResourceList requiredClientResourceList;
private readonly IVirtualPathResolver virtualPathResolver;
public FindSearchPageController(IClient searchClient, IFindUIConfiguration findUIConfiguration, IRequiredClientResourceList requiredClientResourceList, IVirtualPathResolver virtualPathResolver)
this.searchClient = searchClient;
this.findUIConfiguration = findUIConfiguration;
this.requiredClientResourceList = requiredClientResourceList;
this.virtualPathResolver = virtualPathResolver;

public ViewResult Index(FindSearchPage currentPage, string q, string selectedAnalyzer)
var model = new FindSearchContentModel(currentPage)
PublicProxyPath = findUIConfiguration.AbsolutePublicProxyPath()

//detect if serviceUrl and/or defaultIndex is configured.
model.IsConfigured = SearchIndexIsConfigured(EPiServer.Find.Configuration.GetConfiguration());

if (model.IsConfigured && !string.IsNullOrWhiteSpace(model.Query))
var query = BuildQuery(model, selectedAnalyzer);

//Create a hit specification to determine display based on values entered by an editor on the search page.
var hitSpec = new HitSpecification
HighlightTitle = model.CurrentPage.HighlightTitles,
HighlightExcerpt = model.CurrentPage.HighlightExcerpts,
ExcerptLength = model.ExcerptLength

model.Hits = query.GetResult(hitSpec);
catch (WebException wex)
model.IsConfigured = wex.Status != WebExceptionStatus.NameResolutionFailure;

model.Analyzers = CreateAnalyzers(selectedAnalyzer);


return View(model);

private IEnumerable<SelectListItem> CreateAnalyzers(string selected)
var items = new List<SelectListItem> {CreateSelectListItem("", "", selected)};
items.AddRange(searchClient.Settings.Languages.Select(x => CreateSelectListItem(x.Name, x.FieldSuffix, selected)));

return items;

private SelectListItem CreateSelectListItem(string name, string value, string selected)
return new SelectListItem { Text = name, Value = value, Selected = value == selected };

private ITypeSearch<ISearchContent> BuildQuery(FindSearchContentModel model, string selectedAnalyzer)
var language = searchClient.Settings.Languages.GetSupportedLanguage(selectedAnalyzer);

var queryFor = language != null ?
searchClient.UnifiedSearch(language) :

var querySearch = string.IsNullOrEmpty(selectedAnalyzer) || language == null
? queryFor.For(model.Query)
: queryFor.For(model.Query, x => x.Analyzer = language.Analyzer);

if (model.UseAndForMultipleSearchTerms)
querySearch = querySearch.WithAndAsDefaultOperator();

var query = querySearch
//Include a facet whose value is used to show the total number of hits regardless of section.
//The filter here is irrelevant but should match *everything*.
.TermsFacetFor(x => x.SearchSection)
.FilterFacet("AllSections", x => x.SearchSection.Exists())
//Fetch the specific paging page.
.Skip((model.PagingPage - 1)*model.CurrentPage.PageSize)
//Allow editors (from the Find/Optimizations view) to push specific hits to the top
//for certain search phrases.

// obey DNT
var doNotTrackHeader = System.Web.HttpContext.Current.Request.Headers.Get("DNT");
// Should not track when value equals 1
if (doNotTrackHeader == null || doNotTrackHeader.Equals("0"))
query = query.Track();

//If a section filter exists (in the query string) we apply
//a filter to only show hits from a given section.
if (!string.IsNullOrWhiteSpace(model.SectionFilter))
query = query.FilterHits(x => x.SearchSection.Match(model.SectionFilter));

return query;

/// <summary>
/// Checks if service url and index are configured
/// </summary>
/// <param name="configuration">Find configuration</param>
/// <returns>True if configured, false otherwise</returns>
private bool SearchIndexIsConfigured(EPiServer.Find.Configuration configuration)
return (!configuration.ServiceUrl.IsNullOrEmpty()
&& !configuration.ServiceUrl.Contains("YOUR_URI")
&& !configuration.DefaultIndex.IsNullOrEmpty()
&& !configuration.DefaultIndex.Equals("YOUR_INDEX"));

/// <summary>
/// Requires the client resources used in the view.
/// </summary>
private void RequireClientResources()
// jQuery.UI is used in autocomplete example.
// Add jQuery.UI files to existing client resource bundles or load it from CDN or use any other alternative library.
// We use local resources for demo purposes without Internet connection.

Mar 26, 2018 8:23
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.