You are viewing a plain text version of this content. The canonical link for it is here.
Posted to solr-commits@lucene.apache.org by ry...@apache.org on 2007/05/10 03:52:33 UTC
svn commit: r536730 - in /lucene/solr/trunk: CHANGES.txt
src/java/org/apache/solr/schema/IndexSchema.java
src/test/org/apache/solr/schema/IndexSchemaTest.java
src/test/test-files/solr/conf/schema.xml
Author: ryan
Date: Wed May 9 18:52:32 2007
New Revision: 536730
URL: http://svn.apache.org/viewvc?view=rev&rev=536730
Log:
SOLR-226 adding support for dynamic fields as copyField destination.
Added:
lucene/solr/trunk/src/test/org/apache/solr/schema/IndexSchemaTest.java (with props)
Modified:
lucene/solr/trunk/CHANGES.txt
lucene/solr/trunk/src/java/org/apache/solr/schema/IndexSchema.java
lucene/solr/trunk/src/test/test-files/solr/conf/schema.xml
Modified: lucene/solr/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/CHANGES.txt?view=diff&rev=536730&r1=536729&r2=536730
==============================================================================
--- lucene/solr/trunk/CHANGES.txt (original)
+++ lucene/solr/trunk/CHANGES.txt Wed May 9 18:52:32 2007
@@ -180,6 +180,9 @@
settings, this may halt the server. Likewise, if solrconfig.xml
defines multiple RequestHandlers with the same name it will also add
an error. (ryan)
+
+30. SOLR-226: Added support for dynamic field as the destination of a
+ copyField using glob (*) replacement. (ryan)
Changes in runtime behavior
1. Highlighting using DisMax will only pick up terms from the main
Modified: lucene/solr/trunk/src/java/org/apache/solr/schema/IndexSchema.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/schema/IndexSchema.java?view=diff&rev=536730&r1=536729&r2=536730
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/schema/IndexSchema.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/schema/IndexSchema.java Wed May 9 18:52:32 2007
@@ -498,16 +498,37 @@
NamedNodeMap attrs = node.getAttributes();
String source = DOMUtil.getAttr(attrs,"source","copyField definition");
+ String dest = DOMUtil.getAttr(attrs,"dest", "copyField definition");
boolean sourceIsPattern = isWildCard(source);
+ boolean destIsPattern = isWildCard(dest);
- String dest = DOMUtil.getAttr(attrs,"dest","copyField definition");
log.fine("copyField source='"+source+"' dest='"+dest+"'");
SchemaField d = getField(dest);
if(sourceIsPattern) {
- dCopies.add(new DynamicCopy(source, d));
- } else {
+ if( destIsPattern ) {
+ DynamicField df = null;
+ for( DynamicField dd : dynamicFields ) {
+ if( dd.regex.equals( dest ) ) {
+ df = dd;
+ break;
+ }
+ }
+ if( df == null ) {
+ throw new SolrException( 500, "copyField dynamic destination must match a dynamicField." );
+ }
+ dCopies.add(new DynamicDestCopy(source, df ));
+ }
+ else {
+ dCopies.add(new DynamicCopy(source, d));
+ }
+ }
+ else if( destIsPattern ) {
+ String msg = "copyField only supports a dynamic destination if the source is also dynamic" ;
+ throw new SolrException( 500, msg );
+ }
+ else {
// retrieve the field to force an exception if it doesn't exist
SchemaField f = getField(source);
@@ -682,25 +703,65 @@
}
}
-
- //
- // Instead of storing a type, this could be implemented as a hierarchy
- // with a virtual matches().
- // Given how often a search will be done, however, speed is the overriding
- // concern and I'm not sure which is faster.
- //
- final static class DynamicCopy extends DynamicReplacement {
+ static class DynamicCopy extends DynamicReplacement {
final SchemaField targetField;
DynamicCopy(String regex, SchemaField targetField) {
super(regex);
this.targetField = targetField;
}
+
+ public SchemaField getTargetField( String sourceField )
+ {
+ return targetField;
+ }
+ @Override
public String toString() {
return targetField.toString();
}
}
+ static class DynamicDestCopy extends DynamicCopy
+ {
+ final DynamicField dynamic;
+
+ final int dtype;
+ final String dstr;
+
+ DynamicDestCopy(String source, DynamicField dynamic) {
+ super(source, dynamic.prototype );
+ this.dynamic = dynamic;
+
+ String dest = dynamic.regex;
+ if (dest.startsWith("*")) {
+ dtype=ENDS_WITH;
+ dstr=dest.substring(1);
+ }
+ else if (dest.endsWith("*")) {
+ dtype=STARTS_WITH;
+ dstr=dest.substring(0,dest.length()-1);
+ }
+ else {
+ throw new RuntimeException("dynamic copyField destination name must start or end with *");
+ }
+ }
+
+ @Override
+ public SchemaField getTargetField( String sourceField )
+ {
+ String dyn = ( type==STARTS_WITH )
+ ? sourceField.substring( str.length() )
+ : sourceField.substring( 0, sourceField.length()-str.length() );
+
+ String name = (dtype==STARTS_WITH) ? (dstr+dyn) : (dyn+dstr);
+ return dynamic.makeSchemaField( name );
+ }
+
+ @Override
+ public String toString() {
+ return targetField.toString();
+ }
+ }
private DynamicField[] dynamicFields;
@@ -849,7 +910,7 @@
for(DynamicCopy dynamicCopy : dynamicCopyFields) {
if(dynamicCopy.matches(sourceField)) {
- matchCopyFields.add(dynamicCopy.targetField);
+ matchCopyFields.add(dynamicCopy.getTargetField(sourceField));
}
}
@@ -881,6 +942,8 @@
}
}
+
+
Added: lucene/solr/trunk/src/test/org/apache/solr/schema/IndexSchemaTest.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/test/org/apache/solr/schema/IndexSchemaTest.java?view=auto&rev=536730
==============================================================================
--- lucene/solr/trunk/src/test/org/apache/solr/schema/IndexSchemaTest.java (added)
+++ lucene/solr/trunk/src/test/org/apache/solr/schema/IndexSchemaTest.java Wed May 9 18:52:32 2007
@@ -0,0 +1,84 @@
+/**
+ * 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.HashMap;
+import java.util.Map;
+
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.request.LocalSolrQueryRequest;
+import org.apache.solr.request.MapSolrParams;
+import org.apache.solr.request.SolrParams;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.util.AbstractSolrTestCase;
+
+
+public class IndexSchemaTest extends AbstractSolrTestCase {
+
+ @Override public String getSchemaFile() { return "schema.xml"; }
+ @Override public String getSolrConfigFile() { return "solrconfig.xml"; }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ /**
+ * This test assumes the schema includes:
+ * <dynamicField name="dynamic_*" type="string" indexed="true" stored="true"/>
+ * <dynamicField name="*_dynamic" type="string" indexed="true" stored="true"/>
+ */
+ public void testDynamicCopy()
+ {
+ assertU(adoc("id", "10", "title", "test", "aaa_dynamic", "aaa"));
+ assertU(commit());
+
+ Map<String,String> args = new HashMap<String, String>();
+ args.put( SolrParams.Q, "title:test" );
+ args.put( "indent", "true" );
+ SolrQueryRequest req = new LocalSolrQueryRequest( SolrCore.getSolrCore(), new MapSolrParams( args) );
+
+ assertQ("Make sure they got in", req
+ ,"//*[@numFound='1']"
+ ,"//result/doc[1]/int[@name='id'][.='10']"
+ );
+
+ args = new HashMap<String, String>();
+ args.put( SolrParams.Q, "aaa_dynamic:aaa" );
+ args.put( "indent", "true" );
+ req = new LocalSolrQueryRequest( SolrCore.getSolrCore(), new MapSolrParams( args) );
+ assertQ("dynamic source", req
+ ,"//*[@numFound='1']"
+ ,"//result/doc[1]/int[@name='id'][.='10']"
+ );
+
+ args = new HashMap<String, String>();
+ args.put( SolrParams.Q, "dynamic_aaa:aaa" );
+ args.put( "indent", "true" );
+ req = new LocalSolrQueryRequest( SolrCore.getSolrCore(), new MapSolrParams( args) );
+ assertQ("dynamic destination", req
+ ,"//*[@numFound='1']"
+ ,"//result/doc[1]/int[@name='id'][.='10']"
+ );
+ }
+}
Propchange: lucene/solr/trunk/src/test/org/apache/solr/schema/IndexSchemaTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/solr/trunk/src/test/org/apache/solr/schema/IndexSchemaTest.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Modified: lucene/solr/trunk/src/test/test-files/solr/conf/schema.xml
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/test/test-files/solr/conf/schema.xml?view=diff&rev=536730&r1=536729&r2=536730
==============================================================================
--- lucene/solr/trunk/src/test/test-files/solr/conf/schema.xml (original)
+++ lucene/solr/trunk/src/test/test-files/solr/conf/schema.xml Wed May 9 18:52:32 2007
@@ -400,8 +400,11 @@
<dynamicField name="t_*" type="text" indexed="true" stored="true"/>
<dynamicField name="tv_*" type="text" indexed="true" stored="true"
termVectors="true" termPositions="true" termOffsets="true"/>
-
+ <!-- special fields for dynamic copyField test -->
+ <dynamicField name="dynamic_*" type="string" indexed="true" stored="true"/>
+ <dynamicField name="*_dynamic" type="string" indexed="true" stored="true"/>
+
<!-- for testing to ensure that longer patterns are matched first -->
<dynamicField name="*aa" type="string" indexed="true" stored="true"/>
<dynamicField name="*aaa" type="integer" indexed="false" stored="true"/>
@@ -426,6 +429,9 @@
<copyField source="*_t" dest="text"/>
+ <!-- dynamic destination -->
+ <copyField source="*_dynamic" dest="dynamic_*"/>
+
<!-- Similarity is the scoring routine for each document vs a query.
A custom similarity may be specified here, but the default is fine
for most applications.