[ 
https://issues.apache.org/jira/browse/SOLR-18524?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18125313#comment-18125313
 ] 

David Smiley commented on SOLR-18524:
-------------------------------------

"q.alt" then becomes technically "alt" when viewed by the query parser of "q", 
due to the hoisting I proposed.  For consistency anyway, not because I think 
the parameter deserves it otherwise.  I don't love that change specifically but 
why not.

If I might take this local-param hoisting farther a little, I'd make "q.type" 
be a preferred substitute for "defType" since "type" happens to be the 
little-known local-param that chooses the query parser when there's 
local-params. 

I don't think the hoisting idea should be taken further to "fq" as its 
multi-valued; each fq is really its own thing.

> Honor q.op only as a local-param, not as a request param
> --------------------------------------------------------
>
>                 Key: SOLR-18524
>                 URL: https://issues.apache.org/jira/browse/SOLR-18524
>             Project: Solr
>          Issue Type: Improvement
>          Components: query parsers
>            Reporter: David Smiley
>            Priority: Major
>
> h3. What
> {{q.op}} (default operator for the implicit operator between clauses) should 
> be honored only when given as a local-param of the query it applies to, e.g. 
> {{q={!q.op=AND}solr rocks}} or {{fq={!edismax q.op=AND qf=title}foo bar}}. A 
> request-level {{q.op}} (including one set in a request handler's 
> defaults/appends/invariants) should no longer be consulted by query parsers.
> h3. Why
> *1. A request-level q.op silently changes the meaning of every {{lucene}} 
> query in the request, not just the user's.*
> Parsers fetch it via {{QParser.getParam}}, which falls back from local params 
> to request params. So a request-level {{q.op=AND}} reaches every query parsed 
> in that request, not just {{q}}: each {{fq}}, {{facet.query}}, JSON Facet 
> domain filters and queries, {{bq}}/{{boost}}, nested 
> {{\{!parent\}}}/{{\{!join\}}} sub-queries, and so on. Readers include:
> * {{LuceneQParser}} — 
> {{lparser.setDefaultOperator(QueryParsing.parseOP(getParam(QueryParsing.OP)))}}
> * {{ComplexPhraseQParserPlugin}} — same via {{getParam}}
> * {{ExtendedDismaxQParser}} and {{SimpleQParserPlugin}} — 
> {{SolrParams.wrapDefaults(localParams, params)}}
> * {{SolrPluginUtils.parseMinShouldMatch}} — derives the {{mm}} default from it
> Operators might set {{q.op=AND}} in solrconfig.xml to tune how *user* queries 
> match. In practice this comes with a comment like the one in a config I 
> maintain: {{<str name="q.op">AND</str><!-- affects filter queries too, 
> unfortunately :-( -->}}. That "unfortunately" is the bug.
> *2. Queries generated by programs need meanings that don't depend on context.*
> Filters and other non-{{q}} queries are usually built by application code, 
> not typed by users. The same reasoning was given for closing SOLR-15345 as 
> Won't Fix: {{defType}} intentionally applies only to {{q}}. Yet today the 
> meaning of a generated {{fq=a b}} depends on a parameter its author may not 
> control and may not even know is set. Defensive client code has to avoid 
> relying on the implicit operator everywhere: always spell out {{AND}}/{{OR}}, 
> never emit bare SHOULD clauses, or wrap every query in {{\{!lucene 
> q.op=OR\}}}. Equivalent query strings shouldn't need that care.
> *3. It's inconsistent with {{defType}}.*
> {{defType}} applies to {{q}} only, and {{q.op}} is closely related to it. A 
> user who reasonably assumes they work the same way gets surprised.
> *4. It keeps producing bugs that only show up in queries it was never meant 
> for.*
> * SOLR-12212: a parenthesized pure-NOT {{fq}} breaks under {{q.op=AND}}
> * SOLR-17796: a tagged {{\{!collapse\}}} {{fq}} fails under {{q.op=AND}}
> * SOLR-5161: distributed MoreLikeThis misbehaves under {{q.op=AND}}
> All of these come from a request-level {{q.op}} reaching a query other than 
> {{q}}.
> *5. The scoped alternative already exists and is the clearer form.*
> Local-params make the operator part of the query it governs: 
> {{\{!q.op=AND\}…}}, {{\{!edismax q.op=AND …\}}}. A sub-query parser doesn't 
> inherit its parent's local params, so it stays truly local — it neither leaks 
> inward to nested queries nor outward to sibling ones.
> h3. Proposal
> * All request params starting with "q." (q dot) are _hoisted_ into 
> local-params when parsing "q" specifically, but without the "q." prefix.  
> Actual/literal local-params take precedence.  Thus a request "q.op" becomes 
> seen as an "op" local-param when "q" is parsed but not anywhere else.
> * Query parsers read {{op}} from their local params only: {{LuceneQParser}}, 
> {{ComplexPhraseQParserPlugin}}, {{ExtendedDismaxQParser}}, 
> {{SimpleQParserPlugin}}, and the {{mm}} default in 
> {{SolrPluginUtils.parseMinShouldMatch}}.  Gate this on luceneMatchVersion.
> * Update the Ref Guide (standard, edismax, dismax, and simple parser pages; 
> local-params page) and the major-version upgrade notes. Migration for a 
> handler-level default: e.g. {{q=\{!q.op=AND v=$qq\}}} with the user's query 
> in {{qq}}, or {{q.op}} in the local params the client already sends.
> Perhaps "df" should be similar.  I'm in favor of that; separate issue.
> 🤖 This issue was drafted with AI assistance (Claude Code).



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to