Using the CollationAnalyzer with a dynamic number of languages

51 views
Skip to first unread message

Morten Bock

unread,
May 13, 2015, 7:49:44 AM5/13/15
to rav...@googlegroups.com
Hi.

We have a website, where we use RavenDB to store product information.

The editors of the website can add new languages as they please, so we do not know up front how many languages we need.

Our current approach is to have a single Product collection, that contains all products. The document will then look something like this (simplified)

{
    "Sku": "12345",
    "CultureName": "en-US",
    "Name": "My product"
}

This presents a challenge when we want to get products for a language, and sort them be Name, since different languages have different sorting rules.

The solution I have currently solves the issue, for a predetermined number of languages:

public ProductDocument_FreeTextWithFacets()
{
Map = products =>
products.Select(product => new
{
product.CultureName,
product.Sku,
product.Name,
SortableName_en = product.Name,
SortableName_da = product.Name,
SortableName_ru = product.Name,
});

Indexes.Add(x => x.CultureName, FieldIndexing.NotAnalyzed);

Indexes.Add(x => x.Name, FieldIndexing.NotAnalyzed);

Index("SortableName_en", FieldIndexing.Analyzed);
Sort("SortableName_en", SortOptions.String);
Analyze("SortableName_en", "Raven.Database.Indexing.Collation.Cultures.EnCollationAnalyzer, Raven.Database");

Index("SortableName_da", FieldIndexing.Analyzed);
Sort("SortableName_da", SortOptions.String);
Analyze("SortableName_da", "Raven.Database.Indexing.Collation.Cultures.DaCollationAnalyzer, Raven.Database");

Index("SortableName_ru", FieldIndexing.Analyzed);
Sort("SortableName_ru", SortOptions.String);
Analyze("SortableName_ru", "Raven.Database.Indexing.Collation.Cultures.RuCollationAnalyzer, Raven.Database");
}

When querying, I then specify which sortable field to use:

var cultureInfo = CultureInfo.GetCultureInfo(parameters.CultureName);
switch (cultureInfo.TwoLetterISOLanguageName)
{
case "da":
query = query.AddOrder("SortableName_da", false);
break;
case "ru":
query = query.AddOrder("SortableName_ru", false);
break;
default:
query = query.AddOrder("SortableName_en", false);
break;
}

This defaults the the english collation analyzer, but since we have 30+ languages, I would like if this was more flexible, so I could just add the fields/analyzers needed for whatever language the document was in.

Looking at this article http://ravendb.net/docs/article-page/2.5/csharp/client-api/advanced/dynamic-fields I think I would be able to add the "SortableName_xx" based on the CultureName property of the document. But I can't figure out if (how) I would be able to set the XxCollationAnalyzer for that dynamic field, as well as specifying the SortOptions.

Is there any way to achieve this for a collection of documents with n languages?


Grisha Kotler

unread,
May 13, 2015, 9:02:32 AM5/13/15
to rav...@googlegroups.com
Hi,

You can do that by implementing an AbstractAnalyzerGenerator and putting that in the plugins folder.
In the overridden method  GenerateAnalyzerForIndexing you will need to verify the index name and according to the CultureName field return the analyzer that you want to use.



Hibernating Rhinos Ltd  cid:image001.png@01CF95E2.8ED1B7D0

Grisha Kotler l RavenDB Core Team Developer Mobile: +972-54-586-8647

Office: +972-4-622-7811 l Fax: +972-153-4-622-7811

RavenDB paving the way to "Data Made Simplehttp://ravendb.net/


--
You received this message because you are subscribed to the Google Groups "RavenDB - 2nd generation document database" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Morten Bock

unread,
May 13, 2015, 9:43:42 AM5/13/15
to rav...@googlegroups.com
Hi Grisha

Correct me if I'm wrong, but does that not set an analyzer for the entire document? 

I only want to change the analyzer for this particular dynamic field.

Oren Eini (Ayende Rahien)

unread,
May 13, 2015, 1:52:23 PM5/13/15
to ravendb
No, AbstractAnalyzerGenerator allows you to return a PerFieldAnalyzer, so you control it at that level.

Hibernating Rhinos Ltd  

Oren Eini l CEO Mobile: + 972-52-548-6969

Reply all
Reply to author
Forward
0 new messages