more SOLR-264 work: add example to schema.xml; fix equals bug in SolrComparatorSource that Koji found; make ValueSource use IndexReader version in it's computation; refactor getSeed to use both the fieldname and the reader version

git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@550668 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Chris M. Hostetter 2007-06-26 03:16:05 +00:00
parent 4006ae52db
commit 89bf821efe
2 changed files with 92 additions and 67 deletions

View File

@ -111,6 +111,20 @@
--> -->
<fieldType name="date" class="solr.DateField" sortMissingLast="true" omitNorms="true"/> <fieldType name="date" class="solr.DateField" sortMissingLast="true" omitNorms="true"/>
<!-- The "RandomSortField" is not used to store or search any
data. You can declare fields of this type it in your schema
to generate psuedo-random orderings of your docs for sorting
purposes. The ordering is generated based on the field name
and the version of the index, As long as the index version
remains unchanged, and the same field name is reused,
the ordering of the docs will be consistent.
If you want differend psuedo-random orderings of documents,
for the same version of the index, use a dynamicField and
change the name
-->
<fieldType name="random" class="solr.RandomSortField" indexed="true" />
<!-- solr.TextField allows the specification of custom text analyzers <!-- solr.TextField allows the specification of custom text analyzers
specified as a tokenizer and a list of token filters. Different specified as a tokenizer and a list of token filters. Different
analyzers may be specified for indexing and querying. analyzers may be specified for indexing and querying.
@ -298,6 +312,8 @@
<dynamicField name="*_d" type="sdouble" indexed="true" stored="true"/> <dynamicField name="*_d" type="sdouble" indexed="true" stored="true"/>
<dynamicField name="*_dt" type="date" indexed="true" stored="true"/> <dynamicField name="*_dt" type="date" indexed="true" stored="true"/>
<dynamicField name="random*" type="random" />
<!-- uncomment the following to ignore any fields that don't already match an existing <!-- uncomment the following to ignore any fields that don't already match an existing
field name or dynamic field, rather than reporting them as an error. field name or dynamic field, rather than reporting them as an error.
alternately, change the type="ignored" to some other type e.g. "text" if you want alternately, change the type="ignored" to some other type e.g. "text" if you want

View File

@ -73,6 +73,30 @@ public class RandomSortField extends FieldType {
return key >>> 1; return key >>> 1;
} }
/**
* Given a field name and an IndexReader, get a random hash seed.
* Using dynamic fields, you can force the random order to change
*/
private static int getSeed(String fieldName, IndexReader r) {
return (int) (fieldName.hashCode()^r.getVersion() );
}
@Override
public SortField getSortField(SchemaField field, boolean reverse) {
return new RandomSort(field.getName(), reverse);
}
@Override
public ValueSource getValueSource(SchemaField field) {
return new RandomValueSource(field.getName());
}
@Override
public void write(XMLWriter xmlWriter, String name, Fieldable f) throws IOException { }
@Override
public void write(TextResponseWriter writer, String name, Fieldable f) throws IOException { }
private static class RandomComparator implements ScoreDocComparator { private static class RandomComparator implements ScoreDocComparator {
final int seed; final int seed;
@ -93,45 +117,45 @@ public class RandomSortField extends FieldType {
} }
}; };
/** given a field name, get a random hash seed -- using dynamic fields, you can force the random order to change */
private static int getSeed(String fieldName) {
return fieldName.hashCode();
}
private static class RandomSort extends SortField { private static class RandomSort extends SortField {
public RandomSort(String n, boolean reverse) { public RandomSort(String n, boolean reverse) {
super(n, SortField.CUSTOM, reverse); super(n, SortField.CUSTOM, reverse);
} }
static class RandomComparatorSource implements SortComparatorSource {
final String field;
public RandomComparatorSource( String field ){
this.field = field;
}
public ScoreDocComparator newComparator(IndexReader reader, String fieldname) throws IOException {
return new RandomComparator( getSeed(field, reader) );
}
@Override
public int hashCode() {
return field.hashCode();
}
@Override
public boolean equals(Object o) {
if( !(o instanceof RandomComparatorSource ) ) return false;
RandomComparatorSource other = (RandomComparatorSource)o;
if( !field.equals( other.field ) ) return false;
return true;
}
}
@Override @Override
public SortComparatorSource getFactory() { public SortComparatorSource getFactory() {
final int seed = getSeed(getField()); return new RandomComparatorSource( getField() );
return new SortComparatorSource() {
public ScoreDocComparator newComparator(IndexReader reader, String fieldname) throws IOException {
return new RandomComparator( (int)(seed^reader.getVersion()) );
}
@Override
public int hashCode() {
return getField().hashCode();
}
@Override
public boolean equals(Object o) {
return (o instanceof RandomSort) && getField().equals(((RandomSort) o).getField());
}
};
} }
} }
public class RandomValueSource extends ValueSource { public class RandomValueSource extends ValueSource {
private final String field; private final String field;
final int seed;
public RandomValueSource(String field) { public RandomValueSource(String field) {
this.field=field; this.field=field;
seed = getSeed(field);
} }
@Override @Override
@ -140,38 +164,39 @@ public class RandomSortField extends FieldType {
} }
@Override @Override
public DocValues getValues(IndexReader reader) throws IOException { public DocValues getValues(final IndexReader reader) throws IOException {
return new DocValues() { return new DocValues() {
@Override private final int seed = getSeed(field, reader);
public float floatVal(int doc) { @Override
return (float)hash(doc+seed); public float floatVal(int doc) {
} return (float)hash(doc+seed);
}
@Override @Override
public int intVal(int doc) { public int intVal(int doc) {
return (int)hash(doc+seed); return (int)hash(doc+seed);
} }
@Override @Override
public long longVal(int doc) { public long longVal(int doc) {
return (long)hash(doc+seed); return (long)hash(doc+seed);
} }
@Override @Override
public double doubleVal(int doc) { public double doubleVal(int doc) {
return (double)hash(doc+seed); return (double)hash(doc+seed);
} }
@Override @Override
public String strVal(int doc) { public String strVal(int doc) {
return Integer.toString(hash(doc+seed)); return Integer.toString(hash(doc+seed));
} }
@Override @Override
public String toString(int doc) { public String toString(int doc) {
return description() + '=' + intVal(doc); return description() + '=' + intVal(doc);
} }
}; };
} }
@Override @Override
@ -186,22 +211,6 @@ public class RandomSortField extends FieldType {
return field.hashCode(); return field.hashCode();
}; };
} }
@Override
public SortField getSortField(SchemaField field, boolean reverse) {
return new RandomSort(field.getName(), reverse);
}
@Override
public ValueSource getValueSource(SchemaField field) {
return new RandomValueSource(field.getName());
}
@Override
public void write(XMLWriter xmlWriter, String name, Fieldable f) throws IOException { }
@Override
public void write(TextResponseWriter writer, String name, Fieldable f) throws IOException { }
} }