2013-06-17 20 views
5

Ho un core con milioni di record.
Desidero aggiungere un gestore personalizzato che esegue la scansione dei documenti esistenti e aggiorna uno dei campi in base a una condizione (età> 12 per esempio).
Preferisco farlo sul lato server Solr per evitare l'invio di milioni di documenti al client e viceversa.
Stavo pensando di scrivere un plugin solr che riceverà una query e aggiornerà alcuni campi sui documenti della query (come l'eliminazione per gestore di query).
Mi chiedevo se esistono soluzioni esistenti o alternative migliori.
Cercai il web per un po 'e non sono riuscito a trovare esempi di plugin Solr che aggiornano i documenti (non è necessario estendere il gestore di aggiornamento).
Ho scritto un plug-in che usa il seguente codice che funziona bene ma non è veloce quanto mi serve.
Attualmente faccio:Come aggiornare i documenti Solr sul lato server Solr con gestore/plug-in personalizzato

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); 
} 

ma questo è molto costoso in quanto il gestore aggiornamento prendere di nuovo il documento che Possiedo già a portata di mano.
C'è un modo sicuro per aggiornare il documento lucene e scriverlo mentre si tiene conto di tutto il codice relativo Solr come cache, logica extra solr ecc.?
Stavo pensando di convertirlo in un SolrInputDocument e quindi basta aggiungere il documento tramite Solr ma prima devo convertire tutti i campi.
Grazie in anticipo, Avner

+0

Probabilmente lo sapete già, ma in Solr, l'atto di aggiornare un documento significa davvero sostituire il documento originale con un documento aggiornato contenente i valori modificati. Il solito modo di gestire le modifiche consiste nel passare dal sistema di origine all'indice, in genere in base a una data oa qualche altra indicazione; non aggiornare in qualche modo l'indice localmente. Puoi dare un po 'più di contesto per quello che stai cercando di fare? – icey502

+0

Sono a conoscenza dell'eliminazione/aggiunta di materiale. Nel mio scenario ci sono dati che esistono solo nell'indice Solr (campo calcolato). Successivamente ho bisogno di aggiungere alcuni dati in un campo per tutti i documenti che rispondono a una query basata sul campo calcolato (nell'esempio il campo "Età"). È così complesso aprire uno scrittore sul lato Solr e cambiare documenti? –

+0

Non ho affrontato questo scenario esatto, ma assumendo il "trigger" per il valore modificato (e successivo aggiornamento) è di per sé un aggiornamento dell'indice, forse questo link sarà utile: http://stackoverflow.com/questions/6593887/solr -e-custom-update-handler – icey502

risposta

0

Non sono sicuro se quanto segue migliorerà le prestazioni, ma pensavo che potesse essere d'aiuto.

Guarda SolrEntityProcessor

La sua descrizione suona molto pertinenti a ciò che si sta cercando.

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. 

Tuttavia, non sono riuscito a trovare una funzionalità pronta per incorporare la logica. Quindi, potresti dover estendere la seguente classe.

SolrEntityProcessor e il link al sourcecode

Probabilmente si può sapere, ma un paio di altri punti.

1) Fare in modo che l'intero processo sfrutti tutti i core della CPU disponibili. Rendilo multi-threaded.

2) Utilizzare la versione più recente di Solr.

3) Esperimento con due app Solr su macchine diverse con ritardo di rete minimo. Questa sarebbe una scelta difficile:

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

4) Tweak Solr cache in un modo che si applica al vostro caso d'uso e particolare implementazione.

5) Un paio di maggiori risorse: Solr Performance Problems e SolrPerformanceFactors

Speranza che aiuta. Fammi sapere le statistiche nonostante questa risposta. Sono curioso e le tue informazioni potrebbero aiutare qualcuno più tardi.

+0

Grazie per il vostro impegno, verificherò le vostre indicazioni e aggiornerò una volta che raggiungerò le conclusioni finali (incluso il premio). @phani –

0

Per indicare dove inserire la logica personalizzata, suggerirei di dare un'occhiata a the SolrEntityProcessor in congiunzione with Solr's ScriptTransformer.

ScriptTransformer consente di calcolare ogni entità dopo che è stata estratta dall'origine di un import di dati, manipolarla e aggiungere valori di campo personalizzati prima che la nuova entità venga scritta in solr.

Un campione dati-config.xml potrebbe assomigliare a questo

<?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> 

Come si può vedere, si può eseguire una trasformazione dei dati che ti piace e sono esprimibili in javascript. Quindi questo sarebbe un buon punto per esprimere la tua logica e le tue trasformazioni.

Si dice un vincolo forse age > 12. Vorrei gestirlo tramite l'attributo query del SolrEntityProcessor. Potresti scrivere query=age:[* TO 12] in modo che solo i record con un'età fino a 12 vengano letti per l'aggiornamento.

+0

Grazie per il tuo impegno, verificherò le tue indicazioni e aggiornerò una volta che avrò raggiunto le conclusioni finali (incluso il premio). @cheffe –