You are viewing a plain text version of this content. The canonical link for it is here.
Posted to solr-user@lucene.apache.org by SUJIT PAL <su...@comcast.net> on 2012/03/17 03:03:57 UTC

Any way to get reference to original request object from within Solr component?

Hello,

I have a custom component which depends on the ordering of a multi-valued parameter. Unfortunately it looks like the values do not come back in the same order as they were put in the URL. Here is some code to explain the behavior:

URL: /solr/my_custom_handler?q=something&myparam=foo&myparam=bar&myparam=baz

Inside my component's process(ResponseBuilder) method, I do the following:

public void process(ResponseBuilder rb) throws IOException {
  String[] myparams = rb.req.getParams().getParams("myparam");
  System.out.println("myparams=" + ArrayUtils.toString(myparams);
  ...
}

and I notice that the values are ordered differently than ["foo", "bar", "baz"] that I would have expected. I am guessing its because the SolrParams is a MultiMap structure, so order is destroyed on its way in.

My question is:
1) is there a setting in Solr can use to enforce ordering of multi-valued parameters? I suppose I could use a single parameter with comma-separated values, but its a bit late to do that now...
2) is it possible to use a specific SolrParams object that preserves order? If so how?
3) is it possible to get a reference to the HTTP request object from within a component? If so how?

I am on Solr version 3.2.0.

Thanks in advance for any help you can provide,

Sujit

Re: Any way to get reference to original request object from within Solr component?

Posted by SUJIT PAL <su...@comcast.net>.
Hi Hoss,

Thanks for the pointers, and sorry, it was a bug in my code (was some dead code which was alphabetizing the facet link text and also the parameters themselves indirectly by reference).

I actually ended up building a servlet and a component to print out the multi-valued parameters using HttpServletRequest.getParameterValues("myparam") and ResponseBuilder.req.getParams().getParams("myparam") respectively to isolate the problem. Both of them returned the parameters in the correct order.

So I went trolling through the code with a debugger, to observe exactly at what point the order got messed up, and found the bug.

FWIW, I am using Tomcat 5.5.

Thanks to everybody for their help, and sorry for the noise, guess I should have done the debugger thing before I threw up my hands :-).

-sujit

On Mar 19, 2012, at 6:55 PM, Chris Hostetter wrote:

> 
> : I have a custom component which depends on the ordering of a 
> : multi-valued parameter. Unfortunately it looks like the values do not 
> : come back in the same order as they were put in the URL. Here is some 
> : code to explain the behavior:
> 	...
> : and I notice that the values are ordered differently than ["foo", "bar", 
> : "baz"] that I would have expected. I am guessing its because the 
> : SolrParams is a MultiMap structure, so order is destroyed on its way in.
> 
> a) MultiMapSolrParams does not destroy order on the way in
> b) when dealing with HTTP requests, the request params actaully use an 
> instance of ServletSolrParams which is backed directly by the 
> ServletRequest.getParameterMap() -- you should get the values returned in 
> the exact order as ServletRequest.getParameterMap().get("myparam")
> 
> : 1) is there a setting in Solr can use to enforce ordering of 
> : multi-valued parameters? I suppose I could use a single parameter with 
> : comma-separated values, but its a bit late to do that now...
> 
> Should already be enforced in MultiMapSolrParams and ServletSolrParams
> 
> : 2) is it possible to use a specific SolrParams object that preserves order? If so how?
> 
> see above.
> 
> : 3) is it possible to get a reference to the HTTP request object from within a component? If so how?
> 
> not out of the box, because there is no garuntee that solr is even running 
> in a servlet container. you can subclass SolrDispatchFilter to do this if 
> you wish (note the comment in the execute() method).
> 
> My questions to you...
> 
> 1) what servlet container are you using? 
> 2) have you tested your servlet 
> container with a simple servlet (ie: eliminate solr from the equation) to 
> verify that the ServletRequest.getParameterMap() contains your request 
> values in order?
> 
> 
> if you debug this and find evidence that something in solr is re-ordering 
> the values in a MultiMapSolrParams or ServletSolrParams *PLEASE* open a 
> jira with a reproducable example .. that would definitley be an anoying 
> bug we should get to the bottom of.
> 
> 
> -Hoss


Re: Any way to get reference to original request object from within Solr component?

Posted by Chris Hostetter <ho...@fucit.org>.
: I have a custom component which depends on the ordering of a 
: multi-valued parameter. Unfortunately it looks like the values do not 
: come back in the same order as they were put in the URL. Here is some 
: code to explain the behavior:
	...
: and I notice that the values are ordered differently than ["foo", "bar", 
: "baz"] that I would have expected. I am guessing its because the 
: SolrParams is a MultiMap structure, so order is destroyed on its way in.

a) MultiMapSolrParams does not destroy order on the way in
b) when dealing with HTTP requests, the request params actaully use an 
instance of ServletSolrParams which is backed directly by the 
ServletRequest.getParameterMap() -- you should get the values returned in 
the exact order as ServletRequest.getParameterMap().get("myparam")

: 1) is there a setting in Solr can use to enforce ordering of 
: multi-valued parameters? I suppose I could use a single parameter with 
: comma-separated values, but its a bit late to do that now...

Should already be enforced in MultiMapSolrParams and ServletSolrParams

: 2) is it possible to use a specific SolrParams object that preserves order? If so how?

see above.

: 3) is it possible to get a reference to the HTTP request object from within a component? If so how?

not out of the box, because there is no garuntee that solr is even running 
in a servlet container. you can subclass SolrDispatchFilter to do this if 
you wish (note the comment in the execute() method).

My questions to you...

1) what servlet container are you using? 
2) have you tested your servlet 
container with a simple servlet (ie: eliminate solr from the equation) to 
verify that the ServletRequest.getParameterMap() contains your request 
values in order?


if you debug this and find evidence that something in solr is re-ordering 
the values in a MultiMapSolrParams or ServletSolrParams *PLEASE* open a 
jira with a reproducable example .. that would definitley be an anoying 
bug we should get to the bottom of.


-Hoss

Re: Any way to get reference to original request object from within Solr component?

Posted by SUJIT PAL <su...@comcast.net>.
Thanks Russel, thats a good idea, I think this would work too... I will try this and update the thread with details once.

-sujit

On Mar 18, 2012, at 7:11 AM, Russell Black wrote:

> One way to do this is to register a servlet filter that places the current request in a global static ThreadLocal variable, thereby making it available to your Solr component.  It's kind of a hack but would work. 
> 
> Sent from my phone
> 
> On Mar 17, 2012, at 6:53 PM, "SUJIT PAL" <su...@comcast.net> wrote:
> 
>> Thanks Pravesh,
>> 
>> Yes, converting the myparam to a single (comma-separated) field is probably the best approach, but as I mentioned, this is probably a bit too late for this to be practical in my case... 
>> 
>> The myparam parameters are facet filter queries, and so far order did not matter, since the filters were just AND-ed together and applied to the result set and facets were being returned in count order. But now the requirement is to "bubble up" the selected facets so the one is most currently selected is on the top. This was uncovered during user-acceptance testing (since the client shows only the top N facets, and the currently selected facet to disappear since its no longer within the top N facets).
>> 
>> Asking the client to switch to a single comma-separated field is an option, but its the last option at this point, so I was wondering if it was possible to switch to some other data structure, or at least get a handle to the original HTTP servlet request from within the component so I could grab the parameters from there.
>> 
>> I noticed that the /select call does preserve the order of the parameters, but that is because its probably being executed by SolrServlet, which gets its parameters from the HttpServletRequest.
>> 
>> I guess I will have to just run the request through a debugger and see where exactly the parameter order gets messed up...I'll update this thread if I find out.
>> 
>> Meanwhile, if any of you have simpler alternatives, would really appreciate knowing...
>> 
>> Thanks,
>> -sujit
>> 
>> On Mar 17, 2012, at 12:01 AM, pravesh wrote:
>> 
>>> Hi Sujit,
>>> 
>>> The Http parameters ordering is above the SOLR level. Don't think this could
>>> be controlled at SOLR level.
>>> You can append all required values in a single Http param at then break at
>>> your component level.
>>> 
>>> Regds
>>> Pravesh
>>> 
>>> --
>>> View this message in context: http://lucene.472066.n3.nabble.com/Any-way-to-get-reference-to-original-request-object-from-within-Solr-component-tp3833703p3834082.html
>>> Sent from the Solr - User mailing list archive at Nabble.com.
>> 


Re: Any way to get reference to original request object from within Solr component?

Posted by Russell Black <rb...@fold3.com>.
One way to do this is to register a servlet filter that places the current request in a global static ThreadLocal variable, thereby making it available to your Solr component.  It's kind of a hack but would work. 

Sent from my phone

On Mar 17, 2012, at 6:53 PM, "SUJIT PAL" <su...@comcast.net> wrote:

> Thanks Pravesh,
> 
> Yes, converting the myparam to a single (comma-separated) field is probably the best approach, but as I mentioned, this is probably a bit too late for this to be practical in my case... 
> 
> The myparam parameters are facet filter queries, and so far order did not matter, since the filters were just AND-ed together and applied to the result set and facets were being returned in count order. But now the requirement is to "bubble up" the selected facets so the one is most currently selected is on the top. This was uncovered during user-acceptance testing (since the client shows only the top N facets, and the currently selected facet to disappear since its no longer within the top N facets).
> 
> Asking the client to switch to a single comma-separated field is an option, but its the last option at this point, so I was wondering if it was possible to switch to some other data structure, or at least get a handle to the original HTTP servlet request from within the component so I could grab the parameters from there.
> 
> I noticed that the /select call does preserve the order of the parameters, but that is because its probably being executed by SolrServlet, which gets its parameters from the HttpServletRequest.
> 
> I guess I will have to just run the request through a debugger and see where exactly the parameter order gets messed up...I'll update this thread if I find out.
> 
> Meanwhile, if any of you have simpler alternatives, would really appreciate knowing...
> 
> Thanks,
> -sujit
> 
> On Mar 17, 2012, at 12:01 AM, pravesh wrote:
> 
>> Hi Sujit,
>> 
>> The Http parameters ordering is above the SOLR level. Don't think this could
>> be controlled at SOLR level.
>> You can append all required values in a single Http param at then break at
>> your component level.
>> 
>> Regds
>> Pravesh
>> 
>> --
>> View this message in context: http://lucene.472066.n3.nabble.com/Any-way-to-get-reference-to-original-request-object-from-within-Solr-component-tp3833703p3834082.html
>> Sent from the Solr - User mailing list archive at Nabble.com.
> 

Re: Any way to get reference to original request object from within Solr component?

Posted by SUJIT PAL <su...@comcast.net>.
Thanks Pravesh,

Yes, converting the myparam to a single (comma-separated) field is probably the best approach, but as I mentioned, this is probably a bit too late for this to be practical in my case... 

The myparam parameters are facet filter queries, and so far order did not matter, since the filters were just AND-ed together and applied to the result set and facets were being returned in count order. But now the requirement is to "bubble up" the selected facets so the one is most currently selected is on the top. This was uncovered during user-acceptance testing (since the client shows only the top N facets, and the currently selected facet to disappear since its no longer within the top N facets).

Asking the client to switch to a single comma-separated field is an option, but its the last option at this point, so I was wondering if it was possible to switch to some other data structure, or at least get a handle to the original HTTP servlet request from within the component so I could grab the parameters from there.

I noticed that the /select call does preserve the order of the parameters, but that is because its probably being executed by SolrServlet, which gets its parameters from the HttpServletRequest.

I guess I will have to just run the request through a debugger and see where exactly the parameter order gets messed up...I'll update this thread if I find out.

Meanwhile, if any of you have simpler alternatives, would really appreciate knowing...

Thanks,
-sujit

On Mar 17, 2012, at 12:01 AM, pravesh wrote:

> Hi Sujit,
> 
> The Http parameters ordering is above the SOLR level. Don't think this could
> be controlled at SOLR level.
> You can append all required values in a single Http param at then break at
> your component level.
> 
> Regds
> Pravesh
> 
> --
> View this message in context: http://lucene.472066.n3.nabble.com/Any-way-to-get-reference-to-original-request-object-from-within-Solr-component-tp3833703p3834082.html
> Sent from the Solr - User mailing list archive at Nabble.com.


Re: Any way to get reference to original request object from within Solr component?

Posted by pravesh <su...@yahoo.com>.
Hi Sujit,

The Http parameters ordering is above the SOLR level. Don't think this could
be controlled at SOLR level.
You can append all required values in a single Http param at then break at
your component level.

Regds
Pravesh

--
View this message in context: http://lucene.472066.n3.nabble.com/Any-way-to-get-reference-to-original-request-object-from-within-Solr-component-tp3833703p3834082.html
Sent from the Solr - User mailing list archive at Nabble.com.