diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 46b0bd95ca2..befc14a5dc7 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -93,6 +93,8 @@ Improvements * LUCENE-8906: Expose Lucene50PostingsFormat.IntBlockTermState as public so that other postings formats can re-use it. (Bruno Roustant) +* SOLR-13663: Introduce into XML Query Parser (Alessandro Benedetti via Mikhail Khludnev) + Optimizations * LUCENE-8922: DisjunctionMaxQuery more efficiently leverages impacts to skip diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/CoreParser.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/CoreParser.java index a4f5ce5c8de..b4703120dd5 100644 --- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/CoreParser.java +++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/CoreParser.java @@ -112,6 +112,10 @@ public class CoreParser implements QueryBuilder, SpanQueryBuilder { spanFactory.addBuilder("SpanFirst", sft); queryFactory.addBuilder("SpanFirst", sft); + SpanPositionRangeBuilder sprt = new SpanPositionRangeBuilder(spanFactory); + spanFactory.addBuilder("SpanPositionRange", sprt); + queryFactory.addBuilder("SpanPositionRange", sprt); + SpanNotBuilder snot = new SpanNotBuilder(spanFactory); spanFactory.addBuilder("SpanNot", snot); queryFactory.addBuilder("SpanNot", snot); diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/builders/SpanPositionRangeBuilder.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/builders/SpanPositionRangeBuilder.java new file mode 100644 index 00000000000..a2097ca3aae --- /dev/null +++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/builders/SpanPositionRangeBuilder.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.queryparser.xml.builders; + +import org.apache.lucene.queryparser.xml.DOMUtils; +import org.apache.lucene.queryparser.xml.ParserException; +import org.apache.lucene.search.spans.SpanBoostQuery; +import org.apache.lucene.search.spans.SpanPositionRangeQuery; +import org.apache.lucene.search.spans.SpanQuery; +import org.w3c.dom.Element; + +/** + * Builder for {@link SpanPositionRangeQuery} + */ +public class SpanPositionRangeBuilder extends SpanBuilderBase { + + private final SpanQueryBuilder factory; + + public SpanPositionRangeBuilder(SpanQueryBuilder factory) { + this.factory = factory; + } + + @Override + public SpanQuery getSpanQuery(Element e) throws ParserException { + int start = DOMUtils.getAttribute(e, "start", 1); + int end = DOMUtils.getAttribute(e, "end", 1); + Element child = DOMUtils.getFirstChildElement(e); + SpanQuery q = factory.getSpanQuery(child); + + SpanPositionRangeQuery query = new SpanPositionRangeQuery(q, start, end); + + float boost = DOMUtils.getAttribute(e, "boost", 1.0f); + return new SpanBoostQuery(query, boost); + } + +} diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/SpanPositionRangeQuery.xml b/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/SpanPositionRangeQuery.xml new file mode 100644 index 00000000000..670f714db60 --- /dev/null +++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/SpanPositionRangeQuery.xml @@ -0,0 +1,21 @@ + + + + + sugar + diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/TestCoreParser.java b/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/TestCoreParser.java index 3fe3ccb6ed0..4faf6e84b1f 100644 --- a/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/TestCoreParser.java +++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/TestCoreParser.java @@ -135,6 +135,15 @@ public class TestCoreParser extends LuceneTestCase { assertEquals(q, sq); } + public void testSpanPositionRangeQueryXML() throws Exception { + Query q = parse("SpanPositionRangeQuery.xml"); + long h = searcher().search(q, 10).totalHits.value; + assertEquals("SpanPositionRangeQuery should produce 2 result ", 2, h); + SpanQuery sq = parseAsSpan("SpanPositionRangeQuery.xml"); + dumpResults("SpanPositionRangeQuery", sq, 5); + assertEquals(q, sq); + } + public void testSpanNearQueryWithoutSlopXML() throws Exception { Exception expectedException = new NumberFormatException("For input string: \"\""); try { diff --git a/solr/solr-ref-guide/src/other-parsers.adoc b/solr/solr-ref-guide/src/other-parsers.adoc index 266080c8087..ed5e0f2c9c2 100644 --- a/solr/solr-ref-guide/src/other-parsers.adoc +++ b/solr/solr-ref-guide/src/other-parsers.adoc @@ -1042,6 +1042,7 @@ The XmlQParser implementation uses the {solr-javadocs}/solr-core/org/apache/solr | |{lucene-javadocs}/queryparser/org/apache/lucene/queryparser/xml/builders/MatchAllDocsQueryBuilder.html[MatchAllDocsQueryBuilder] | |{lucene-javadocs}/queryparser/org/apache/lucene/queryparser/xml/builders/RangeQueryBuilder.html[RangeQueryBuilder] | |{lucene-javadocs}/queryparser/org/apache/lucene/queryparser/xml/builders/SpanFirstBuilder.html[SpanFirstBuilder] +| |{lucene-javadocs}/queryparser/org/apache/lucene/queryparser/xml/builders/SpanPositionRangeBuilder.html[SpanPositionRangeBuilder] | |{lucene-javadocs}/queryparser/org/apache/lucene/queryparser/xml/builders/SpanNearBuilder.html[SpanNearBuilder] | |{lucene-javadocs}/queryparser/org/apache/lucene/queryparser/xml/builders/SpanNotBuilder.html[SpanNotBuilder] | |{lucene-javadocs}/queryparser/org/apache/lucene/queryparser/xml/builders/SpanOrBuilder.html[SpanOrBuilder]