2013-06-17 5 views
5

Mam rdzeń z milionami rekordów.
Chcę dodać niestandardową procedurę obsługi, która skanuje istniejące dokumenty i aktualizuje jedno z pól na podstawie warunku (na przykład wiek> 12).
Wolę robić to po stronie serwera Solr, aby uniknąć wysyłania milionów dokumentów do klienta iz powrotem.
Zastanawiam się nad napisaniem wtyczki solr, która otrzyma zapytanie i zaktualizuje niektóre pola w dokumentach zapytania (np. Usuwanie przez program obsługi zapytań).
Zastanawiam się, czy istnieją istniejące rozwiązania lub lepsze alternatywy.
Przez pewien czas szukałem w Internecie i nie mogłem znaleźć przykładów wtyczek Solr, które aktualizują dokumenty (nie muszę rozszerzać programu obsługi aktualizacji).
Napisałem wtyczkę, która używa następującego kodu, który działa dobrze, ale nie jest tak szybki, jak potrzebuję.
Obecnie robię:Jak aktualizować dokumenty Solr po stronie serwera Solr za pomocą niestandardowego programu obsługi/wtyczki

AddUpdateCommand addUpdateCommand = new AddUpdateCommand(solrQueryRequest); 
DocIterator iterator = docList.iterator(); 
SolrIndexSearcher indexReader = solrQueryRequest.getSearcher(); 
while (iterator.hasNext()) { 
    Document document = indexReader.doc(iterator.nextDoc()); 
    SolrInputDocument solrInputDocument = new SolrInputDocument(); 
    addUpdateCommand.clear(); 
    addUpdateCommand.solrDoc = solrInputDocument; 
    addUpdateCommand.solrDoc.setField("id", document.get("id")); 
    addUpdateCommand.solrDoc.setField("my_updated_field", new_value); 
    updateRequestProcessor.processAdd(addUpdateCommand); 
} 

Ale to jest bardzo drogie, ponieważ obsługi Aktualizacja pobierze ponownie dokument, który już trzymać w ręku.
Czy istnieje bezpieczny sposób aktualizowania dokumentu Lucou i zapisywania go z uwzględnieniem wszystkich kodów związanych z Solr, takich jak pamięci podręczne, dodatkowe logiki solr itp.?
Zastanowiłem się nad konwersją do SolrInputDocument, a następnie po prostu dodałem dokument do Solr, ale najpierw muszę przekonwertować wszystkie pola.
Dzięki z góry, Avner

+0

Prawdopodobnie już to wiesz, ale w Solr akt aktualizacji dokumentu naprawdę oznacza zastąpienie oryginalnego dokumentu zaktualizowanym dokumentem zawierającym zmienione wartości. Najczęstszym sposobem obsługi zmian jest przejście z systemu źródłowego do indeksu, zwykle w oparciu o datę lub inne wskazanie; nie aktualizować lokalnie indeksu. Czy możesz podać nieco więcej kontekstu dla tego, co próbujesz zrobić? – icey502

+0

Jestem świadomy usuwania/dodawania rzeczy. W moim scenariuszu istnieją dane, które istnieją tylko w indeksie Solr (pole obliczeniowe). Później muszę dodać trochę danych do pola dla wszystkich dokumentów, które odpowiadają na zapytanie oparte na polach obliczeniowych (w przykładzie pole "Wiek"). Czy to skomplikowane, aby otworzyć pisarza po stronie Solr i zmienić dokumenty? –

+0

Nie miałem do czynienia z tym dokładnym scenariuszem, ale zakładając, że "wyzwalacz" dla zmienionej wartości (i kolejna aktualizacja) sam jest aktualizacją indeksu, może ten link będzie pomocny: http://stackoverflow.com/questions/6593887/solr -and-custom-update-handler – icey502

Odpowiedz

0

Nie jestem pewien, czy następujące zamierza poprawić wydajność, ale pomyślałem, że może pomóc.

Spójrz na SolrEntityProcessor

jego opis brzmi bardzo istotne dla tego, co szukasz.

This EntityProcessor imports data from different Solr instances and cores. 
The data is retrieved based on a specified (filter) query. 
This EntityProcessor is useful in cases you want to copy your Solr index 
and slightly want to modify the data in the target index. 
In some cases Solr might be the only place were all data is available. 

Jednak nie udało mi się znaleźć gotowej funkcji do osadzenia logiki. Być może będziesz musiał rozszerzyć następującą klasę.

SolrEntityProcessor a link do sourcecode

może zapewne wiecie, ale kilka innych punktów.

1) Upewnij się, że cały proces wykorzystuje wszystkie dostępne rdzenie procesora. Spraw, aby był wielowątkowy.

2) Użyj najnowszej wersji Solr.

3) Eksperymentuj z dwoma aplikacjami Solr na różnych maszynach z minimalnym opóźnieniem w sieci. To byłoby trudne rozmowy:

same machine, two processes VS two machines, more cores, but network overhead. 

4) Tweak Solr cache w sposób, który ma zastosowanie do korzystania przez Państwa przypadku i konkretnej realizacji.

5) Kilka więcej środków: Solr Performance Problems i SolrPerformanceFactors

Nadzieję, że to pomaga. Daj mi znać statystyki pomimo tej odpowiedzi. Jestem ciekawy, a twoje informacje mogą pomóc komuś później.

+0

Dziękuję za pochwałę. Sprawdzę Twoje wskazówki i zaktualizuję je, kiedy dojdę do ostatecznych wniosków (w tym do nagrody). @phani –

0

Aby wskazać, gdzie umieścić niestandardową logikę, sugeruję, aby spojrzeć na the SolrEntityProcessor w połączeniu with Solr's ScriptTransformer.

Funkcja ScriptTransformer umożliwia obliczenie każdej jednostki po jej wyodrębnieniu ze źródła danych, manipulowanie nią i dodawanie niestandardowych wartości pól, zanim nowa jednostka zostanie zapisana w formacie solr.

Próbkę danych config.xml mógłby wyglądać następująco

<?xml version="1.0" encoding="UTF-8" ?> 
<dataConfig> 

    <script> 
    <![CDATA[ 
     function calculateValue(row)  { 
      row.put("CALCULATED_FIELD", "The age is: " + row.get("age")); 
      return row; 
     } 
    ]]> 
    </script> 

    <document> 
    <entity name="sep" processor="SolrEntityProcessor" 
     url="http://localhost:8080/solr/your-core-name" 
     query="*:*" 
     wt="javabin" 
     transformer="script:calculateValue"> 
      <field column="ID" name="id" /> 
      <field column="AGE" name="age" /> 
      <field column="CALCULATED_FIELD" name="update_field" /> 
    </entity> 
    </document> 
</dataConfig> 

Jak widać, można wykonać dowolną transformację danych lubisz i to wyrazić w javascript. Byłby to dobry punkt do wyrażenia logiki i transformacji.

Mówisz, że jedno ograniczenie może być age > 12. Poradziłbym sobie z tym poprzez atrybut query SolrEntityProcessor. Możesz napisać query=age:[* TO 12], aby tylko aktualizacje z wiekiem do 12 były odczytywane.

+0

Dziękuję za pochwałę. Sprawdzę Twoje wskazówki i zaktualizuję je, gdy tylko osiągnę ostateczne wnioski (w tym nagrodę). @cheffe –