blob: e06ad536c291970c81d9f5afbabf571dd038b31e [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.schema;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.EnumFieldValue;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.search.SolrQueryParser;
import org.junit.BeforeClass;
import org.junit.Test;
public class EnumFieldTest extends SolrTestCaseJ4 {
private final String FIELD_NAME = "severity";
private final String MV_FIELD_NAME = "severity_mv";
@BeforeClass
public static void beforeClass() throws Exception {
System.setProperty("solr.tests.EnumFieldTest.indexed", Boolean.toString(random().nextBoolean()));
doInitCore();
// System.out.println("solr.tests.numeric.dv: " + System.getProperty("solr.tests.numeric.dv"));
// System.out.println("solr.tests.EnumFieldTest.indexed: " + System.getProperty("solr.tests.EnumFieldTest.indexed"));
// System.out.println("solr.tests.EnumFieldType: " + System.getProperty("solr.tests.EnumFieldType"));
}
private static void doInitCore() throws Exception {
initCore("solrconfig-minimal.xml", "schema-enums.xml");
}
@Test
public void testEnumSchema() throws Exception {
assumeFalse("Skipping testing of EnumFieldType without docValues, which is unsupported.",
System.getProperty("solr.tests.EnumFieldType").equals("solr.EnumFieldType")
&& System.getProperty("solr.tests.numeric.dv").equals("false"));
IndexSchema schema = h.getCore().getLatestSchema();
SchemaField enumField = schema.getField(FIELD_NAME);
assertNotNull(enumField);
SchemaField mvEnumField = schema.getField(MV_FIELD_NAME);
assertNotNull(mvEnumField);
}
@Test
public void testEnumRangeSearch() throws Exception {
assumeFalse("Skipping testing of EnumFieldType without docValues, which is unsupported.",
System.getProperty("solr.tests.EnumFieldType").equals("solr.EnumFieldType")
&& System.getProperty("solr.tests.numeric.dv").equals("false"));
assumeFalse("Skipping testing of unindexed EnumField without docValues, which is unsupported.",
System.getProperty("solr.tests.EnumFieldType").equals("solr.EnumField")
&& System.getProperty("solr.tests.EnumFieldTest.indexed").equals("false")
&& System.getProperty("solr.tests.numeric.dv").equals("false"));
clearIndex();
assertU(adoc("id", "0", FIELD_NAME, "Not Available"));
assertU(adoc("id", "1", FIELD_NAME, "Not Available"));
assertU(adoc("id", "2", FIELD_NAME, "Not Available"));
assertU(adoc("id", "3", FIELD_NAME, "Not Available"));
assertU(adoc("id", "4", FIELD_NAME, "Not Available"));
assertU(adoc("id", "5", FIELD_NAME, "Low"));
assertU(adoc("id", "6", FIELD_NAME, "Low"));
assertU(adoc("id", "7", FIELD_NAME, "Low"));
assertU(adoc("id", "8", FIELD_NAME, "Low"));
assertU(adoc("id", "9", FIELD_NAME, "Medium"));
assertU(adoc("id", "10", FIELD_NAME, "Medium"));
assertU(adoc("id", "11", FIELD_NAME, "Medium"));
assertU(adoc("id", "12", FIELD_NAME, "High"));
assertU(adoc("id", "13", FIELD_NAME, "High"));
assertU(adoc("id", "14", FIELD_NAME, "Critical"));
// two docs w/o values
for (int i = 20; i <= 21; i++) {
assertU(adoc("id", "" + i));
}
assertU(commit());
//range with the same value
assertQ(req("fl", "" + FIELD_NAME, "q", FIELD_NAME + ":[\"Not Available\" TO \"Not Available\"]"),
"//*[@numFound='5']");
assertQ(req("fl", "" + FIELD_NAME, "q", FIELD_NAME + ":[\"Not Available\" TO Critical]"),
"//*[@numFound='15']");
assertQ(req("fl", "" + FIELD_NAME, "q", FIELD_NAME + ":[Low TO High]"),
"//*[@numFound='9']");
assertQ(req("fl", "" + FIELD_NAME, "q", FIELD_NAME + ":[High TO Low]"),
"//*[@numFound='0']");
//with int values
assertQ(req("fl", "" + FIELD_NAME, "q", FIELD_NAME + ":[High TO 11]"),
"//*[@numFound='3']");
assertQ(req("fl", "" + FIELD_NAME, "q", FIELD_NAME + ":[3 TO Critical]"),
"//*[@numFound='3']");
assertQ(req("fl", "" + FIELD_NAME, "q", FIELD_NAME + ":[3 TO 11]"),
"//*[@numFound='3']");
//exclusive
assertQ(req("fl", "" + FIELD_NAME, "q", FIELD_NAME + ":{Low TO High]"),
"//*[@numFound='5']");
assertQ(req("fl", "" + FIELD_NAME, "q", FIELD_NAME + ":[Low TO High}"),
"//*[@numFound='7']");
assertQ(req("fl", "" + FIELD_NAME, "q", FIELD_NAME + ":{Low TO High}"),
"//*[@numFound='3']");
//all docs
assertQ(req("fl", "" + FIELD_NAME, "q", "*:*"),
"//*[@numFound='17']");
//all docs with values
assertQ(req("fl", "" + FIELD_NAME, "q", FIELD_NAME + ":[* TO *]"),
"//*[@numFound='15']");
//empty docs
assertQ(req("fl", "" + FIELD_NAME, "q", "-" + FIELD_NAME + ":[* TO *]"),
"//*[@numFound='2']");
}
@Test
public void testMultivaluedEnumRangeSearch() {
assumeFalse("Skipping testing of EnumFieldType without docValues, which is unsupported.",
System.getProperty("solr.tests.EnumFieldType").equals("solr.EnumFieldType")
&& System.getProperty("solr.tests.numeric.dv").equals("false"));
assumeFalse("Skipping testing of range searching over multivalued EnumField - see SOLR-11193",
System.getProperty("solr.tests.EnumFieldType").equals("solr.EnumField"));
clearIndex();
assertU(adoc("id", "0", MV_FIELD_NAME, "Not Available")); // Single value
assertU(adoc("id", "1", MV_FIELD_NAME, "Not Available", MV_FIELD_NAME, "Critical"));
assertU(adoc("id", "2", MV_FIELD_NAME, "Not Available", MV_FIELD_NAME, "Critical"));
assertU(adoc("id", "3")); // No values
assertU(adoc("id", "4")); // No values
assertU(adoc("id", "5", MV_FIELD_NAME, "Low", MV_FIELD_NAME, "Medium"));
assertU(adoc("id", "6", MV_FIELD_NAME, "Low", MV_FIELD_NAME, "Medium"));
assertU(adoc("id", "7", MV_FIELD_NAME, "Low", MV_FIELD_NAME, "Medium"));
assertU(adoc("id", "8", MV_FIELD_NAME, "Low", MV_FIELD_NAME, "Critical"));
assertU(adoc("id", "9", MV_FIELD_NAME, "Medium")); // Single value
assertU(adoc("id", "10", MV_FIELD_NAME, "Medium", MV_FIELD_NAME, "High"));
assertU(adoc("id", "11", MV_FIELD_NAME, "Medium", MV_FIELD_NAME, "High"));
assertU(adoc("id", "12", MV_FIELD_NAME, "High", MV_FIELD_NAME, "Critical"));
assertU(adoc("id", "13", MV_FIELD_NAME, "High", MV_FIELD_NAME, "High")); // Two of same value
assertU(adoc("id", "14", MV_FIELD_NAME, "Critical", MV_FIELD_NAME, "Medium", MV_FIELD_NAME, "Not Available"));
assertU(commit());
//range with the same value
assertQ(req("fl", "" + MV_FIELD_NAME, "q", MV_FIELD_NAME + ":[\"Not Available\" TO \"Not Available\"]"),
"//*[@numFound='4']");
assertQ(req("fl", "" + MV_FIELD_NAME, "q", MV_FIELD_NAME + ":[\"Not Available\" TO Critical]"),
"//*[@numFound='13']");
assertQ(req("fl", "" + MV_FIELD_NAME, "q", MV_FIELD_NAME + ":[Low TO High]"),
"//*[@numFound='10']");
assertQ(req("fl", "" + MV_FIELD_NAME, "q", MV_FIELD_NAME + ":[High TO Low]"),
"//*[@numFound='0']");
//with int values
assertQ(req("fl", "" + MV_FIELD_NAME, "q", MV_FIELD_NAME + ":[High TO 11]"),
"//*[@numFound='8']");
assertQ(req("fl", "" + MV_FIELD_NAME, "q", MV_FIELD_NAME + ":[3 TO Critical]"),
"//*[@numFound='8']");
assertQ(req("fl", "" + MV_FIELD_NAME, "q", MV_FIELD_NAME + ":[3 TO 11]"),
"//*[@numFound='8']");
//exclusive
assertQ(req("fl", "" + MV_FIELD_NAME, "q", MV_FIELD_NAME + ":{Low TO High]"),
"//*[@numFound='9']");
assertQ(req("fl", "" + MV_FIELD_NAME, "q", MV_FIELD_NAME + ":[Low TO High}"),
"//*[@numFound='8']");
assertQ(req("fl", "" + MV_FIELD_NAME, "q", MV_FIELD_NAME + ":{Low TO High}"),
"//*[@numFound='7']");
//all docs
assertQ(req("fl", "" + MV_FIELD_NAME, "q", "*:*"),
"//*[@numFound='15']");
//all docs with values
assertQ(req("fl", "" + MV_FIELD_NAME, "q", MV_FIELD_NAME + ":[* TO *]"),
"//*[@numFound='13']");
//empty docs
assertQ(req("fl", "" + MV_FIELD_NAME, "q", "-" + MV_FIELD_NAME + ":[* TO *]"),
"//*[@numFound='2']");
}
@Test
public void testBogusEnumSearch() throws Exception {
assumeFalse("Skipping testing of EnumFieldType without docValues, which is unsupported.",
System.getProperty("solr.tests.EnumFieldType").equals("solr.EnumFieldType")
&& System.getProperty("solr.tests.numeric.dv").equals("false"));
clearIndex();
assertU(adoc("id", "0", FIELD_NAME, "Not Available"));
assertU(adoc("id", "1", FIELD_NAME, "Low"));
assertU(adoc("id", "2", FIELD_NAME, "Medium"));
assertU(adoc("id", "3", FIELD_NAME, "High"));
assertU(adoc("id", "4", FIELD_NAME, "Critical"));
// two docs w/o values
for (int i = 8; i <= 9; i++) {
assertU(adoc("id", "" + i));
}
assertU(commit());
assertQ(req("fl", "" + FIELD_NAME, "q", FIELD_NAME + ":bla"),
"//*[@numFound='0']");
assertQ(req("fl", "" + FIELD_NAME, "q", FIELD_NAME + ":7"),
"//*[@numFound='0']");
assertQ(req("fl", "" + FIELD_NAME, "q", FIELD_NAME + ":\"-3\""),
"//*[@numFound='0']");
}
@Test
public void testMultivaluedBogusEnumSearch() throws Exception {
assumeFalse("Skipping testing of EnumFieldType without docValues, which is unsupported.",
System.getProperty("solr.tests.EnumFieldType").equals("solr.EnumFieldType")
&& System.getProperty("solr.tests.numeric.dv").equals("false"));
clearIndex();
assertU(adoc("id", "0", MV_FIELD_NAME, "Not Available", MV_FIELD_NAME, "Critical"));
assertU(adoc("id", "1", MV_FIELD_NAME, "Low", MV_FIELD_NAME, "Not Available"));
assertU(adoc("id", "2", MV_FIELD_NAME, "Medium", MV_FIELD_NAME, "Low"));
assertU(adoc("id", "3", MV_FIELD_NAME, "High", MV_FIELD_NAME, "Medium"));
assertU(adoc("id", "4", MV_FIELD_NAME, "Critical", MV_FIELD_NAME, "High"));
// two docs w/o values
for (int i = 8; i <= 9; i++) {
assertU(adoc("id", "" + i));
}
assertU(commit());
assertQ(req("fl", "" + MV_FIELD_NAME, "q", MV_FIELD_NAME + ":bla"),
"//*[@numFound='0']");
assertQ(req("fl", "" + MV_FIELD_NAME, "q", MV_FIELD_NAME + ":7"),
"//*[@numFound='0']");
assertQ(req("fl", "" + MV_FIELD_NAME, "q", MV_FIELD_NAME + ":\"-3\""),
"//*[@numFound='0']");
}
@Test
public void testBogusEnumIndexing() throws Exception {
assumeFalse("Skipping testing of EnumFieldType without docValues, which is unsupported.",
System.getProperty("solr.tests.EnumFieldType").equals("solr.EnumFieldType")
&& System.getProperty("solr.tests.numeric.dv").equals("false"));
ignoreException("Unknown value for enum field: " + FIELD_NAME + ", value: blabla");
ignoreException("Unknown value for enum field: " + FIELD_NAME + ", value: 145");
ignoreException("Unknown value for enum field: " + FIELD_NAME + ", value: -4");
clearIndex();
assertFailedU(adoc("id", "0", FIELD_NAME, "blabla"));
assertFailedU(adoc("id", "0", FIELD_NAME, "145"));
assertFailedU(adoc("id", "0", FIELD_NAME, "-4"));
}
@Test
public void testMultivaluedBogusEnumIndexing() throws Exception {
assumeFalse("Skipping testing of EnumFieldType without docValues, which is unsupported.",
System.getProperty("solr.tests.EnumFieldType").equals("solr.EnumFieldType")
&& System.getProperty("solr.tests.numeric.dv").equals("false"));
ignoreException("Unknown value for enum field: " + MV_FIELD_NAME + ", value: blabla");
ignoreException("Unknown value for enum field: " + MV_FIELD_NAME + ", value: 145");
ignoreException("Unknown value for enum field: " + MV_FIELD_NAME + ", value: -4");
clearIndex();
assertFailedU(adoc("id", "0", MV_FIELD_NAME, "blabla", MV_FIELD_NAME, "High"));
assertFailedU(adoc("id", "0", MV_FIELD_NAME, "145", MV_FIELD_NAME, "Low"));
assertFailedU(adoc("id", "0", MV_FIELD_NAME, "-4", MV_FIELD_NAME, "Critical"));
}
@Test
public void testKnownIntegerEnumIndexing() throws Exception {
assumeFalse("Skipping testing of EnumFieldType without docValues, which is unsupported.",
System.getProperty("solr.tests.EnumFieldType").equals("solr.EnumFieldType")
&& System.getProperty("solr.tests.numeric.dv").equals("false"));
clearIndex();
assertU(adoc("id", "0", FIELD_NAME, "1"));
assertU(adoc("id", "1", FIELD_NAME, "11"));
assertU(commit());
assertQ(req("fl", "id," + FIELD_NAME, "q", "*:*"),
"//doc[str[@name='id']/text()='0']/str[@name='" + FIELD_NAME + "']/text()='Low'",
"//doc[str[@name='id']/text()='1']/str[@name='" + FIELD_NAME + "']/text()='Critical'");
}
@Test
public void testMultivaluedKnownIntegerEnumIndexing() throws Exception {
assumeFalse("Skipping testing of EnumFieldType without docValues, which is unsupported.",
System.getProperty("solr.tests.EnumFieldType").equals("solr.EnumFieldType")
&& System.getProperty("solr.tests.numeric.dv").equals("false"));
clearIndex();
assertU(adoc("id", "0", MV_FIELD_NAME, "1", MV_FIELD_NAME, "2"));
assertU(adoc("id", "1", MV_FIELD_NAME, "11", MV_FIELD_NAME, "3"));
assertU(commit());
assertQ(req("fl", "id," + MV_FIELD_NAME, "q", "*:*"),
"//doc[str[@name='id']/text()='0']/arr[@name='" + MV_FIELD_NAME + "']/str/text()='Low'",
"//doc[str[@name='id']/text()='0']/arr[@name='" + MV_FIELD_NAME + "']/str/text()='Medium'",
"//doc[str[@name='id']/text()='1']/arr[@name='" + MV_FIELD_NAME + "']/str/text()='Critical'",
"//doc[str[@name='id']/text()='1']/arr[@name='" + MV_FIELD_NAME + "']/str/text()='High'");
}
@Test
public void testEnumSort() throws Exception {
assumeFalse("Skipping testing of EnumFieldType without docValues, which is unsupported.",
System.getProperty("solr.tests.EnumFieldType").equals("solr.EnumFieldType")
&& System.getProperty("solr.tests.numeric.dv").equals("false"));
assumeFalse("Skipping testing of unindexed EnumField without docValues, which is unsupported.",
System.getProperty("solr.tests.EnumFieldType").equals("solr.EnumField")
&& System.getProperty("solr.tests.EnumFieldTest.indexed").equals("false")
&& System.getProperty("solr.tests.numeric.dv").equals("false"));
clearIndex();
assertU(adoc("id", "0", FIELD_NAME, "Not Available"));
assertU(adoc("id", "1", FIELD_NAME, "Low"));
assertU(adoc("id", "2", FIELD_NAME, "Medium"));
assertU(adoc("id", "3", FIELD_NAME, "High"));
assertU(adoc("id", "4", FIELD_NAME, "Critical"));
// two docs w/o values
for (int i = 8; i <= 9; i++) {
assertU(adoc("id", "" + i));
}
assertU(commit());
assertQ(req("fl", "id," + FIELD_NAME, "q", "*:*", "sort", FIELD_NAME + " desc", "indent","on"),
"//doc[1]/str[@name='" + FIELD_NAME + "']/text()='Critical'",
"//doc[2]/str[@name='" + FIELD_NAME + "']/text()='High'",
"//doc[3]/str[@name='" + FIELD_NAME + "']/text()='Medium'",
"//doc[4]/str[@name='" + FIELD_NAME + "']/text()='Low'",
"//doc[5]/str[@name='" + FIELD_NAME + "']/text()='Not Available'");
//sort ascending - empty values will be first
assertQ(req("fl", "id," + FIELD_NAME, "q", "*:*", "sort", FIELD_NAME + " asc", "indent", "on"),
"//doc[3]/str[@name='" + FIELD_NAME + "']/text()='Not Available'");
//q for not empty docs
assertQ(req("fl", "id," + FIELD_NAME, "q", FIELD_NAME + ":[* TO *]" , "sort", FIELD_NAME + " asc", "indent", "on"),
"//doc[1]/str[@name='" + FIELD_NAME + "']/text()='Not Available'",
"//doc[2]/str[@name='" + FIELD_NAME + "']/text()='Low'",
"//doc[3]/str[@name='" + FIELD_NAME + "']/text()='Medium'",
"//doc[4]/str[@name='" + FIELD_NAME + "']/text()='High'",
"//doc[5]/str[@name='" + FIELD_NAME + "']/text()='Critical'"
);
// missing first....
for (String dir : Arrays.asList("asc", "desc")) {
assertQ(req("fl", "id", "q", "*:*", "sort", FIELD_NAME + "_missingFirst " + dir + ", id desc")
, "//doc[1]/str[@name='id']/text()='9'"
, "//doc[2]/str[@name='id']/text()='8'"
);
}
// missing last...
for (String dir : Arrays.asList("asc", "desc")) {
assertQ(req("fl", "id", "q", "*:*", "sort", FIELD_NAME + "_missingLast " + dir + ", id desc")
, "//doc[6]/str[@name='id']/text()='9'"
, "//doc[7]/str[@name='id']/text()='8'"
);
}
}
@Test
public void testMultivaluedEnumSort() throws Exception {
assumeFalse("Skipping testing of EnumFieldType without docValues, which is unsupported.",
System.getProperty("solr.tests.EnumFieldType").equals("solr.EnumFieldType")
&& System.getProperty("solr.tests.numeric.dv").equals("false"));
assumeFalse("Skipping testing of sorting over multivalued EnumField - see SOLR-11193",
System.getProperty("solr.tests.EnumFieldType").equals("solr.EnumField"));
clearIndex();
assertU(adoc("id", "0", MV_FIELD_NAME, "Not Available")); // Single value
assertU(adoc("id", "1", MV_FIELD_NAME, "Not Available", MV_FIELD_NAME, "Critical"));
assertU(adoc("id", "2", MV_FIELD_NAME, "Not Available", MV_FIELD_NAME, "Critical"));
assertU(adoc("id", "3")); // No values
assertU(adoc("id", "4")); // No values
assertU(adoc("id", "5", MV_FIELD_NAME, "Low", MV_FIELD_NAME, "Medium"));
assertU(adoc("id", "6", MV_FIELD_NAME, "Low", MV_FIELD_NAME, "Medium"));
assertU(adoc("id", "7", MV_FIELD_NAME, "Low", MV_FIELD_NAME, "Medium"));
assertU(adoc("id", "8", MV_FIELD_NAME, "Low", MV_FIELD_NAME, "Critical"));
assertU(adoc("id", "9", MV_FIELD_NAME, "Medium")); // Single value
assertU(adoc("id", "10", MV_FIELD_NAME, "Medium", MV_FIELD_NAME, "High"));
assertU(adoc("id", "11", MV_FIELD_NAME, "Medium", MV_FIELD_NAME, "High"));
assertU(adoc("id", "12", MV_FIELD_NAME, "High", MV_FIELD_NAME, "Critical"));
assertU(adoc("id", "13", MV_FIELD_NAME, "High", MV_FIELD_NAME, "High")); // Two of same value
assertU(adoc("id", "14", MV_FIELD_NAME, "Critical", MV_FIELD_NAME, "Medium", MV_FIELD_NAME, "Not Available"));
assertU(commit());
assertQ(req("fl", "id," + MV_FIELD_NAME, "q", "*:*", "sort", "field(" + MV_FIELD_NAME + ",min) desc", "indent","on"),
"//doc[1]/arr[@name='" + MV_FIELD_NAME + "']/str/text()='Critical'",
"//doc[2]/arr[@name='" + MV_FIELD_NAME + "']/str/text()='High'",
"//doc[3]/arr[@name='" + MV_FIELD_NAME + "']/str/text()='Medium'",
"//doc[6]/arr[@name='" + MV_FIELD_NAME + "']/str/text()='Low'",
"//doc[10]/arr[@name='" + MV_FIELD_NAME + "']/str/text()='Not Available'");
//sort ascending - empty values will be first
assertQ(req("fl", "id," + MV_FIELD_NAME, "q", "*:*", "sort", "field(" + MV_FIELD_NAME + ",min) asc", "indent", "on"),
"//doc[3]/arr[@name='" + MV_FIELD_NAME + "']/str/text()='Not Available'");
//q for not empty docs
assertQ(req("fl", "id," + MV_FIELD_NAME,
"q", MV_FIELD_NAME + ":[* TO *]" , "sort", "field(" + MV_FIELD_NAME + ",'min') asc",
"rows","15", "indent","on"),
"//doc[1]/arr[@name='" + MV_FIELD_NAME + "']/str/text()='Not Available'",
"//doc[5]/arr[@name='" + MV_FIELD_NAME + "']/str/text()='Low'",
"//doc[9]/arr[@name='" + MV_FIELD_NAME + "']/str/text()='Medium'",
"//doc[10]/arr[@name='" + MV_FIELD_NAME + "']/str/text()='High'",
"//doc[12]/arr[@name='" + MV_FIELD_NAME + "']/str/text()='Critical'");
}
@Test
public void testSetQuery() throws Exception {
assumeFalse("Skipping testing of EnumFieldType without docValues, which is unsupported.",
System.getProperty("solr.tests.EnumFieldType").equals("solr.EnumFieldType")
&& System.getProperty("solr.tests.numeric.dv").equals("false"));
assumeFalse("Skipping testing of unindexed EnumField without docValues, which is unsupported.",
System.getProperty("solr.tests.EnumFieldType").equals("solr.EnumField")
&& System.getProperty("solr.tests.EnumFieldTest.indexed").equals("false")
&& System.getProperty("solr.tests.numeric.dv").equals("false"));
clearIndex();
SchemaField sf = h.getCore().getLatestSchema().getField(FIELD_NAME);
Set<String> enumStrs = ((AbstractEnumField)sf.getType()).getEnumMapping().enumStringToIntMap.keySet();
assertTrue(enumStrs.size() > SolrQueryParser.TERMS_QUERY_THRESHOLD);
Iterator<String> enumStrIter = enumStrs.iterator();
for (int i = 0 ; enumStrIter.hasNext() ; ++i) {
assertU(adoc("id", "" + i, FIELD_NAME, enumStrIter.next()));
}
assertU(commit());
StringBuilder builder = new StringBuilder(FIELD_NAME + ":(");
enumStrs.forEach(v -> builder.append(v.replace(" ", "\\ ")).append(' '));
builder.append(')');
if (sf.indexed()) { // SolrQueryParser should also be generating a TermInSetQuery if indexed
String setQuery = sf.getType().getSetQuery(null, sf, enumStrs).toString();
if (sf.getType() instanceof EnumField) { // Trie field TermInSetQuery non-XML chars serialize with "#XX;" syntax
Pattern nonXMLCharPattern = Pattern.compile("[\u0000-\u0008\u000B\u000C\u000E-\u0019]");
StringBuffer munged = new StringBuffer();
Matcher matcher = nonXMLCharPattern.matcher(setQuery);
while (matcher.find()) {
matcher.appendReplacement(munged, "#" + (int)matcher.group(0).charAt(0) + ";");
}
matcher.appendTail(munged);
setQuery = munged.toString();
}
assertQ(req(CommonParams.DEBUG, CommonParams.QUERY, "q", "*:*", "fq", builder.toString(),
"fl", "id," + FIELD_NAME, "rows", "" + enumStrs.size(), "indent", "on"),
"//*[@numFound='" + enumStrs.size() + "']",
"//*[@name='parsed_filter_queries']/str[normalize-space(.)=normalize-space('TermInSetQuery(" + setQuery + ")')]"); // fix [\r\n] problems
} else {
// Won't use TermInSetQuery if the field is not indexed, but should match the same docs
assertQ(req(CommonParams.DEBUG, CommonParams.QUERY, "q", "*:*", "fq", builder.toString(), "fl", "id," + FIELD_NAME, "indent", "on"),
"//*[@numFound='" + enumStrs.size() + "']");
}
}
@Test
public void testMultivaluedSetQuery() throws Exception {
assumeFalse("Skipping testing of EnumFieldType without docValues, which is unsupported.",
System.getProperty("solr.tests.EnumFieldType").equals("solr.EnumFieldType")
&& System.getProperty("solr.tests.numeric.dv").equals("false"));
assumeFalse("Skipping testing of unindexed EnumField without docValues, which is unsupported.",
System.getProperty("solr.tests.EnumFieldType").equals("solr.EnumField")
&& System.getProperty("solr.tests.EnumFieldTest.indexed").equals("false")
&& System.getProperty("solr.tests.numeric.dv").equals("false"));
clearIndex();
SchemaField sf = h.getCore().getLatestSchema().getField(MV_FIELD_NAME);
Set<String> enumStrs = ((AbstractEnumField)sf.getType()).getEnumMapping().enumStringToIntMap.keySet();
assertTrue(enumStrs.size() > SolrQueryParser.TERMS_QUERY_THRESHOLD);
Iterator<String> enumStrIter = enumStrs.iterator();
String prevEnumStr = "x18"; // wrap around
for (int i = 0 ; enumStrIter.hasNext() ; ++i) {
String thisEnumStr = enumStrIter.next();
assertU(adoc("id", "" + i, MV_FIELD_NAME, thisEnumStr, MV_FIELD_NAME, prevEnumStr));
prevEnumStr = thisEnumStr;
}
assertU(commit());
StringBuilder builder = new StringBuilder(MV_FIELD_NAME + ":(");
enumStrs.forEach(v -> builder.append(v.replace(" ", "\\ ")).append(' '));
builder.append(')');
if (sf.indexed()) { // SolrQueryParser should also be generating a TermInSetQuery if indexed
String setQuery = sf.getType().getSetQuery(null, sf, enumStrs).toString();
if (sf.getType() instanceof EnumField) { // Trie field TermInSetQuery non-XML chars serialize with "#XX;" syntax
Pattern nonXMLCharPattern = Pattern.compile("[\u0000-\u0008\u000B\u000C\u000E-\u0019]");
StringBuffer munged = new StringBuffer();
Matcher matcher = nonXMLCharPattern.matcher(setQuery);
while (matcher.find()) {
matcher.appendReplacement(munged, "#" + (int)matcher.group(0).charAt(0) + ";");
}
matcher.appendTail(munged);
setQuery = munged.toString();
}
assertQ(req(CommonParams.DEBUG, CommonParams.QUERY, "q", "*:*", "fq", builder.toString(),
"fl", "id," + MV_FIELD_NAME, "rows", "" + enumStrs.size(), "indent", "on"),
"//*[@numFound='" + enumStrs.size() + "']",
"//*[@name='parsed_filter_queries']/str[normalize-space(.)=normalize-space('TermInSetQuery(" + setQuery + ")')]"); // fix [\r\n] problems
} else {
// Won't use TermInSetQuery if the field is not indexed, but should match the same docs
assertQ(req(CommonParams.DEBUG, CommonParams.QUERY, "q", "*:*", "fq", builder.toString(), "fl", "id," + MV_FIELD_NAME, "indent", "on"),
"//*[@numFound='" + enumStrs.size() + "']");
}
}
@Test
public void testEnumFieldTypeWithoutDocValues() throws Exception {
assumeTrue("Only testing EnumFieldType without docValues.",
System.getProperty("solr.tests.EnumFieldType").equals("solr.EnumFieldType")
&& System.getProperty("solr.tests.numeric.dv").equals("false"));
try {
deleteCore();
initCore("solrconfig-minimal.xml", "bad-schema-enums.xml");
SolrException e = expectThrows(SolrException.class,
() -> assertU(adoc("id", "0", FIELD_NAME, "Not Available")));
assertTrue(e.getMessage().contains("EnumFieldType requires docValues=\"true\""));
} finally { // put back the core expected by other tests
deleteCore();
doInitCore();
}
}
@SuppressWarnings("unchecked")
@Test
public void testFacetEnumSearch() throws Exception {
assumeFalse("This requires docValues",
System.getProperty("solr.tests.numeric.dv").equals("false"));
clearIndex();
assertU(adoc("id", "0", FIELD_NAME, "Not Available"));
assertU(adoc("id", "1", FIELD_NAME, "Low"));
assertU(adoc("id", "2", FIELD_NAME, "Medium"));
assertU(adoc("id", "3", FIELD_NAME, "High"));
assertU(adoc("id", "4", FIELD_NAME, "Critical"));
assertU(adoc("id", "5", FIELD_NAME, "Critical"));
assertU(commit());
final String jsonFacetParam = "{ " + FIELD_NAME + " : { type : terms, field : " + FIELD_NAME + ", "+
"missing : true, exists : true, allBuckets : true, method : enum }}";
assertQ(req("fl", "" + FIELD_NAME, "q", FIELD_NAME + ":*", "json.facet", jsonFacetParam),
"//*[@name='facets']/int/text()=6",
"//*[@name='allBuckets']/long/text()=6",
"//*[@name='buckets']/lst[int[@name='count'][.='2']][str[@name='val'][.='Critical']]",
"//*[@name='buckets']/lst[int[@name='count'][.='1']][str[@name='val'][.='Not Available']]",
"//*[@name='buckets']/lst[int[@name='count'][.='1']][str[@name='val'][.='Low']]",
"//*[@name='buckets']/lst[int[@name='count'][.='1']][str[@name='val'][.='Medium']]",
"//*[@name='buckets']/lst[int[@name='count'][.='1']][str[@name='val'][.='High']]");
try (SolrQueryRequest req = req("fl", "" + FIELD_NAME, "q", FIELD_NAME + ":*", "json.facet", jsonFacetParam, "wt", "json")) {
SolrQueryResponse rsp = h.queryAndResponse(req.getParams().get(CommonParams.QT),req);
List<NamedList<?>> buckets = (List<NamedList<?>>) ((NamedList<?>)((NamedList<?>)rsp.getValues().get("facets")).get("severity")).get("buckets");
for (NamedList<?> bucket : buckets) {
assertTrue("Bucket value must be instance of EnumFieldVale!", bucket.get("val") instanceof EnumFieldValue);
}
}
}
}