blob: 3f99fa6415863e8da2828fb5c82977aee89edd3c [file] [log] [blame]
/*
* 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.solr.search;
import org.apache.lucene.index.Term;
import org.apache.solr.legacy.LegacyNumericRangeQuery;
import org.apache.lucene.search.*;
import org.apache.solr.common.params.MapSolrParams;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.SolrTestCaseJ4;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Collections;
public class TestMaxScoreQueryParser extends SolrTestCaseJ4 {
Query q;
BooleanClause[] clauses;
@BeforeClass
public static void beforeClass() throws Exception {
initCore("solrconfig.xml", "schema.xml");
}
@Test
public void testFallbackToLucene() {
q = parse("foo");
assertEquals(new TermQuery(new Term("text", "foo")), q);
q = parse("foo^3.0");
assertEquals(new BoostQuery(new TermQuery(new Term("text", "foo")), 3f), q);
q = parse("price:[0 TO 10]");
@SuppressWarnings({"rawtypes"})
Class expected = LegacyNumericRangeQuery.class;
if (Boolean.getBoolean(NUMERIC_POINTS_SYSPROP)) {
expected = PointRangeQuery.class;
if (Boolean.getBoolean(NUMERIC_DOCVALUES_SYSPROP)) {
expected = IndexOrDocValuesQuery.class;
}
}
assertTrue(expected + " vs actual: " + q.getClass(), expected.isInstance(q));
}
@Test
public void testNoShouldClauses() {
q = parse("+foo +bar");
clauses = clauses(q);
assertEquals(2, clauses.length);
assertTrue(clauses[0].isRequired());
assertTrue(clauses[1].isRequired());
q = parse("+foo -bar");
clauses = clauses(q);
assertEquals(2, clauses.length);
assertTrue(clauses[0].isRequired());
assertTrue(clauses[1].isProhibited());
}
@Test
public void testPureMax() {
q = parse("foo bar");
clauses = clauses(q);
assertEquals(1, clauses.length);
assertTrue(clauses[0].getQuery() instanceof DisjunctionMaxQuery);
assertEquals(0.0, ((DisjunctionMaxQuery) clauses[0].getQuery()).getTieBreakerMultiplier(), 1e-15);
List<Query> qa = ((DisjunctionMaxQuery) clauses[0].getQuery()).getDisjuncts();
assertEquals(2, qa.size());
assertEquals("text:foo", qa.get(0).toString());
}
@Test
public void testMaxAndProhibited() {
q = parse("foo bar -baz");
clauses = clauses(q);
assertEquals(2, clauses.length);
assertTrue(clauses[0].getQuery() instanceof DisjunctionMaxQuery);
assertTrue(clauses[1].getQuery() instanceof TermQuery);
assertEquals("text:baz", clauses[1].getQuery().toString());
assertTrue(clauses[1].isProhibited());
}
@Test
public void testTie() {
q = parse("foo bar", "tie", "0.5");
clauses = clauses(q);
assertEquals(1, clauses.length);
assertTrue(clauses[0].getQuery() instanceof DisjunctionMaxQuery);
assertEquals(0.5, ((DisjunctionMaxQuery) clauses[0].getQuery()).getTieBreakerMultiplier(), 1e-15);
}
@Test
public void testBoost() {
// Simple term query
q = parse("foo^3.0");
assertTrue(q instanceof BoostQuery);
assertEquals(3.0, ((BoostQuery) q).getBoost(), 1e-15);
// Some DMQ and one plain required
q = parse("foo^5.0 bar^6.0 +baz^7");
clauses = clauses(q);
assertEquals(2, clauses.length);
assertTrue(clauses[0].getQuery() instanceof DisjunctionMaxQuery);
DisjunctionMaxQuery dmq = ((DisjunctionMaxQuery) clauses[0].getQuery());
Query fooClause = ((BooleanQuery)dmq.getDisjuncts().get(0)).clauses().iterator().next().getQuery();
assertEquals(5.0, ((BoostQuery) fooClause).getBoost(), 1e-15);
Query barClause = ((BooleanQuery)dmq.getDisjuncts().get(1)).clauses().iterator().next().getQuery();
assertEquals(6.0, ((BoostQuery) barClause).getBoost(), 1e-15);
assertEquals(7.0, ((BoostQuery) clauses[1].getQuery()).getBoost(), 1e-15);
assertFalse(q instanceof BoostQuery);
// Grouped with parens on top level
q = parse("(foo^2.0 bar)^3.0");
clauses = clauses(q);
assertEquals(1, clauses.length);
assertTrue(clauses[0].getQuery() instanceof DisjunctionMaxQuery);
dmq = ((DisjunctionMaxQuery) clauses[0].getQuery());
fooClause = ((BooleanQuery)dmq.getDisjuncts().get(0)).clauses().iterator().next().getQuery();
assertEquals(2.0, ((BoostQuery) fooClause).getBoost(), 1e-15);
barClause = ((BooleanQuery)dmq.getDisjuncts().get(1)).clauses().iterator().next().getQuery();
assertFalse(barClause instanceof BoostQuery);
assertEquals(3.0, ((BoostQuery) q).getBoost(), 1e-15);
}
//
// Helper methods
//
private Query parse(String q, String... params) {
try {
ModifiableSolrParams p = new ModifiableSolrParams();
ArrayList<String> al = new ArrayList<>(Arrays.asList(params));
while(al.size() >= 2) {
p.add(al.remove(0), al.remove(0));
}
return new MaxScoreQParser(q, p, new MapSolrParams(Collections.singletonMap("df", "text")), req(q)).parse();
} catch (SyntaxError syntaxError) {
fail("Failed with exception "+syntaxError.getMessage());
}
fail("Parse failed");
return null;
}
private BooleanClause[] clauses(Query q) {
while (q instanceof BoostQuery) {
q = ((BoostQuery) q).getQuery();
}
return ((BooleanQuery) q).clauses().toArray(new BooleanClause[0]);
}
}