mirror of https://github.com/apache/lucene.git
SOLR-10423: Disable graph query production via schema configuration <fieldtype ... enableGraphQueries="false">. This fixes broken queries for ShingleFilter-containing query-time analyzers when request param sow=false.
This commit is contained in:
parent
ef8126e5ea
commit
dbd22a6ada
|
@ -215,6 +215,10 @@ Bug Fixes
|
|||
|
||||
* SOLR-10404: The fetch() streaming expression wouldn't work if a value included query syntax chars (like :+-).
|
||||
Fixed, and enhanced the generated query to not pollute the queryCache. (David Smiley)
|
||||
|
||||
* SOLR-10423: Disable graph query production via schema configuration <fieldtype ... enableGraphQueries="false">.
|
||||
This fixes broken queries for ShingleFilter-containing query-time analyzers when request param sow=false.
|
||||
(Steve Rowe)
|
||||
|
||||
================== 6.5.0 ==================
|
||||
|
||||
|
|
|
@ -52,12 +52,13 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
|
|||
|
||||
@Override
|
||||
protected Query newFieldQuery(Analyzer analyzer, String field, String queryText,
|
||||
boolean quoted, boolean fieldAutoGenPhraseQueries) throws SyntaxError {
|
||||
boolean quoted, boolean fieldAutoGenPhraseQueries, boolean fieldEnableGraphQueries)
|
||||
throws SyntaxError {
|
||||
setAutoGenerateMultiTermSynonymsPhraseQuery(fieldAutoGenPhraseQueries || getAutoGeneratePhraseQueries());
|
||||
// Don't auto-quote graph-aware field queries
|
||||
boolean treatAsQuoted = getSplitOnWhitespace()
|
||||
? (quoted || fieldAutoGenPhraseQueries || getAutoGeneratePhraseQueries()) : quoted;
|
||||
return super.newFieldQuery(analyzer, field, queryText, treatAsQuoted, false);
|
||||
return super.newFieldQuery(analyzer, field, queryText, treatAsQuoted, false, fieldEnableGraphQueries);
|
||||
}
|
||||
|
||||
// * Query ::= ( Clause )*
|
||||
|
|
|
@ -76,12 +76,13 @@ public class QueryParser extends SolrQueryParserBase {
|
|||
|
||||
@Override
|
||||
protected Query newFieldQuery(Analyzer analyzer, String field, String queryText,
|
||||
boolean quoted, boolean fieldAutoGenPhraseQueries) throws SyntaxError {
|
||||
boolean quoted, boolean fieldAutoGenPhraseQueries, boolean fieldEnableGraphQueries)
|
||||
throws SyntaxError {
|
||||
setAutoGenerateMultiTermSynonymsPhraseQuery(fieldAutoGenPhraseQueries || getAutoGeneratePhraseQueries());
|
||||
// Don't auto-quote graph-aware field queries
|
||||
boolean treatAsQuoted = getSplitOnWhitespace()
|
||||
? (quoted || fieldAutoGenPhraseQueries || getAutoGeneratePhraseQueries()) : quoted;
|
||||
return super.newFieldQuery(analyzer, field, queryText, treatAsQuoted, false);
|
||||
return super.newFieldQuery(analyzer, field, queryText, treatAsQuoted, false, fieldEnableGraphQueries);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -437,10 +437,14 @@ public abstract class SolrQueryParserBase extends QueryBuilder {
|
|||
}
|
||||
|
||||
protected Query newFieldQuery(Analyzer analyzer, String field, String queryText,
|
||||
boolean quoted, boolean fieldAutoGenPhraseQueries) throws SyntaxError {
|
||||
boolean quoted, boolean fieldAutoGenPhraseQueries, boolean fieldEnableGraphQueries)
|
||||
throws SyntaxError {
|
||||
BooleanClause.Occur occur = operator == Operator.AND ? BooleanClause.Occur.MUST : BooleanClause.Occur.SHOULD;
|
||||
return createFieldQuery(analyzer, occur, field, queryText,
|
||||
setEnableGraphQueries(fieldEnableGraphQueries);
|
||||
Query query = createFieldQuery(analyzer, occur, field, queryText,
|
||||
quoted || fieldAutoGenPhraseQueries || autoGeneratePhraseQueries, phraseSlop);
|
||||
setEnableGraphQueries(true); // reset back to default
|
||||
return query;
|
||||
}
|
||||
|
||||
|
||||
|
@ -632,8 +636,10 @@ public abstract class SolrQueryParserBase extends QueryBuilder {
|
|||
Query subq;
|
||||
if (ft.isTokenized() && sfield.indexed()) {
|
||||
boolean fieldAutoGenPhraseQueries = ft instanceof TextField && ((TextField)ft).getAutoGeneratePhraseQueries();
|
||||
boolean fieldEnableGraphQueries = ft instanceof TextField && ((TextField)ft).getEnableGraphQueries();
|
||||
|
||||
subq = newFieldQuery(getAnalyzer(), sfield.getName(), rawq.getJoinedExternalVal(),
|
||||
false, fieldAutoGenPhraseQueries);
|
||||
false, fieldAutoGenPhraseQueries, fieldEnableGraphQueries);
|
||||
booleanBuilder.add(subq, BooleanClause.Occur.SHOULD);
|
||||
} else {
|
||||
for (String externalVal : rawq.getExternalVals()) {
|
||||
|
@ -949,7 +955,8 @@ public abstract class SolrQueryParserBase extends QueryBuilder {
|
|||
// delegate to type for everything except tokenized fields
|
||||
if (ft.isTokenized() && sf.indexed()) {
|
||||
boolean fieldAutoGenPhraseQueries = ft instanceof TextField && ((TextField)ft).getAutoGeneratePhraseQueries();
|
||||
return newFieldQuery(getAnalyzer(), field, queryText, quoted, fieldAutoGenPhraseQueries);
|
||||
boolean fieldEnableGraphQueries = ft instanceof TextField && ((TextField)ft).getEnableGraphQueries();
|
||||
return newFieldQuery(getAnalyzer(), field, queryText, quoted, fieldAutoGenPhraseQueries, fieldEnableGraphQueries);
|
||||
} else {
|
||||
if (raw) {
|
||||
return new RawQuery(sf, queryText);
|
||||
|
@ -960,7 +967,7 @@ public abstract class SolrQueryParserBase extends QueryBuilder {
|
|||
}
|
||||
|
||||
// default to a normal field query
|
||||
return newFieldQuery(getAnalyzer(), field, queryText, quoted, false);
|
||||
return newFieldQuery(getAnalyzer(), field, queryText, quoted, false, true);
|
||||
}
|
||||
|
||||
// Assumption: quoted is always false
|
||||
|
@ -993,7 +1000,9 @@ public abstract class SolrQueryParserBase extends QueryBuilder {
|
|||
if (ft.isTokenized() && sf.indexed()) {
|
||||
String queryText = queryTerms.size() == 1 ? queryTerms.get(0) : String.join(" ", queryTerms);
|
||||
boolean fieldAutoGenPhraseQueries = ft instanceof TextField && ((TextField)ft).getAutoGeneratePhraseQueries();
|
||||
return newFieldQuery(getAnalyzer(), field, queryText, false, fieldAutoGenPhraseQueries);
|
||||
boolean fieldEnableGraphQueries = ft instanceof TextField && ((TextField)ft).getEnableGraphQueries();
|
||||
return newFieldQuery
|
||||
(getAnalyzer(), field, queryText, false, fieldAutoGenPhraseQueries, fieldEnableGraphQueries);
|
||||
} else {
|
||||
if (raw) {
|
||||
return new RawQuery(sf, queryTerms);
|
||||
|
@ -1025,7 +1034,7 @@ public abstract class SolrQueryParserBase extends QueryBuilder {
|
|||
|
||||
// default to a normal field query
|
||||
String queryText = queryTerms.size() == 1 ? queryTerms.get(0) : String.join(" ", queryTerms);
|
||||
return newFieldQuery(getAnalyzer(), field, queryText, false, false);
|
||||
return newFieldQuery(getAnalyzer(), field, queryText, false, false, true);
|
||||
}
|
||||
|
||||
protected boolean isRangeShouldBeProtectedFromReverse(String field, String part1){
|
||||
|
|
|
@ -833,7 +833,8 @@ public abstract class FieldType extends FieldProperties {
|
|||
|
||||
private static final String POSTINGS_FORMAT = "postingsFormat";
|
||||
private static final String DOC_VALUES_FORMAT = "docValuesFormat";
|
||||
private static final String AUTO_GENERATE_PHRASE_QUERIES = "autoGeneratePhraseQueries";
|
||||
protected static final String AUTO_GENERATE_PHRASE_QUERIES = "autoGeneratePhraseQueries";
|
||||
protected static final String ENABLE_GRAPH_QUERIES = "enableGraphQueries";
|
||||
private static final String ARGS = "args";
|
||||
private static final String POSITION_INCREMENT_GAP = "positionIncrementGap";
|
||||
|
||||
|
@ -856,6 +857,7 @@ public abstract class FieldType extends FieldProperties {
|
|||
}
|
||||
if (this instanceof TextField) {
|
||||
namedPropertyValues.add(AUTO_GENERATE_PHRASE_QUERIES, ((TextField) this).getAutoGeneratePhraseQueries());
|
||||
namedPropertyValues.add(ENABLE_GRAPH_QUERIES, ((TextField) this).getEnableGraphQueries());
|
||||
}
|
||||
namedPropertyValues.add(getPropertyName(INDEXED), hasProperty(INDEXED));
|
||||
namedPropertyValues.add(getPropertyName(STORED), hasProperty(STORED));
|
||||
|
|
|
@ -41,6 +41,7 @@ import org.apache.solr.uninverting.UninvertingReader.Type;
|
|||
*/
|
||||
public class TextField extends FieldType {
|
||||
protected boolean autoGeneratePhraseQueries;
|
||||
protected boolean enableGraphQueries;
|
||||
|
||||
/**
|
||||
* Analyzer set by schema for text types to use when searching fields
|
||||
|
@ -69,9 +70,15 @@ public class TextField extends FieldType {
|
|||
} else {
|
||||
autoGeneratePhraseQueries = true;
|
||||
}
|
||||
String autoGeneratePhraseQueriesStr = args.remove("autoGeneratePhraseQueries");
|
||||
String autoGeneratePhraseQueriesStr = args.remove(AUTO_GENERATE_PHRASE_QUERIES);
|
||||
if (autoGeneratePhraseQueriesStr != null)
|
||||
autoGeneratePhraseQueries = Boolean.parseBoolean(autoGeneratePhraseQueriesStr);
|
||||
|
||||
enableGraphQueries = true;
|
||||
String enableGraphQueriesStr = args.remove(ENABLE_GRAPH_QUERIES);
|
||||
if (enableGraphQueriesStr != null)
|
||||
enableGraphQueries = Boolean.parseBoolean(enableGraphQueriesStr);
|
||||
|
||||
super.init(schema, args);
|
||||
}
|
||||
|
||||
|
@ -93,6 +100,10 @@ public class TextField extends FieldType {
|
|||
public boolean getAutoGeneratePhraseQueries() {
|
||||
return autoGeneratePhraseQueries;
|
||||
}
|
||||
|
||||
public boolean getEnableGraphQueries() {
|
||||
return enableGraphQueries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SortField getSortField(SchemaField field, boolean reverse) {
|
||||
|
|
|
@ -1080,7 +1080,8 @@ public class ExtendedDismaxQParser extends QParser {
|
|||
|
||||
@Override
|
||||
protected Query newFieldQuery(Analyzer analyzer, String field, String queryText,
|
||||
boolean quoted, boolean fieldAutoGenPhraseQueries) throws SyntaxError {
|
||||
boolean quoted, boolean fieldAutoGenPhraseQueries, boolean enableGraphQueries)
|
||||
throws SyntaxError {
|
||||
Analyzer actualAnalyzer;
|
||||
if (removeStopFilter) {
|
||||
if (nonStopFilterAnalyzerPerField == null) {
|
||||
|
@ -1093,7 +1094,7 @@ public class ExtendedDismaxQParser extends QParser {
|
|||
} else {
|
||||
actualAnalyzer = parser.getReq().getSchema().getFieldType(field).getQueryAnalyzer();
|
||||
}
|
||||
return super.newFieldQuery(actualAnalyzer, field, queryText, quoted, fieldAutoGenPhraseQueries);
|
||||
return super.newFieldQuery(actualAnalyzer, field, queryText, quoted, fieldAutoGenPhraseQueries, enableGraphQueries);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -467,7 +467,14 @@
|
|||
|
||||
<fieldType name="currency" class="solr.CurrencyField" currencyConfig="currency.xml" multiValued="false"/>
|
||||
|
||||
|
||||
<fieldType name="shingle23" class="solr.TextField" enableGraphQueries="false" multiValued="true">
|
||||
<analyzer>
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.ShingleFilterFactory" minShingleSize="2" maxShingleSize="3"
|
||||
tokenSeparator="_" outputUnigrams="false"/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
|
||||
<field name="id" type="string" indexed="true" stored="true" multiValued="false" required="true"/>
|
||||
<field name="signatureField" type="string" indexed="true" stored="false"/>
|
||||
<field name="uuid" type="uuid" stored="true"/>
|
||||
|
@ -568,6 +575,8 @@
|
|||
<field name="uniq2" type="string" indexed="true" stored="true" multiValued="true"/>
|
||||
<field name="uniq3" type="string" indexed="true" stored="true"/>
|
||||
<field name="nouniq" type="string" indexed="true" stored="true" multiValued="true"/>
|
||||
|
||||
<field name="shingle23" type="shingle23" indexed="true" stored="true"/>
|
||||
|
||||
|
||||
<!--
|
||||
|
|
|
@ -93,6 +93,7 @@ public class TestExtendedDismaxParser extends SolrTestCaseJ4 {
|
|||
assertU(adoc("id", "70", "text_sw", "hair"));
|
||||
assertU(adoc("id", "71", "text_sw", "ties"));
|
||||
assertU(adoc("id", "72", "text_sw", "wifi ATM"));
|
||||
assertU(adoc("id", "73", "shingle23", "A B X D E"));
|
||||
assertU(commit());
|
||||
}
|
||||
|
||||
|
@ -1946,4 +1947,21 @@ public class TestExtendedDismaxParser extends SolrTestCaseJ4 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShingleQueries() throws Exception {
|
||||
ModifiableSolrParams params = new ModifiableSolrParams();
|
||||
params.add("sow", "false");
|
||||
params.add("defType", "edismax");
|
||||
|
||||
try (SolrQueryRequest req = req(params)) {
|
||||
QParser qParser = QParser.getParser("shingle23:(A B C)", req);
|
||||
Query q = qParser.getQuery();
|
||||
assertEquals("Synonym(shingle23:A_B shingle23:A_B_C) shingle23:B_C", q.toString());
|
||||
}
|
||||
|
||||
assertJQ(req("df", "shingle23", "q", "A B C", "sow", "false")
|
||||
, "/response/numFound==1"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,6 +67,8 @@ public class TestSolrQueryParser extends SolrTestCaseJ4 {
|
|||
assertU(adoc("id", "13", "eee_s", "'balance'", "rrr_s", "/leading_slash"));
|
||||
|
||||
assertU(adoc("id", "20", "syn", "wifi ATM"));
|
||||
|
||||
assertU(adoc("id", "30", "shingle23", "A B X D E"));
|
||||
|
||||
assertU(commit());
|
||||
}
|
||||
|
@ -995,4 +997,20 @@ public class TestSolrQueryParser extends SolrTestCaseJ4 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShingleQueries() throws Exception {
|
||||
ModifiableSolrParams sowFalseParams = new ModifiableSolrParams();
|
||||
sowFalseParams.add("sow", "false");
|
||||
|
||||
try (SolrQueryRequest req = req(sowFalseParams)) {
|
||||
QParser qParser = QParser.getParser("shingle23:(A B C)", req);
|
||||
Query q = qParser.getQuery();
|
||||
assertEquals("Synonym(shingle23:A_B shingle23:A_B_C) shingle23:B_C", q.toString());
|
||||
}
|
||||
|
||||
assertJQ(req("df", "shingle23", "q", "A B C", "sow", "false")
|
||||
, "/response/numFound==1"
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue