Mark: first off, the details matter.

Nothing in your first email mae it clear that the {!join} query you were 
refering to was not the entirety of your query param -- which is part of 
the confusion and was a significant piece of Shawn's answer.  Had you 
posted the *exact* request you were sending (with all params) and the 
full response you got, the root cause of your problem would have been a 
lot more obvious to some folks very quickly.

As shawn mentioned, the {!...} syntax involves localparams and invoking a 
nammed parser -- normaly this syntax is the *first* thig in a query 
string, and causes the *entire* string to be parsed by that parser.  this 
is why something like this should work fine for you (please confirm if 
it does not)...

  q={!join from=member_profile_doc_id to=id}language_proficiency_id_number:[30 
TO 50]

...because the "{!" at the begining of the param value tells solr to let 
that parser (in this case "join") parse the entire string, using the 
localparam options specified (from=member_profile_doc_id & to=id).  the 
"join" parser then delegates to the "lucene" parser for it's body 
(language_proficiency_id_number:[30 TO 50])

However ... when the "{!" syntax is not the first thing in the param 
value, what happens is that the default parser (lucene) is used -- the 
lucene parser has a handy feature that supports looking for the "{!" 
syntax nested inside of it ... which means you can do things like this...


  q=+(+{!prefix f=foo}bar -{!term f=yak}wak) -aaa:zzz

...however there is an important caveat to this: when the "lucene" parser 
is looking for the "{!" syntax to know when you want it to delegate to 
another parser, how does it know if/when you intended for the input to 
that nested parser to end?

Specifically, in the example above, how does it know if the input to the 
prefix parser was ment to be "bar" or "bar -{!term f=yak}wak) -aaa:zzz"

The answer is that it's conservative and assumes the input to the nested 
parser stops as soon as it sees something that looks like the end of a the 
current clause: whitespace or an open/close parent for example.

Which brings us to your specific example...

: +({!join from=member_profile_doc_id to=id}language_noun:english
:  ({!join from=member_profile_doc_id to=id}language_proficiency_id_number:30
:   {!join from=member_profile_doc_id to=id}language_proficiency_id_number:40 
:   {!join from=member_profile_doc_id to=id}language_proficiency_id_number:50))

...in this case, when the lucene parser sees the nested {!join...} parsers 
it has no problem, because it's conservative rulees about the end of the 
clauses match up with what you expect given the simple term queries.  if 
you change those individual term queries to a range query however...

+({!join from=member_profile_doc_id to=id}language_noun:english
  {!join from=member_profile_doc_id to=id}language_proficiency_id_number:[30 TO 
50])

...in this case, the lucene parser sees the "{!join} syntax and delegates 
to the join parser, but it assumes only the 
"language_proficiency_id_number:[30" portion of the input is ment for that 
parser, and hangs on to the "TO 50]" to parse ass additional clauses.  the 
join parse doesn't really care about the input, but when it delegates to 
another nested instance of the lucene parser, the input 
"language_proficiency_id_number:[30" isn't valid because it's the start of 
an unfinished range query.

Does that make sense so far?

As for the solution:

when you use the "{!foo} syntax, the local param "v" can be used to 
specify the main input to the nested parser instead of the usual 
prefix-ish syntax -- and this scopes the input un-ambiguiously...

+({!join from=member_profile_doc_id to=id v='language_noun:english'}
  {!join from=member_profile_doc_id to=id v='language_proficiency_id_number:[30 
TO 50]'})

FWIW, you can also use param derefrencing it it helps make things easier 
to read for you (and/or if you need to include nested quotes and don't 
want to deal with the escaping)...

q=+({!join from=$from to=id v=$noun} {!join from=$from to=id v=$prof)}
from=member_profile_doc_id
$noun=language_noun:english
$prof=language_proficiency_id_str:["thirty three" TO "fifty"]'




-Hoss
http://www.lucidworks.com/

Reply via email to