blob: a49e9fe9b772340ddd34a58496a0cf588b244eb5 [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.update.processor;
import java.io.File;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.Date;
import java.util.Locale;
import org.apache.commons.io.FileUtils;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.schema.IndexSchema;
import org.junit.After;
import org.junit.Before;
/**
* Tests for the field mutating update processors
* that parse Dates, Longs, Doubles, and Booleans.
*/
public class AddSchemaFieldsUpdateProcessorFactoryTest extends UpdateProcessorTestBase {
private static final String SOLRCONFIG_XML = "solrconfig-add-schema-fields-update-processor-chains.xml";
private static final String SCHEMA_XML = "schema-add-schema-fields-update-processor.xml";
private static File tmpSolrHome;
private static File tmpConfDir;
private static final String collection = "collection1";
private static final String confDir = collection + "/conf";
@Before
private void initManagedSchemaCore() throws Exception {
tmpSolrHome = createTempDir().toFile();
tmpConfDir = new File(tmpSolrHome, confDir);
File testHomeConfDir = new File(TEST_HOME(), confDir);
FileUtils.copyFileToDirectory(new File(testHomeConfDir, SOLRCONFIG_XML), tmpConfDir);
FileUtils.copyFileToDirectory(new File(testHomeConfDir, SCHEMA_XML), tmpConfDir);
// initCore will trigger an upgrade to managed schema, since the solrconfig*.xml has
// <schemaFactory class="ManagedIndexSchemaFactory" ... />
initCore(SOLRCONFIG_XML, SCHEMA_XML, tmpSolrHome.getPath());
}
public void testEmptyValue() {
IndexSchema schema = h.getCore().getLatestSchema();
final String fieldName = "newFieldABC";
assertNull(schema.getFieldOrNull(fieldName));
//UpdateProcessorTestBase#doc doesn't deal with nulls
SolrInputDocument doc = new SolrInputDocument();
doc.addField("id", "1");
doc.addField(fieldName, null);
SolrInputDocument finalDoc = doc;
expectThrows(AssertionError.class, () -> processAdd("add-fields-no-run-processor", finalDoc));
expectThrows(AssertionError.class, () -> processAdd("add-fields-no-run-processor", new SolrInputDocument(null , null)));
}
public void testSingleField() throws Exception {
IndexSchema schema = h.getCore().getLatestSchema();
final String fieldName = "newfield1";
assertNull(schema.getFieldOrNull(fieldName));
Date date = Date.from(Instant.now());
SolrInputDocument d = processAdd("add-fields-no-run-processor", doc(f("id", "1"), f(fieldName, date)));
assertNotNull(d);
schema = h.getCore().getLatestSchema();
assertNotNull(schema.getFieldOrNull(fieldName));
assertEquals("pdates", schema.getFieldType(fieldName).getTypeName());
}
public void testSingleFieldRoundTrip() throws Exception {
IndexSchema schema = h.getCore().getLatestSchema();
final String fieldName = "newfield2";
assertNull(schema.getFieldOrNull(fieldName));
Float floatValue = -13258.992f;
SolrInputDocument d = processAdd("add-fields", doc(f("id", "2"), f(fieldName, floatValue)));
assertNotNull(d);
schema = h.getCore().getLatestSchema();
assertNotNull(schema.getFieldOrNull(fieldName));
assertEquals("pfloats", schema.getFieldType(fieldName).getTypeName());
assertU(commit());
assertQ(req("id:2"), "//arr[@name='" + fieldName + "']/float[.='" + floatValue.toString() + "']");
}
public void testSingleFieldMixedFieldTypesRoundTrip() throws Exception {
IndexSchema schema = h.getCore().getLatestSchema();
final String fieldName = "newfield3";
assertNull(schema.getFieldOrNull(fieldName));
Float fieldValue1 = -13258.0f;
Double fieldValue2 = 8.4828800808E10;
SolrInputDocument d = processAdd
("add-fields", doc(f("id", "3"), f(fieldName, fieldValue1, fieldValue2)));
assertNotNull(d);
schema = h.getCore().getLatestSchema();
assertNotNull(schema.getFieldOrNull(fieldName));
assertEquals("pdoubles", schema.getFieldType(fieldName).getTypeName());
assertU(commit());
assertQ(req("id:3")
,"//arr[@name='" + fieldName + "']/double[.='" + fieldValue1.toString() + "']"
,"//arr[@name='" + fieldName + "']/double[.='" + fieldValue2.toString() + "']");
}
public void testSingleFieldDefaultFieldTypeRoundTrip() throws Exception {
IndexSchema schema = h.getCore().getLatestSchema();
final String fieldName = "newfield4";
assertNull(schema.getFieldOrNull(fieldName));
Float fieldValue1 = -13258.0f;
Double fieldValue2 = 8.4828800808E10;
String fieldValue3 = "blah blah";
SolrInputDocument d = processAdd
("add-fields", doc(f("id", "4"), f(fieldName, fieldValue1, fieldValue2, fieldValue3)));
assertNotNull(d);
schema = h.getCore().getLatestSchema();
assertNotNull(schema.getFieldOrNull(fieldName));
assertEquals("text", schema.getFieldType(fieldName).getTypeName());
assertEquals(0, schema.getCopyFieldProperties(true, Collections.singleton(fieldName), null).size());
assertU(commit());
assertQ(req("id:4")
,"//arr[@name='" + fieldName + "']/str[.='" + fieldValue1.toString() + "']"
,"//arr[@name='" + fieldName + "']/str[.='" + fieldValue2.toString() + "']"
,"//arr[@name='" + fieldName + "']/str[.='" + fieldValue3.toString() + "']"
);
}
public void testSingleFieldDefaultTypeMappingRoundTrip() throws Exception {
IndexSchema schema = h.getCore().getLatestSchema();
final String fieldName = "newfield4";
assertNull(schema.getFieldOrNull(fieldName));
Float fieldValue1 = -13258.0f;
Double fieldValue2 = 8.4828800808E10;
String fieldValue3 = "blah blah";
SolrInputDocument d = processAdd
("add-fields-default-mapping", doc(f("id", "4"), f(fieldName, fieldValue1, fieldValue2, fieldValue3)));
assertNotNull(d);
schema = h.getCore().getLatestSchema();
assertNotNull(schema.getFieldOrNull(fieldName));
assertEquals("text", schema.getFieldType(fieldName).getTypeName());
assertEquals(1, schema.getCopyFieldProperties(true, Collections.singleton(fieldName), null).size());
assertU(commit());
assertQ(req("id:4")
,"//arr[@name='" + fieldName + "']/str[.='" + fieldValue1.toString() + "']"
,"//arr[@name='" + fieldName + "']/str[.='" + fieldValue2.toString() + "']"
,"//arr[@name='" + fieldName + "']/str[.='" + fieldValue3.toString() + "']"
);
}
public void testMultipleFieldsRoundTrip() throws Exception {
IndexSchema schema = h.getCore().getLatestSchema();
final String fieldName1 = "newfield5";
final String fieldName2 = "newfield6";
assertNull(schema.getFieldOrNull(fieldName1));
assertNull(schema.getFieldOrNull(fieldName2));
Float field1Value1 = -13258.0f;
Double field1Value2 = 8.4828800808E10;
Long field1Value3 = 999L;
Integer field2Value1 = 55123;
Long field2Value2 = 1234567890123456789L;
SolrInputDocument d = processAdd
("add-fields", doc(f("id", "5"), f(fieldName1, field1Value1, field1Value2, field1Value3),
f(fieldName2, field2Value1, field2Value2)));
assertNotNull(d);
schema = h.getCore().getLatestSchema();
assertNotNull(schema.getFieldOrNull(fieldName1));
assertNotNull(schema.getFieldOrNull(fieldName2));
assertEquals("pdoubles", schema.getFieldType(fieldName1).getTypeName());
assertEquals("plongs", schema.getFieldType(fieldName2).getTypeName());
assertU(commit());
assertQ(req("id:5")
,"//arr[@name='" + fieldName1 + "']/double[.='" + field1Value1.toString() + "']"
,"//arr[@name='" + fieldName1 + "']/double[.='" + field1Value2.toString() + "']"
,"//arr[@name='" + fieldName1 + "']/double[.='" + field1Value3.doubleValue() + "']"
,"//arr[@name='" + fieldName2 + "']/long[.='" + field2Value1.toString() + "']"
,"//arr[@name='" + fieldName2 + "']/long[.='" + field2Value2.toString() + "']");
}
public void testParseAndAddMultipleFieldsRoundTrip() throws Exception {
IndexSchema schema = h.getCore().getLatestSchema();
final String fieldName1 = "newfield7";
final String fieldName2 = "newfield8";
final String fieldName3 = "newfield9";
final String fieldName4 = "newfield10";
assertNull(schema.getFieldOrNull(fieldName1));
assertNull(schema.getFieldOrNull(fieldName2));
assertNull(schema.getFieldOrNull(fieldName3));
assertNull(schema.getFieldOrNull(fieldName4));
String field1String1 = "-13,258.0";
Float field1Value1 = -13258.0f;
String field1String2 = "84,828,800,808.0";
Double field1Value2 = 8.4828800808E10;
String field1String3 = "999";
Long field1Value3 = 999L;
String field2String1 = "55,123";
Integer field2Value1 = 55123;
String field2String2 = "1,234,567,890,123,456,789";
Long field2Value2 = 1234567890123456789L;
String field3String1 = "blah-blah";
String field3Value1 = field3String1;
String field3String2 = "-5.28E-3";
Double field3Value2 = -5.28E-3;
String field4String1 = "1999-04-17 17:42";
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm", Locale.ROOT).withZone(ZoneOffset.UTC);
LocalDateTime dateTime = LocalDateTime.parse(field4String1, dateTimeFormatter);
Date field4Value1 = Date.from(dateTime.atZone(ZoneOffset.UTC).toInstant());
DateTimeFormatter dateTimeFormatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss", Locale.ROOT).withZone(ZoneOffset.UTC);
String field4Value1String = dateTime.format(dateTimeFormatter2) + "Z";
SolrInputDocument d = processAdd
("parse-and-add-fields", doc(f("id", "6"), f(fieldName1, field1String1, field1String2, field1String3),
f(fieldName2, field2String1, field2String2),
f(fieldName3, field3String1, field3String2),
f(fieldName4, field4String1)));
assertNotNull(d);
schema = h.getCore().getLatestSchema();
assertNotNull(schema.getFieldOrNull(fieldName1));
assertNotNull(schema.getFieldOrNull(fieldName2));
assertNotNull(schema.getFieldOrNull(fieldName3));
assertNotNull(schema.getFieldOrNull(fieldName4));
assertEquals("pdoubles", schema.getFieldType(fieldName1).getTypeName());
assertEquals("plongs", schema.getFieldType(fieldName2).getTypeName());
assertEquals("text", schema.getFieldType(fieldName3).getTypeName());
assertEquals("pdates", schema.getFieldType(fieldName4).getTypeName());
assertU(commit());
assertQ(req("id:6")
,"//arr[@name='" + fieldName1 + "']/double[.='" + field1Value1.toString() + "']"
,"//arr[@name='" + fieldName1 + "']/double[.='" + field1Value2.toString() + "']"
,"//arr[@name='" + fieldName1 + "']/double[.='" + field1Value3.doubleValue() + "']"
,"//arr[@name='" + fieldName2 + "']/long[.='" + field2Value1.toString() + "']"
,"//arr[@name='" + fieldName2 + "']/long[.='" + field2Value2.toString() + "']"
,"//arr[@name='" + fieldName3 + "']/str[.='" + field3String1 + "']"
,"//arr[@name='" + fieldName3 + "']/str[.='" + field3String2 + "']"
,"//arr[@name='" + fieldName4 + "']/date[.='" + field4Value1String + "']");
}
public void testStringWithCopyField() throws Exception {
IndexSchema schema = h.getCore().getLatestSchema();
final String fieldName = "stringField";
final String strFieldName = fieldName+"_str";
assertNull(schema.getFieldOrNull(fieldName));
String content = "This is a text that should be copied to a string field but not be cutoff";
SolrInputDocument d = processAdd("add-fields", doc(f("id", "1"), f(fieldName, content)));
assertNotNull(d);
schema = h.getCore().getLatestSchema();
assertNotNull(schema.getFieldOrNull(fieldName));
assertNotNull(schema.getFieldOrNull(strFieldName));
assertEquals("text", schema.getFieldType(fieldName).getTypeName());
assertEquals(1, schema.getCopyFieldProperties(true, Collections.singleton(fieldName), Collections.singleton(strFieldName)).size());
}
public void testStringWithCopyFieldAndMaxChars() throws Exception {
IndexSchema schema = h.getCore().getLatestSchema();
final String fieldName = "stringField";
final String strFieldName = fieldName+"_str";
assertNull(schema.getFieldOrNull(fieldName));
String content = "This is a text that should be copied to a string field and cutoff at 10 characters";
SolrInputDocument d = processAdd("add-fields-maxchars", doc(f("id", "1"), f(fieldName, content)));
assertNotNull(d);
System.out.println("Document is "+d);
schema = h.getCore().getLatestSchema();
assertNotNull(schema.getFieldOrNull(fieldName));
assertNotNull(schema.getFieldOrNull(strFieldName));
assertEquals("text", schema.getFieldType(fieldName).getTypeName());
// We have three copyFields, one with maxChars 10 and two with maxChars 20
assertEquals(3, schema.getCopyFieldProperties(true, Collections.singleton(fieldName), null).size());
assertEquals("The configured maxChars cutoff does not exist on the copyField", 10,
schema.getCopyFieldProperties(true, Collections.singleton(fieldName), Collections.singleton(strFieldName))
.get(0).get("maxChars"));
assertEquals("The configured maxChars cutoff does not exist on the copyField", 20,
schema.getCopyFieldProperties(true, Collections.singleton(fieldName), Collections.singleton(fieldName+"_t"))
.get(0).get("maxChars"));
assertEquals("The configured maxChars cutoff does not exist on the copyField", 20,
schema.getCopyFieldProperties(true, Collections.singleton(fieldName), Collections.singleton(fieldName+"2_t"))
.get(0).get("maxChars"));
}
public void testCopyFieldByIndexing() throws Exception {
String content = "This is a text that should be copied to a string field and cutoff at 10 characters";
SolrInputDocument d = processAdd("add-fields-default-mapping", doc(f("id", "1"), f("mynewfield", content)));
assertU(commit());
ModifiableSolrParams params = new ModifiableSolrParams();
params.add("q", "*:*").add("facet", "true").add("facet.field", "mynewfield_str");
assertQ(req(params)
, "*[count(//doc)=1]"
,"//lst[@name='mynewfield_str']/int[@name='This is a '][.='1']"
);
}
@After
private void deleteCoreAndTempSolrHomeDirectory() throws Exception {
deleteCore();
}
}