Get Item in all languages in which it has a version
Asked Answered
E

2

6

Say we have an Item Product(which has versions in en, jp, zh and 0 versions in ru). How can I get this item in en, jp and zh and not in ru.

I tried the below code.

Item tempItem = Sitecore.Context.Database.GetItem(tempID);
foreach (var itemLanguage in tempItem.Languages)
{
  //Do Something
}

Here tempItem.Languages is returning all four languages where I was expecting only three as ru does not have versions.

Is it the correct way to achieve this?

Enumerate answered 7/4, 2014 at 14:43 Comment(0)
I
9

You need to check the versioncount of the returned items. There are probably better ways to achieve this, but following your own code example, it would look something like this:

Item tempItem = Sitecore.Context.Database.GetItem(tempID);
foreach (var itemLanguage in tempItem.Languages)
{
    var item = tempItem.Database.GetItem(tempItem.ID, itemLanguage);
    if (item.Versions.Count > 0)
    {
        // do something. If there is no "ru" version, this will be 0
    }
}
Iorgos answered 7/4, 2014 at 15:11 Comment(0)
S
6

I ran an experiment to get a list of languages with the number of versions for items with varying numbers of children to check how expensive this is on the system.

The script below returns a list with the names of languages which have versions for the item.

public static List<string> LanguagesWithContent(this Item item)
{
    var result = ItemManager.GetContentLanguages(item).Select(lang => new {
        lang.Name,
        Versions = ItemManager.GetVersions(item, lang).Count
        //this is better than db.GetItem(item.ID, lang).Versions.Count      
    }).Where(t => t.Versions > 0).Select(t => t.Name).ToList();
    return result;
}

Benchmarking performance

First Load using GetVersions - when data is not from cache

  • 0.7298ms to get Version Counts with 8 language versions. Time to load item: 9.3041ms. Langs: es-ES, es-MX, sv-SE, en, it-IT, pt-BR, fr-FR, de-DE
  • 0.0448ms to get Version Counts with 7 language versions. Time to load item: 2.0039ms. Langs: es-ES, es-MX, en, it-IT, fr-FR, de-DE, ro-RO
  • 0.0334ms to get Version Counts with 6 language versions. Time to load item: 3.145ms. Langs: es-ES, es-MX, en, it-IT, fr-FR, de-DE
  • 0.0307ms to get Version Counts with 5 language versions. Time to load item: 1.5976ms. Langs: es-MX, en, it-IT, fr-FR, de-DE
  • 0.0353ms to get Version Counts with 4 language versions. Time to load item: 10.2764ms. Langs: en, de-DE, ja-JP, da
  • 0.0258ms to get Version Counts with 3 language versions. Time to load item: 1.9507ms. Langs: en, de-DE, ja-JP
  • 0.0193ms to get Version Counts with 2 language versions. Time to load item: 2.0533ms. Langs: en, de-DE
  • 0.0201ms to get Version Counts with 1 language versions. Time to load item: 4.7689ms. Langs: en

Repeat 1st Load experiment, using GetItem instead of GetVersions

conclusion: it's better to use ItemManager.GetVersions(item, lang).Count than db.GetItem(item.ID, lang).Versions.Count to get the list of language versions an item contains.

  • 3.4936ms to get Version Counts with 8 language versions. Time to load item: 8.9118ms. Langs: es-ES, es-MX, sv-SE, en, it-IT, pt-BR, fr-FR, de-DE
  • 0.9966ms to get Version Counts with 7 language versions. Time to load item: 1.6489ms. Langs: es-ES, es-MX, en, it-IT, fr-FR, de-DE, ro-RO
  • 1.0875ms to get Version Counts with 6 language versions. Time to load item: 3.1538ms. Langs: es-ES, es-MX, en, it-IT, fr-FR, de-DE
  • 0.5891ms to get Version Counts with 5 language versions. Time to load item: 1.4402ms. Langs: es-MX, en, it-IT, fr-FR, de-DE
  • 2.2096ms to get Version Counts with 4 language versions. Time to load item: 9.8701ms. Langs: en, de-DE, ja-JP, da
  • 0.9255ms to get Version Counts with 3 language versions. Time to load item: 2.5175ms. Langs: en, de-DE, ja-JP
  • 0.7606ms to get Version Counts with 2 language versions. Time to load item: 2.2407ms. Langs: en, de-DE
  • 1.9032ms to get Version Counts with 1 language versions. Time to load item: 5.0206ms. Langs: en

    Subsequent loads - item is cached already

    using ItemManager.GetVersions(item, lang) in this case. GetItem should in theory give similar results since subsequent loads leverage cache.

  • 0.569ms to get Version Counts with 8 language versions. Time to load item: 0.0372ms. Langs: es -ES, es-MX, sv-SE, en, it-IT, pt-BR, fr-FR, de-DE
  • 0.0429ms to get Version Counts with 7 language versions. Time to load item: 0.0475ms. Langs: es-ES, es-MX, en, it-IT, fr-FR, de-DE, ro-RO
  • 0.025ms to get Version Counts with 6 language versions. Time to load item: 0.0247ms. Langs: es-ES, es-MX, en, it-IT, fr-FR, de-DE
  • 0.0239ms to get Version Counts with 5 language versions. Time to load item: 0.0201ms. Langs: es-MX, en, it-IT, fr-FR, de-DE
  • 0.0342ms to get Version Counts with 4 language versions. Time to load item: 0.0216ms. Langs: en, de-DE, ja-JP, da
  • 0.0258ms to get Version Counts with 3 language versions. Time to load item: 0.0197ms. Langs: en, de-DE, ja-JP
  • 0.0228ms to get Version Counts with 2 language versions. Time to load item: 0.019ms. Langs: en, de-DE
  • 0.0228ms to get Version Counts with 1 language versions. Time to load item: 0.0178ms. Langs: en
Strepitous answered 10/7, 2015 at 23:28 Comment(3)
Are your benchmark results averages of x runs? Or did you measure each test just once? The numbers you listed look strange.Majolica
this is a snapshot of a single run, not an average. Though i did run it multiple times to check if the numbers are consistent.Strepitous
It's better to iterate over db.GetLanguages() than item.GetLanguages(). They both return the same list of languages which are in use on your system (in /sitecore/system/languages) but item.GetLanguages is much slower. I ran 100 iterations of each and db.GetLanguages() took 0.2ms while item.GetLanguages() took 387.3ms. Don't iterate through Sitecore.Globalization.LanguageDefinitions.Definitions - it returns a full list of known language definitions (131 in my case)Strepitous

© 2022 - 2024 — McMap. All rights reserved.