UpdateRequestProcessorFactory / Chain etc

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

UpdateRequestProcessorFactory / Chain etc

Brian Whitman
Trying to build a simple UpdateRequestProcessor that keeps a field  
(the time of original index) when overwriting a document.

1) Can I make a updateRequestProcessor chain only work as a certain  
handler or does putting the following in my solrconfig.xml:

  <updateRequestProcessorChain>
     <processor class="myspecial.KeepIndexedDateFactory" >
    <processor class="solr.RunUpdateProcessorFactory" />
    <processor class="solr.LogUpdateProcessorFactory" />
  </updateRequestProcessorChain>

Just handle all document updates?

2) Does a UpdateRequestProcessor support inform ?




Reply | Threaded
Open this post in threaded view
|

Re: UpdateRequestProcessorFactory / Chain etc

Brian Whitman
Answered my own qs, I think:


> Trying to build a simple UpdateRequestProcessor that keeps a field  
> (the time of original index) when overwriting a document.
>
> 1) Can I make a updateRequestProcessor chain only work as a certain  
> handler or does putting the following in my solrconfig.xml:
>
> <updateRequestProcessorChain>
>    <processor class="myspecial.KeepIndexedDateFactory" >
>   <processor class="solr.RunUpdateProcessorFactory" />
>   <processor class="solr.LogUpdateProcessorFactory" />
> </updateRequestProcessorChain>
>
> Just handle all document updates?



What you have to do is:

   <requestHandler name="/update2"  
class="solr.XmlUpdateRequestHandler" >
     <lst name="invariants">
      <str name="update.processor">KeepIndexed</str>
     </lst>
   </requestHandler>

<updateRequestProcessorChain name="KeepIndexed">
     <processor class="myspecial.KeepIndexedDateFactory"/>
    <processor class="solr.RunUpdateProcessorFactory" />
    <processor class="solr.LogUpdateProcessorFactory" />
</updateRequestProcessorChain>

And then calls to /update2 will go through the chain. Calls to /update  
will not.



> 2) Does a UpdateRequestProcessor support inform ?


No, not that I can tell. And the factory won't get instantiated until  
the first time you use it.





Reply | Threaded
Open this post in threaded view
|

Re: UpdateRequestProcessorFactory / Chain etc

hossman

: And then calls to /update2 will go through the chain. Calls to /update will
: not.

Correct.  Note also that there is also a "default" attribute you can put
on one UpdateProcesserChain and then XmlUpdateRequestHandler (etc...) will use
that even if you don't tell them to use a particular chain.  If you only
define one chain, it becomes the default automaticly.

: > 2) Does a UpdateRequestProcessor support inform ?

: No, not that I can tell. And the factory won't get instantiated until the
: first time you use it.

inform, no ... but the factories should be getting instantiated during
SolrCore init, what makes you think it's not until first use?  (that would
be a bug if it's true, but a quick skim of SolrCore suggests it should be
working correctly)




-Hoss

Reply | Threaded
Open this post in threaded view
|

Re: UpdateRequestProcessorFactory / Chain etc

Shalin Shekhar Mangar
On Sun, Sep 7, 2008 at 11:00 AM, Chris Hostetter
<[hidden email]>wrote:

>
> inform, no ... but the factories should be getting instantiated during
> SolrCore init, what makes you think it's not until first use?  (that would
> be a bug if it's true, but a quick skim of SolrCore suggests it should be
> working correctly)
>

I think Brian is referring to the method
UpdateRequestProcessorFactory#getInstance(SolrQueryRequest,
SolrQueryResponse, UpdateRequestProcessor) which kinda limits you to create
it only on first request as an API. Noble pointed this out in SOLR-660 (but
after it was committed) --
https://issues.apache.org/jira/browse/SOLR-660?focusedCommentId=12617235#action_12617235

--
Regards,
Shalin Shekhar Mangar.
Reply | Threaded
Open this post in threaded view
|

Re: UpdateRequestProcessorFactory / Chain etc

Brian Whitman
Hm... I seem to be having trouble getting either the Factory or the  
Processor to do an init() for me.

The end result I'd like to see is a function that gets called only  
once, either on solr init or the first time the handler is called.  I  
can't seem to do that.

I have these two classes:

public class KeepIndexedDateFactory extends  
UpdateRequestProcessorFactory
with a getInstance method

and then

class KeepIndexedDateProcessor extends UpdateRequestProcessor
with a processAdd method


The init() on both classes is never called, ever.

The getInstance() method of the first class is called every time I add  
a doc, so I can't init stuff there.

inform() of the first class is called if I add a implements  
SolrCoreAware -- but the class I need to instantiate once is only  
needed in the second class.

I hope this makes sense -- java is not my first language.




Reply | Threaded
Open this post in threaded view
|

Re: UpdateRequestProcessorFactory / Chain etc

Brian Whitman

On Sep 7, 2008, at 2:04 PM, Brian Whitman wrote:

> Hm... I seem to be having trouble getting either the Factory or the  
> Processor to do an init() for me.
>
> The end result I'd like to see is a function that gets called only  
> once, either on solr init or the first time the handler is called.  
> I can't seem to do that.
>

Here's my code, and a solution I think works -- is there a better way  
to do this:


public class KeepIndexedDateFactory extends  
UpdateRequestProcessorFactory implements SolrCoreAware
{

   DataClassIWantToInstantiateOnce data;
   KeepIndexedDateProcessor p;

   public void inform(SolrCore core) {
     data = new DataClassIWantToInstantiateOnce(null);

   }

   public UpdateRequestProcessor getInstance(SolrQueryRequest req,  
SolrQueryResponse rsp, UpdateRequestProcessor next)
   {
     KeepIndexedDateProcessor p = new KeepIndexedDateProcessor(next);
     p.associateData(data);
     return p;
   }
}


class KeepIndexedDateProcessor extends UpdateRequestProcessor
{
   DataClassIWantToInstantiateOnce data;
   public KeepIndexedDateProcessor( UpdateRequestProcessor next) {
     super( next );
   }

   public void associateData(Data d) { data = d; }

   @Override
   public void processAdd(AddUpdateCommand cmd) throws IOException {
     SolrInputDocument doc = cmd.getSolrInputDocument();
     String id = doc.getFieldValue( "id" ).toString();
     if( id != null ) {
       SolrQuery getIndexedDatesOfId = new SolrQuery();
       getIndexedDatesOfId.setQuery("id:"+id);
       getIndexedDatesOfId.setFields("indexed");
       getIndexedDatesOfId.setRows(1);
       QueryResponse qr = data.query(getIndexedDatesOfId);
       if(qr != null) {
         if(qr.getResults() != null) {
           if(qr.getResults().size()>0) {
             Date thisIndexed =  
(Date)qr.getResults().get(0).getFieldValue("indexed");
             doc.setField("indexed", thisIndexed);
           }
         }
       }
     }
     // pass it up the chain
     super.processAdd(cmd);
   }

}

Reply | Threaded
Open this post in threaded view
|

Re: UpdateRequestProcessorFactory / Chain etc

hossman

: > Hm... I seem to be having trouble getting either the Factory or the
: > Processor to do an init() for me.

The UpdateRequestProcessor API doesn't have an init() method, but the
UpdateRequestProcessorFactory API definitely does, and i can see it
getting called.  are you sure you are overriding the method correctly?
(the code you sent was after you already got rid of your init() method so
i'm not sure) ...

  @Override
  public void init( NamedList args ) {
    // do stuff here.
  }

...the "@Override" part isn't strictly neccessary, but it will make the
compiler complain if you've got a typo in your method name or something
and it's not actually overriding the super class.

As you've already figured out however, UpdateRequestProcessorFactory can
aparently also implement SolrCoreAware and do stuff in it's inform method.

: Here's my code, and a solution I think works -- is there a better way to do
: this:

I'm not really an expert on the UpdateRequestProcessor's but what you've
got seems like it should be fine to me.




-Hoss