Czasami, gdy pracujemy nad indeksami w Sitecore, nie wystarczy użyć tylko gotowych pól, które są przechowywane w indeksach. Kiedy chcemy zredukować lub uniknąć wywołań DB podczas uruchamiania zapytania, musimy przechowywać więcej informacji w indeksie. W takich sytuacjach często używa się pola obliczane.
Pomaga nam to w łatwy sposób dodawać informacje do indeksu. Kiedy rozszerzamy dane przechowywane w computed fields, jest więcej niż pewne, że użyjemy informacji z innych elementów Sitecore. Nie jest to nic złego, ponieważ chcemy przyspieszyć wyszukiwanie tak bardzo, jak to możliwe, ale w takich sytuacjach powinniśmy być świadomi potencjalnych problemów.
Jakiemu niebezpieczeństwu możemy stawić czoła?
Gdy computed field przechowuje informacje z innego elementu Sitecore, musimy uważać, aby dane w naszych indeksach były aktualne. Gdy zmienimy coś w elemencie Sitecore, w oparciu o strategię aktualizacji indeksu, dokument indeksu dla tego elementu również zostanie zaktualizowany. W takich sytuacjach powinniśmy również pamiętać o aktualizacji dokumentów indeksowych, które korzystają ze zmienionego elementu w polach wyliczanych. W przeciwnym razie w naszym indeksie pozostaną przestarzałe dane, co może spowodować niespójne wyniki prezentowane użytkownikowi końcowemu.
Przykład problemu

Przedstawiona powyżej struktura drzewa pokazuje potencjalny problem. Mamy określone typy przedmiotów:
- Sklep samochodowy - lokalizacja, w której znajduje się sklep. Zawiera różne marki samochodów.
- Marka samochodu - element odpowiedzialny za przechowywanie danych o marce.
- Model samochodu - element zawierający informacje o modelu i cenie
Wyobraźmy sobie, że chcemy znaleźć wszystkie sklepy oferujące samochody w określonym przedziale cenowym. Opierając się na strukturze z przykładu, pole ceny istnieje tylko w pozycjach modeli samochodów. W tej sytuacji moglibyśmy przejrzeć wszystkie samochody w indeksie, wybrać te, które zawierają odpowiednią cenę dla naszego zakresu i pobrać powiązane sklepy samochodowe do wyników. Brzmi to dobrze, ale w przypadku dużej ilości pozycji może to zająć trochę czasu.
Aby to poprawić, możemy przygotować proste pole wyliczane, aby zachować zakres cen dla każdego elementu sklepu samochodowego. Nasze niestandardowe pole wyliczane sprawdzi wszystkie samochody w sklepie samochodowym i wybierze wartości minimalne i maksymalne. Wówczas nasze wyszukiwanie przejdzie tylko przez pozycje sklepu zamiast przez wszystkie samochody, które posiadamy. W tym celu tworzymy pole obliczane do przechowywania zakresu cen i przebudowujemy indeks. Na razie wygląda to dobrze, ponieważ nasz indeks został niedawno przebudowany. Należy jednak pamiętać, że gdy zaktualizujemy cenę pojedynczego samochodu w Sitecore, dokument indeksu dla tej pozycji zostanie zaktualizowany o nową wartość, ale sklep nadal będzie przechowywał stary zakres cen w swoim dokumencie indeksu. Aby uniknąć tego problemu, możemy stworzyć niestandardową strategię indeksowania, ale będzie to dość duży kawałek kodu. Zobaczmy kilka prostych sztuczek, które będzie można wykorzystać w podobnej sytuacji.
Aktualizacja pozycji indeksu
Aby uprościć sprawę, dobrze będzie obsłużyć kilka wydarzenia sitecore jak item:saved
lub publish:end
i aktualizować indeksy tylko dla określonych pozycji.
Wewnątrz obsługi zdarzenia powinniśmy odświeżyć indeks dokumentów powiązanych ze zmienionym. Po znalezieniu wszystkich wymaganych pozycji, zaktualizujmy je za pomocą jednego z proponowanych fragmentów kodu:
public static void Update(string indexName, ICollection<Item> items)
{
var index = ContentSearchManager.GetIndex(indexName);
foreach (var item in items)
{
var uniqueId = new SitecoreItemUniqueId(item.Uri);
IndexCustodian.UpdateItem(index, uniqueId);
}
}
Powyższy kod będzie aktualizował indeks dokumentów dla pozycji przekazanych w parametrach. Będzie on działał w sposób asynchroniczny, ponieważ IndexCustodian
tworzy proces aktualizacji jako zadanie Sitecore i umieszcza go w kolejce zadań. Polecam ten sposób zamiast synchronicznego. Ponieważ jeśli użylibyśmy go w Sitecore event handlers, musimy być świadomi, że działają one również w sposób synchroniczny, więc w przypadku dużej ilości elementów, może to zamrozić naszą instancję na chwilę.
Ale jeśli nadal chcesz zrobić to w sposób synchroniczny, przykład przedstawiony poniżej pokazuje, jak to osiągnąć bez IndexCustodian
:
public static void Update(string indexName, ICollection<Item> items)
{
var index = ContentSearchManager.GetIndex(indexName);
foreach (var item in items)
{
var uniqueId = new SitecoreItemUniqueId(item.Uri);
index.Update(uniqueId);
}
}
Odświeżanie pozycji indeksu
Poza aktualizacją indeksu, jesteśmy w stanie również odświeżyć element indeksu. Główna różnica polega na tym, że proces odświeżania aktualizuje indeksy dla wskazanego elementu i jego elementów potomnych. Spójrz na poniższy kod:
public static void Refresh(string indexName, Item item)
{
var index = ContentSearchManager.GetIndex(indexName);
var indexableItem = (SitecoreIndexableItem) item;
IndexCustodian.Refresh(index, indexableItem);
}
W kodzie przedstawionym powyżej użyliśmy IndexCustodian
jak w przykładzie aktualizacji, więc proces ten będzie obsługiwany asynchronicznie.
Jeśli chcemy zrobić to w sposób synchroniczny, wystarczy spojrzeć na poniższy przykład:
public static void Refresh(string indexName, Item item)
{
var index = ContentSearchManager.GetIndex(indexName);
var indexableItem = (SitecoreIndexableItem)item;
index.Refresh(indexableItem);
}
Wnioski
Computed fields
są bardzo pomocne w zakresie dostosowywania indeksów. Dają nam możliwość przechowywania dodatkowych informacji w celu przyspieszenia wyszukiwania i innych funkcji, takich jak faceting, paginacja itp. Ważne jest, aby korzystać z nich mądrze, pamiętając o wszystkich relacjach z innymi elementami i aktualizując dokumenty indeksu. W tym celu moglibyśmy przebudować indeks, ale będzie to kosztować zbyt wiele czasu i wysiłku w przypadku zmian pojedynczych elementów. Lepszym rozwiązaniem jest aktualizacja lub odświeżenie pojedynczych elementów indeksu, ale musimy być świadomi różnic między tymi dwoma procesami i używać ich w odpowiednich sytuacjach.
Dziękuję za przeczytanie tego postu, mam nadzieję, że pomoże on niektórym z was.
Chcesz porozmawiać z naszymi ekspertami o rozwiązaniach technologicznych dla Twojej firmy?
Skontaktuj się z nami już teraz!