[
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]