blob: 8f6e72d55374aa42140d03b2d11ca2b635278449 [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.search.TermQuery;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.Query;
import org.apache.lucene.index.Term;
import org.apache.solr.SolrTestCaseJ4;
import org.junit.BeforeClass;
import java.util.Collection;
/**
*
*/
public class TestQueryUtils extends SolrTestCaseJ4 {
@BeforeClass
public static void beforeClass() throws Exception {
initCore("solrconfig.xml", "schema.xml");
}
@Override
public void setUp() throws Exception {
super.setUp();
}
@Override
public void tearDown() throws Exception {
super.tearDown();
}
public void positive(Query q) {
assertFalse(QueryUtils.isNegative(q));
assertTrue(QueryUtils.getAbs(q)==q);
Collection<BooleanClause> clauses = (q instanceof BooleanQuery) ? ((BooleanQuery)q).clauses() : null;
if (clauses != null) {
if (clauses.size() != 0) {
assertTrue(QueryUtils.makeQueryable(q)==q);
}
} else {
assertTrue(QueryUtils.makeQueryable(q)==q);
}
}
public void negative(Query q) {
assertTrue(QueryUtils.isNegative(q));
Query abs = QueryUtils.getAbs(q);
assertTrue(q != abs);
Query neg2 = QueryUtils.fixNegativeQuery(q);
assertFalse(abs.equals(q));
assertFalse(neg2.equals(q));
}
public void testNegativeQueries() {
TermQuery tq = new TermQuery(new Term("hi","there"));
TermQuery tq2 = new TermQuery(new Term("wow","dude"));
BooleanQuery.Builder bq = new BooleanQuery.Builder();
positive(tq);
// positive(bq);
bq.add(tq, BooleanClause.Occur.SHOULD);
positive(bq.build());
bq.add(tq2, BooleanClause.Occur.MUST_NOT);
positive(bq.build());
bq = new BooleanQuery.Builder();
bq.add(tq,BooleanClause.Occur.MUST_NOT);
negative(bq.build());
bq.add(tq2,BooleanClause.Occur.MUST_NOT);
negative(bq.build());
String f = "name"; // name is whitespace tokenized
assertU(adoc("id", "1", f, "A"));
assertU(adoc("id", "2", f, "B"));
assertU(adoc("id", "3", f, "C"));
assertU(adoc("id", "4", f, "C"));
assertU(adoc("id", "5", f, "D"));
assertU(adoc("id", "6", f, "E"));
assertU(adoc("id", "7", f, "E"));
assertU(adoc("id", "8", f, "E W"));
assertU(adoc("id", "9", f, "F W"));
assertU(adoc("id", "10", f, "G W"));
assertU(adoc("id", "11", f, "G X "));
assertU(adoc("id", "12", f, "G X Y"));
assertU(adoc("id", "13", f, "G X Y Z"));
assertU(adoc("id", "14", f, "G Y Z"));
assertU(adoc("id", "15", f, "G Z"));
assertU(adoc("id", "16", f, "G"));
assertU(commit());
assertQ("test negative base q matching nothing",
req("-qlkciyopsbgzyvkylsjhchghjrdf")
,"//result[@numFound='16']"
);
assertQ("test negative base q matching something",
req("-name:E")
,"//result[@numFound='13']"
);
assertQ("test negative base q with two terms",
req("-name:G -name:W")
,"//result[@numFound='7']"
);
assertQ("test negative base q with three terms",
req("-name:G -name:W -name:E")
,"//result[@numFound='5']"
);
assertQ("test negative boolean query",
req("-(name:G OR name:W)")
,"//result[@numFound='7']"
);
assertQ("test non negative q",
req("-name:G -name:W -name:E id:[* TO *]")
,"//result[@numFound='5']"
);
assertQ("test non negative q",
req("-name:G -name:W -name:E +id:[* TO *]")
,"//result[@numFound='5']"
);
// now for the filters...
assertQ("test negative base q matching nothing, with filters",
req("q","-qlkciyopsbgzyvkylsjhchghjrdf"
,"fq","name:A"
)
,"//result[@numFound='1']"
);
assertQ("test negative filters",
req("q","name:A"
,"fq","-name:A"
)
,"//result[@numFound='0']"
);
assertQ("test negative filters",
req("q","name:A"
,"fq","-name:A"
)
,"//result[@numFound='0']"
);
assertQ("test negative filters",
req("q","-name:E"
,"fq","name:E"
)
,"//result[@numFound='0']"
);
assertQ("test negative filters",
req("q","-name:E"
,"fq","name:W"
)
,"//result[@numFound='2']"
);
assertQ("test negative filters",
req("q","-name:E"
,"fq","name:W"
)
,"//result[@numFound='2']"
);
assertQ("one pos filter, one neg",
req("q","-name:E"
,"fq","name:W"
,"fq","-name:G"
)
,"//result[@numFound='1']"
);
assertQ("two neg filters",
req("q","-name:E"
,"fq","-name:W"
,"fq","-name:G"
)
,"//result[@numFound='5']" // ABCCD
);
assertQ("three neg filters",
req("q","-name:E"
,"fq","-name:W"
,"fq","-name:G"
,"fq","-name:C"
)
,"//result[@numFound='3']" // ABD
);
assertQ("compound neg filters",
req("q","-name:E"
,"fq","-name:W -name:G"
,"fq","-name:C"
)
,"//result[@numFound='3']" // ABD
);
assertQ("compound neg filters",
req("q","-name:E"
,"fq","-name:W -name:G -name:C"
)
,"//result[@numFound='3']" // ABD
);
assertQ("compound neg filters",
req("q","-name:E"
,"fq","-(name:W name:G name:C)"
)
,"//result[@numFound='3']" // ABD
);
assertQ("three neg filters + pos",
req("q","-name:E"
,"fq","-name:W"
,"fq","-name:G"
,"fq","-name:C"
,"fq","name:G"
)
,"//result[@numFound='0']"
);
assertQ("three neg filters + pos",
req("q","-name:E"
,"fq","-name:W"
,"fq","-name:G"
,"fq","-name:C"
,"fq","+id:1"
)
,"//result[@numFound='1']" // A
);
assertQ("three neg filters + pos",
req("q","-name:E"
,"fq","-name:W"
,"fq","-name:G"
,"fq","-name:C"
,"fq","id:[* TO *]"
)
,"//result[@numFound='3']" // ABD
);
// QueryParser turns term queries on stopwords into a BooleanQuery with
// zero clauses.
assertQ("neg base query on stopword",
req("q","-text:stopworda")
,"//result[@numFound='16']" // ABD
);
assertQ("negative filter on stopword",
req("q","id:[* TO *]"
,"fq","-text:stopworda"
)
,"//result[@numFound='16']" // ABD
);
assertQ("two negative filters on stopword",
req("q","id:[* TO *]"
,"fq","-text:stopworda"
,"fq","-text:stopworda"
)
,"//result[@numFound='16']" // ABD
);
assertQ("compound negative filters with stopword",
req("q","id:[* TO *]"
,"fq","-text:stopworda -id:1"
)
,"//result[@numFound='15']" // ABD
);
}
}