Index: solr/core/src/test/org/apache/solr/schema/PolyFieldTest.java =================================================================== --- solr/core/src/test/org/apache/solr/schema/PolyFieldTest.java (revision 1158028) +++ solr/core/src/test/org/apache/solr/schema/PolyFieldTest.java (working copy) @@ -16,8 +16,8 @@ * limitations under the License. */ -import org.apache.lucene.document.Fieldable; import org.apache.lucene.queries.function.ValueSource; +import org.apache.lucene.index.IndexableField; import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.Query; @@ -83,12 +83,12 @@ assertEquals(pt.getDimension(), 2); double[] xy = new double[]{35.0, -79.34}; String point = xy[0] + "," + xy[1]; - Fieldable[] fields = home.createFields(point, 2); + IndexableField[] fields = home.createFields(point, 2); assertEquals(fields.length, 3);//should be 3, we have a stored field //first two fields contain the values, third is just stored and contains the original for (int i = 0; i < 3; i++) { boolean hasValue = fields[1].tokenStreamValue() != null - || fields[1].getBinaryValue() != null + || fields[1].binaryValue() != null || fields[1].stringValue() != null; assertTrue("Doesn't have a value: " + fields[1], hasValue); } Index: solr/core/src/test/org/apache/solr/schema/DateFieldTest.java =================================================================== --- solr/core/src/test/org/apache/solr/schema/DateFieldTest.java (revision 1158028) +++ solr/core/src/test/org/apache/solr/schema/DateFieldTest.java (working copy) @@ -18,7 +18,7 @@ package org.apache.solr.schema; import org.apache.lucene.document.Field; -import org.apache.lucene.document.Fieldable; +import org.apache.lucene.index.IndexableField; import org.apache.lucene.util.LuceneTestCase; import org.apache.solr.schema.DateField; import org.apache.solr.util.DateMathParser; @@ -119,7 +119,7 @@ public void testCreateField() { int props = FieldProperties.INDEXED ^ FieldProperties.STORED; SchemaField sf = new SchemaField( "test", f, props, null ); - Fieldable out = (Field)f.createField(sf, "1995-12-31T23:59:59Z", 1.0f ); + IndexableField out = (Field)f.createField(sf, "1995-12-31T23:59:59Z", 1.0f ); assertEquals(820454399000l, f.toObject( out ).getTime() ); out = (Field)f.createField(sf, new Date(820454399000l), 1.0f ); Index: solr/core/src/test/org/apache/solr/search/TestSort.java =================================================================== --- solr/core/src/test/org/apache/solr/search/TestSort.java (revision 1158028) +++ solr/core/src/test/org/apache/solr/search/TestSort.java (working copy) @@ -17,9 +17,13 @@ package org.apache.solr.search; +import java.io.IOException; +import java.util.*; + import org.apache.lucene.analysis.core.SimpleAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.StringField; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; @@ -29,16 +33,10 @@ import org.apache.lucene.store.RAMDirectory; import org.apache.lucene.util.OpenBitSet; import org.apache.lucene.util._TestUtil; - -import org.apache.solr.request.SolrQueryRequest; - import org.apache.solr.SolrTestCaseJ4; - +import org.apache.solr.request.SolrQueryRequest; import org.junit.BeforeClass; -import java.io.IOException; -import java.util.*; - public class TestSort extends SolrTestCaseJ4 { @BeforeClass public static void beforeClass() throws Exception { @@ -152,8 +150,8 @@ public void testSort() throws Exception { Directory dir = new RAMDirectory(); - Field f = new Field("f","0", Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS); - Field f2 = new Field("f2","0", Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS); + Field f = new Field("f",StringField.TYPE_UNSTORED,"0"); + Field f2 = new Field("f2",StringField.TYPE_UNSTORED,"0"); for (int iterCnt = 0; iterCnt 0) { if (!sfield.multiValued()) { String oldValue = map.put(sfield.getName(), val); @@ -66,12 +66,12 @@ } } // Add each field - for (Fieldable field : fields) { + for (IndexableField field : fields) { doc.add(field); } } } else { - Fieldable field = sfield.createField(val, boost); + IndexableField field = sfield.createField(val, boost); if (field != null) { if (!sfield.multiValued()) { String oldValue = map.put(sfield.getName(), val); @@ -145,10 +145,6 @@ } } - public void setBoost(float boost) { - doc.setBoost(boost); - } - public void endDoc() { } @@ -159,7 +155,7 @@ // default value are defacto 'required' fields. List missingFields = null; for (SchemaField field : schema.getRequiredFields()) { - if (doc.getFieldable(field.getName() ) == null) { + if (doc.getField(field.getName() ) == null) { if (field.getDefaultValue() != null) { addField(doc, field, field.getDefaultValue(), 1.0f); } else { @@ -176,7 +172,7 @@ // add the uniqueKey if possible if( schema.getUniqueKeyField() != null ) { String n = schema.getUniqueKeyField().getName(); - String v = doc.get( n ); + String v = doc.getField( n ).stringValue(); builder.append( "Document ["+n+"="+v+"] " ); } builder.append("missing required fields: " ); @@ -194,12 +190,12 @@ private static void addField(Document doc, SchemaField field, Object val, float boost) { if (field.isPolyField()) { - Fieldable[] farr = field.getType().createFields(field, val, boost); - for (Fieldable f : farr) { + IndexableField[] farr = field.getType().createFields(field, val, boost); + for (IndexableField f : farr) { if (f != null) doc.add(f); // null fields are not added } } else { - Fieldable f = field.createField(val, boost); + IndexableField f = field.createField(val, boost); if (f != null) doc.add(f); // null fields are not added } } @@ -231,7 +227,7 @@ public static Document toDocument( SolrInputDocument doc, IndexSchema schema ) { Document out = new Document(); - out.setBoost( doc.getDocumentBoost() ); + final float docBoost = doc.getDocumentBoost(); // Load fields from SolrDocument to Document for( SolrInputField field : doc ) { @@ -258,7 +254,7 @@ hasField = true; if (sfield != null) { used = true; - addField(out, sfield, v, boost); + addField(out, sfield, v, docBoost*boost); } // Check if we should copy this field to any other fields. @@ -267,7 +263,7 @@ for (CopyField cf : copyFields) { SchemaField destinationField = cf.getDestination(); // check if the copy field is a multivalued or not - if (!destinationField.multiValued() && out.getFieldable(destinationField.getName()) != null) { + if (!destinationField.multiValued() && out.getField(destinationField.getName()) != null) { throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "ERROR: "+getID(doc, schema)+"multiple values encountered for non multiValued copy field " + destinationField.getName() + ": " + v); @@ -281,9 +277,9 @@ val = cf.getLimitedValue((String)val); } - Fieldable [] fields = destinationField.createFields(val, boost); + IndexableField [] fields = destinationField.createFields(val, docBoost*boost); if (fields != null) { // null fields are not added - for (Fieldable f : fields) { + for (IndexableField f : fields) { if(f != null) out.add(f); } } @@ -293,7 +289,7 @@ // document boost and *all* boosts on values of that field. // For multi-valued fields, we only want to set the boost on the // first field. - boost = 1.0f; + boost = docBoost; } } catch( Exception ex ) { @@ -313,7 +309,7 @@ // Now validate required fields or add default values // fields with default values are defacto 'required' for (SchemaField field : schema.getRequiredFields()) { - if (out.getFieldable(field.getName() ) == null) { + if (out.getField(field.getName() ) == null) { if (field.getDefaultValue() != null) { addField(out, field, field.getDefaultValue(), 1.0f); } @@ -339,8 +335,8 @@ */ public SolrDocument loadStoredFields( SolrDocument doc, Document luceneDoc ) { - for( Fieldable field : luceneDoc.getFields() ) { - if( field.isStored() ) { + for( IndexableField field : luceneDoc) { + if( field.stored() ) { SchemaField sf = schema.getField( field.name() ); if( !schema.isCopyFieldTarget( sf ) ) { doc.addField( field.name(), sf.getType().toObject( field ) ); Index: solr/core/src/java/org/apache/solr/update/UpdateHandler.java =================================================================== --- solr/core/src/java/org/apache/solr/update/UpdateHandler.java (revision 1158028) +++ solr/core/src/java/org/apache/solr/update/UpdateHandler.java (working copy) @@ -19,9 +19,9 @@ import org.apache.lucene.index.IndexReader.AtomicReaderContext; +import org.apache.lucene.index.IndexableField; import org.apache.lucene.index.Term; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Fieldable; import org.apache.lucene.search.Collector; import org.apache.lucene.search.Scorer; @@ -129,7 +129,6 @@ */ public abstract void newIndexWriter() throws IOException; - public abstract int addDoc(AddUpdateCommand cmd) throws IOException; public abstract void delete(DeleteUpdateCommand cmd) throws IOException; public abstract void deleteByQuery(DeleteUpdateCommand cmd) throws IOException; Index: solr/core/src/java/org/apache/solr/update/AddUpdateCommand.java =================================================================== --- solr/core/src/java/org/apache/solr/update/AddUpdateCommand.java (revision 1158028) +++ solr/core/src/java/org/apache/solr/update/AddUpdateCommand.java (working copy) @@ -18,7 +18,7 @@ package org.apache.solr.update; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Fieldable; +import org.apache.lucene.index.IndexableField; import org.apache.lucene.index.Term; import org.apache.lucene.util.BytesRef; import org.apache.solr.common.SolrException; Index: solr/core/src/java/org/apache/solr/highlight/DefaultSolrHighlighter.java =================================================================== --- solr/core/src/java/org/apache/solr/highlight/DefaultSolrHighlighter.java (revision 1158028) +++ solr/core/src/java/org/apache/solr/highlight/DefaultSolrHighlighter.java (working copy) @@ -33,6 +33,7 @@ import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.tokenattributes.OffsetAttribute; import org.apache.lucene.document.Document; +import org.apache.lucene.index.IndexableField; import org.apache.lucene.search.Query; import org.apache.lucene.search.highlight.*; import org.apache.lucene.search.vectorhighlight.FastVectorHighlighter; @@ -416,7 +417,14 @@ // END: Hack SolrParams params = req.getParams(); - String[] docTexts = doc.getValues(fieldName); + IndexableField[] docFields = doc.getFields(fieldName); + List listFields = new ArrayList(); + for (IndexableField field : docFields) { + listFields.add(field.stringValue()); + } + + String[] docTexts = (String[]) listFields.toArray(new String[listFields.size()]); + // according to Document javadoc, doc.getValues() never returns null. check empty instead of null if (docTexts.length == 0) return; @@ -537,7 +545,15 @@ private void alternateField( NamedList docSummaries, SolrParams params, Document doc, String fieldName ){ String alternateField = params.getFieldParam(fieldName, HighlightParams.ALTERNATE_FIELD); if (alternateField != null && alternateField.length() > 0) { - String[] altTexts = doc.getValues(alternateField); + IndexableField[] docFields = doc.getFields(alternateField); + List listFields = new ArrayList(); + for (IndexableField field : docFields) { + if (field.binaryValue() == null) + listFields.add(field.stringValue()); + } + + String[] altTexts = listFields.toArray(new String[listFields.size()]); + if (altTexts != null && altTexts.length > 0){ int alternateFieldLen = params.getFieldInt(fieldName, HighlightParams.ALTERNATE_FIELD_LENGTH,0); if( alternateFieldLen <= 0 ){ Index: solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java =================================================================== --- solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java (revision 1158028) +++ solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java (working copy) @@ -34,9 +34,10 @@ import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Fieldable; import org.apache.lucene.index.FieldInfo.IndexOptions; +import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexableField; import org.apache.lucene.index.Term; import org.apache.lucene.index.Fields; import org.apache.lucene.index.FieldsEnum; @@ -163,21 +164,21 @@ /** - * @return a string representing a Fieldable's flags. + * @return a string representing a IndexableField's flags. */ - private static String getFieldFlags( Fieldable f ) + private static String getFieldFlags( IndexableField f ) { StringBuilder flags = new StringBuilder(); - flags.append( (f != null && f.isIndexed()) ? FieldFlag.INDEXED.getAbbreviation() : '-' ); - flags.append( (f != null && f.isTokenized()) ? FieldFlag.TOKENIZED.getAbbreviation() : '-' ); - flags.append( (f != null && f.isStored()) ? FieldFlag.STORED.getAbbreviation() : '-' ); + flags.append( (f != null && f.indexed()) ? FieldFlag.INDEXED.getAbbreviation() : '-' ); + flags.append( (f != null && f.tokenized()) ? FieldFlag.TOKENIZED.getAbbreviation() : '-' ); + flags.append( (f != null && f.stored()) ? FieldFlag.STORED.getAbbreviation() : '-' ); flags.append( (false) ? FieldFlag.MULTI_VALUED.getAbbreviation() : '-' ); // SchemaField Specific - flags.append( (f != null && f.isTermVectorStored()) ? FieldFlag.TERM_VECTOR_STORED.getAbbreviation() : '-' ); - flags.append( (f != null && f.isStoreOffsetWithTermVector()) ? FieldFlag.TERM_VECTOR_OFFSET.getAbbreviation() : '-' ); - flags.append( (f != null && f.isStorePositionWithTermVector()) ? FieldFlag.TERM_VECTOR_POSITION.getAbbreviation() : '-' ); - flags.append( (f != null && f.getOmitNorms()) ? FieldFlag.OMIT_NORMS.getAbbreviation() : '-' ); - flags.append( (f != null && f.isLazy()) ? FieldFlag.LAZY.getAbbreviation() : '-' ); - flags.append( (f != null && f.isBinary()) ? FieldFlag.BINARY.getAbbreviation() : '-' ); + flags.append( (f != null && f.storeTermVectors()) ? FieldFlag.TERM_VECTOR_STORED.getAbbreviation() : '-' ); + flags.append( (f != null && f.storeTermVectorOffsets()) ? FieldFlag.TERM_VECTOR_OFFSET.getAbbreviation() : '-' ); + flags.append( (f != null && f.storeTermVectorPositions()) ? FieldFlag.TERM_VECTOR_POSITION.getAbbreviation() : '-' ); + flags.append( (f != null && f.omitNorms()) ? FieldFlag.OMIT_NORMS.getAbbreviation() : '-' ); + flags.append( (f != null && f.getClass().getSimpleName().equals("LazyField")) ? FieldFlag.LAZY.getAbbreviation() : '-' ); + flags.append( (f != null && f.binaryValue()!=null) ? FieldFlag.BINARY.getAbbreviation() : '-' ); flags.append( (false) ? FieldFlag.SORT_MISSING_FIRST.getAbbreviation() : '-' ); // SchemaField Specific flags.append( (false) ? FieldFlag.SORT_MISSING_LAST.getAbbreviation() : '-' ); // SchemaField Specific return flags.toString(); @@ -239,34 +240,34 @@ final CharsRef spare = new CharsRef(); SimpleOrderedMap finfo = new SimpleOrderedMap(); for( Object o : doc.getFields() ) { - Fieldable fieldable = (Fieldable)o; + Field field = (Field)o; SimpleOrderedMap f = new SimpleOrderedMap(); - SchemaField sfield = schema.getFieldOrNull( fieldable.name() ); + SchemaField sfield = schema.getFieldOrNull( field.name() ); FieldType ftype = (sfield==null)?null:sfield.getType(); f.add( "type", (ftype==null)?null:ftype.getTypeName() ); f.add( "schema", getFieldFlags( sfield ) ); - f.add( "flags", getFieldFlags( fieldable ) ); + f.add( "flags", getFieldFlags( field ) ); - Term t = new Term(fieldable.name(), ftype!=null ? ftype.storedToIndexed(fieldable) : fieldable.stringValue()); + Term t = new Term(field.name(), ftype!=null ? ftype.storedToIndexed(field) : field.stringValue()); - f.add( "value", (ftype==null)?null:ftype.toExternal( fieldable ) ); + f.add( "value", (ftype==null)?null:ftype.toExternal( field ) ); // TODO: this really should be "stored" - f.add( "internal", fieldable.stringValue() ); // may be a binary number + f.add( "internal", field.stringValue() ); // may be a binary number - byte[] arr = fieldable.getBinaryValue(); - if (arr != null) { - f.add( "binary", Base64.byteArrayToBase64(arr, 0, arr.length)); + BytesRef bytes = field.binaryValue(); + if (bytes != null) { + f.add( "binary", Base64.byteArrayToBase64(bytes.bytes, bytes.offset, bytes.length)); } - f.add( "boost", fieldable.getBoost() ); + f.add( "boost", field.boost() ); f.add( "docFreq", t.text()==null ? 0 : reader.docFreq( t ) ); // this can be 0 for non-indexed fields // If we have a term vector, return that - if( fieldable.isTermVectorStored() ) { + if( field.storeTermVectors() ) { try { - TermFreqVector v = reader.getTermFreqVector( docId, fieldable.name() ); + TermFreqVector v = reader.getTermFreqVector( docId, field.name() ); if( v != null ) { SimpleOrderedMap tfv = new SimpleOrderedMap(); for( int i=0; iemptySet()); + //Only load the id field to get the uniqueKey of that + //field + + final String finalUniqFieldName = uniqFieldName; + + final List uniqValues = new ArrayList(); + final StoredFieldVisitor getUniqValue = new StoredFieldVisitor() { + @Override + public boolean stringField(FieldInfo fieldInfo, IndexInput in, int numUTF8Bytes) throws IOException { + if (fieldInfo.name.equals(finalUniqFieldName)) { + final byte[] b = new byte[numUTF8Bytes]; + in.readBytes(b, 0, b.length); + uniqValues.add(new String(b, "UTF-8")); + } else { + in.seek(in.getFilePointer() + numUTF8Bytes); + } + return false; + } + + @Override + public boolean intField(FieldInfo fieldInfo, int value) throws IOException { + if (fieldInfo.name.equals(finalUniqFieldName)) { + uniqValues.add(Integer.toString(value)); + } + return false; + } + + @Override + public boolean longField(FieldInfo fieldInfo, long value) throws IOException { + if (fieldInfo.name.equals(finalUniqFieldName)) { + uniqValues.add(Long.toString(value)); + } + return false; + } + }; + TVMapper mapper = new TVMapper(reader); mapper.fieldOptions = allFields; //this will only stay set if fieldOptions.isEmpty() (in other words, only if the user didn't set any fields) while (iter.hasNext()) { @@ -205,13 +239,11 @@ termVectors.add("doc-" + docId, docNL); if (keyField != null) { - Document document = reader.document(docId, fieldSelector); - Fieldable uniqId = document.getFieldable(uniqFieldName); + reader.document(docId, getUniqValue); String uniqVal = null; - if (uniqId != null) { - uniqVal = keyField.getType().storedToReadable(uniqId); - } - if (uniqVal != null) { + if (uniqValues.size() != 0) { + uniqVal = uniqValues.get(0); + uniqValues.clear(); docNL.add("uniqueKey", uniqVal); termVectors.add("uniqueKeyFieldName", uniqFieldName); } Index: solr/core/src/java/org/apache/solr/handler/MoreLikeThisHandler.java =================================================================== --- solr/core/src/java/org/apache/solr/handler/MoreLikeThisHandler.java (revision 1158028) +++ solr/core/src/java/org/apache/solr/handler/MoreLikeThisHandler.java (working copy) @@ -353,7 +353,7 @@ realMLTQuery = new BooleanQuery(); realMLTQuery.add(boostedMLTQuery, BooleanClause.Occur.MUST); realMLTQuery.add( - new TermQuery(new Term(uniqueKeyField.getName(), uniqueKeyField.getType().storedToIndexed(doc.getFieldable(uniqueKeyField.getName())))), + new TermQuery(new Term(uniqueKeyField.getName(), uniqueKeyField.getType().storedToIndexed(doc.getField(uniqueKeyField.getName())))), BooleanClause.Occur.MUST_NOT); DocListAndSet results = new DocListAndSet(); Index: solr/core/src/java/org/apache/solr/response/BinaryResponseWriter.java =================================================================== --- solr/core/src/java/org/apache/solr/response/BinaryResponseWriter.java (revision 1158028) +++ solr/core/src/java/org/apache/solr/response/BinaryResponseWriter.java (working copy) @@ -16,13 +16,17 @@ */ package org.apache.solr.response; +import java.io.*; +import java.util.*; + import org.apache.lucene.document.Document; -import org.apache.lucene.document.Fieldable; +import org.apache.lucene.index.IndexableField; +import org.apache.lucene.util.BytesRef; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.params.CommonParams; +import org.apache.solr.common.util.JavaBinCodec; import org.apache.solr.common.util.NamedList; -import org.apache.solr.common.util.JavaBinCodec; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.transform.DocTransformer; import org.apache.solr.response.transform.TransformContext; @@ -33,10 +37,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.*; -import java.util.*; - public class BinaryResponseWriter implements BinaryQueryResponseWriter { private static final Logger LOG = LoggerFactory.getLogger(BinaryResponseWriter.class); public static final Set KNOWN_TYPES = new HashSet(); @@ -159,7 +160,7 @@ public SolrDocument getDoc(Document doc) { SolrDocument solrDoc = new SolrDocument(); - for (Fieldable f : doc.getFields()) { + for (IndexableField f : doc) { String fieldName = f.name(); if( !returnFields.wantsField(fieldName) ) continue; @@ -168,8 +169,16 @@ if(sf != null) ft =sf.getType(); Object val; if (ft == null) { // handle fields not in the schema - if (f.isBinary()) val = f.getBinaryValue(); - else val = f.stringValue(); + BytesRef bytesRef = f.binaryValue(); + if (bytesRef != null) { + if (bytesRef.offset == 0 && bytesRef.length == bytesRef.bytes.length) { + val = bytesRef.bytes; + } else { + final byte[] bytes = new byte[bytesRef.length]; + val = bytes; + System.arraycopy(bytesRef.bytes, bytesRef.offset, bytes, 0, bytesRef.length); + } + } else val = f.stringValue(); } else { try { if (useFieldObjects && KNOWN_TYPES.contains(ft.getClass())) { Index: solr/core/src/java/org/apache/solr/response/TextResponseWriter.java =================================================================== --- solr/core/src/java/org/apache/solr/response/TextResponseWriter.java (revision 1158028) +++ solr/core/src/java/org/apache/solr/response/TextResponseWriter.java (working copy) @@ -22,7 +22,7 @@ import java.util.*; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Fieldable; +import org.apache.lucene.index.IndexableField; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.util.FastWriter; @@ -120,8 +120,8 @@ } else if (val instanceof String) { writeStr(name, val.toString(), true); // micro-optimization... using toString() avoids a cast first - } else if (val instanceof Fieldable) { - Fieldable f = (Fieldable)val; + } else if (val instanceof IndexableField) { + IndexableField f = (IndexableField)val; SchemaField sf = schema.getFieldOrNull( f.name() ); if( sf != null ) { sf.getType().write(this, name, f); @@ -202,7 +202,7 @@ public final SolrDocument toSolrDocument( Document doc ) { SolrDocument out = new SolrDocument(); - for( Fieldable f : doc.getFields() ) { + for( IndexableField f : doc) { // Make sure multivalued fields are represented as lists Object existing = out.get(f.name()); if (existing == null) { Index: solr/core/src/java/org/apache/solr/response/CSVResponseWriter.java =================================================================== --- solr/core/src/java/org/apache/solr/response/CSVResponseWriter.java (revision 1158028) +++ solr/core/src/java/org/apache/solr/response/CSVResponseWriter.java (working copy) @@ -20,7 +20,7 @@ import org.apache.commons.csv.CSVPrinter; import org.apache.commons.csv.CSVStrategy; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Fieldable; +import org.apache.lucene.index.IndexableField; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.SolrException; @@ -146,7 +146,7 @@ CSVSharedBufPrinter mvPrinter; // printer used to encode multiple values in a single CSV value // used to collect values - List values = new ArrayList(1); // low starting amount in case there are many fields + List values = new ArrayList(1); // low starting amount in case there are many fields int tmp; } Index: solr/core/src/java/org/apache/solr/response/JSONResponseWriter.java =================================================================== --- solr/core/src/java/org/apache/solr/response/JSONResponseWriter.java (revision 1158028) +++ solr/core/src/java/org/apache/solr/response/JSONResponseWriter.java (working copy) @@ -26,7 +26,8 @@ import java.util.Map; import java.util.Set; -import org.apache.lucene.document.Fieldable; +import org.apache.lucene.index.IndexableField; +import org.apache.lucene.util.StringHelper; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.util.NamedList; @@ -302,10 +303,10 @@ protected static class MultiValueField { final SchemaField sfield; - final ArrayList fields; - MultiValueField(SchemaField sfield, Fieldable firstVal) { + final ArrayList fields; + MultiValueField(SchemaField sfield, IndexableField firstVal) { this.sfield = sfield; - this.fields = new ArrayList(4); + this.fields = new ArrayList(4); this.fields.add(firstVal); } } Index: solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java =================================================================== --- solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java (revision 1158028) +++ solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java (working copy) @@ -20,6 +20,7 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.FieldSelector; import org.apache.lucene.document.FieldSelectorResult; +import org.apache.lucene.document.FieldSelectorVisitor; import org.apache.lucene.index.*; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.*; @@ -406,13 +407,13 @@ return doc(i, (Set)null); } - /** Retrieve a {@link Document} using a {@link org.apache.lucene.document.FieldSelector} - * This method does not currently use the Solr document cache. + /** Visit a document's fields using a {@link StoredFieldVisitor} + * This method does not currently use the Solr document cache. * - * @see IndexReader#document(int, FieldSelector) */ + * @see IndexReader#document(int, StoredFieldVisitor) */ @Override - public Document doc(int n, FieldSelector fieldSelector) throws IOException { - return getIndexReader().document(n, fieldSelector); + public void doc(int n, StoredFieldVisitor visitor) throws IOException { + getIndexReader().document(n, visitor); } /** @@ -433,8 +434,9 @@ if(!enableLazyFieldLoading || fields == null) { d = getIndexReader().document(i); } else { - d = getIndexReader().document(i, - new SetNonLazyFieldSelector(fields)); + final FieldSelectorVisitor visitor = new FieldSelectorVisitor(new SetNonLazyFieldSelector(fields)); + getIndexReader().document(i, visitor); + d = visitor.getDocument(); } if (documentCache != null) { Index: solr/core/src/java/org/apache/solr/search/Grouping.java =================================================================== --- solr/core/src/java/org/apache/solr/search/Grouping.java (revision 1158028) +++ solr/core/src/java/org/apache/solr/search/Grouping.java (working copy) @@ -18,8 +18,9 @@ package org.apache.solr.search; import org.apache.commons.lang.ArrayUtils; -import org.apache.lucene.document.Fieldable; +import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexReader.AtomicReaderContext; +import org.apache.lucene.index.IndexableField; import org.apache.lucene.queries.function.DocValues; import org.apache.lucene.queries.function.FunctionQuery; import org.apache.lucene.queries.function.ValueSource; @@ -752,7 +753,7 @@ SchemaField schemaField = searcher.getSchema().getField(groupBy); FieldType fieldType = schemaField.getType(); String readableValue = fieldType.indexedToReadable(group.groupValue.utf8ToString()); - Fieldable field = schemaField.createField(readableValue, 0.0f); + IndexableField field = schemaField.createField(readableValue, 0.0f); nl.add("groupValue", fieldType.toObject(field)); } else { nl.add("groupValue", null); Index: solr/core/src/java/org/apache/solr/spelling/FileBasedSpellChecker.java =================================================================== --- solr/core/src/java/org/apache/solr/spelling/FileBasedSpellChecker.java (revision 1158028) +++ solr/core/src/java/org/apache/solr/spelling/FileBasedSpellChecker.java (working copy) @@ -26,6 +26,7 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.TextField; import org.apache.lucene.search.spell.HighFrequencyDictionary; import org.apache.lucene.search.spell.PlainTextDictionary; import org.apache.lucene.store.RAMDirectory; @@ -100,7 +101,7 @@ for (String s : lines) { Document d = new Document(); - d.add(new Field(WORD_FIELD_NAME, s, Field.Store.NO, Field.Index.ANALYZED)); + d.add(new TextField(WORD_FIELD_NAME, s)); writer.addDocument(d); } writer.optimize(); Index: solr/contrib/analysis-extras/src/java/org/apache/solr/schema/ICUCollationField.java =================================================================== --- solr/contrib/analysis-extras/src/java/org/apache/solr/schema/ICUCollationField.java (revision 1158028) +++ solr/contrib/analysis-extras/src/java/org/apache/solr/schema/ICUCollationField.java (working copy) @@ -27,7 +27,7 @@ import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute; import org.apache.lucene.collation.ICUCollationKeyAnalyzer; -import org.apache.lucene.document.Fieldable; +import org.apache.lucene.index.IndexableField; import org.apache.lucene.search.Query; import org.apache.lucene.search.SortField; import org.apache.lucene.search.TermRangeQuery; @@ -164,7 +164,7 @@ } @Override - public void write(TextResponseWriter writer, String name, Fieldable f) throws IOException { + public void write(TextResponseWriter writer, String name, IndexableField f) throws IOException { writer.writeStr(name, f.stringValue(), true); } Index: modules/queries/src/java/org/apache/lucene/queries/mlt/MoreLikeThis.java =================================================================== --- modules/queries/src/java/org/apache/lucene/queries/mlt/MoreLikeThis.java (revision 1158028) +++ modules/queries/src/java/org/apache/lucene/queries/mlt/MoreLikeThis.java (working copy) @@ -19,7 +19,9 @@ import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexableField; import org.apache.lucene.index.Term; import org.apache.lucene.index.TermFreqVector; import org.apache.lucene.search.*; @@ -705,10 +707,10 @@ // field does not store term vector info if (vector == null) { Document d = ir.document(docNum); - String text[] = d.getValues(fieldName); - if (text != null) { - for (int j = 0; j < text.length; j++) { - addTermFrequencies(new StringReader(text[j]), termFreqMap, fieldName); + IndexableField fields[] = d.getFields(fieldName); + if (fields != null) { + for (int j = 0; j < fields.length; j++) { + addTermFrequencies(new StringReader(fields[j].stringValue()), termFreqMap, fieldName); } } } else { Index: modules/queries/src/test/org/apache/lucene/queries/function/FunctionTestSetup.java =================================================================== --- modules/queries/src/test/org/apache/lucene/queries/function/FunctionTestSetup.java (revision 1158028) +++ modules/queries/src/test/org/apache/lucene/queries/function/FunctionTestSetup.java (working copy) @@ -4,7 +4,9 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; -import org.apache.lucene.document.Fieldable; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; +import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.queries.function.valuesource.ByteFieldSource; @@ -128,23 +130,26 @@ private static void addDoc(RandomIndexWriter iw, int i) throws Exception { Document d = new Document(); - Fieldable f; + Field f; int scoreAndID = i + 1; - f = newField(ID_FIELD, id2String(scoreAndID), Field.Store.YES, Field.Index.NOT_ANALYZED); // for debug purposes - f.setOmitNorms(true); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + customType.setTokenized(false); + customType.setOmitNorms(true); + + f = newField(ID_FIELD, id2String(scoreAndID), customType); // for debug purposes d.add(f); - f = newField(TEXT_FIELD, "text of doc" + scoreAndID + textLine(i), Field.Store.NO, Field.Index.ANALYZED); // for regular search - f.setOmitNorms(true); + FieldType customType2 = new FieldType(TextField.TYPE_UNSTORED); + customType2.setOmitNorms(true); + f = newField(TEXT_FIELD, "text of doc" + scoreAndID + textLine(i), customType2); // for regular search d.add(f); - f = newField(INT_FIELD, "" + scoreAndID, Field.Store.NO, Field.Index.NOT_ANALYZED); // for function scoring - f.setOmitNorms(true); + f = newField(INT_FIELD, "" + scoreAndID, customType); // for function scoring d.add(f); - f = newField(FLOAT_FIELD, scoreAndID + ".000", Field.Store.NO, Field.Index.NOT_ANALYZED); // for function scoring - f.setOmitNorms(true); + f = newField(FLOAT_FIELD, scoreAndID + ".000", customType); // for function scoring d.add(f); iw.addDocument(d); Index: modules/queries/src/test/org/apache/lucene/queries/mlt/TestMoreLikeThis.java =================================================================== --- modules/queries/src/test/org/apache/lucene/queries/mlt/TestMoreLikeThis.java (revision 1158028) +++ modules/queries/src/test/org/apache/lucene/queries/mlt/TestMoreLikeThis.java (working copy) @@ -27,6 +27,8 @@ import org.apache.lucene.analysis.MockTokenizer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.search.BooleanClause; @@ -66,7 +68,9 @@ private void addDoc(RandomIndexWriter writer, String text) throws IOException { Document doc = new Document(); - doc.add(newField("text", text, Field.Store.YES, Field.Index.ANALYZED)); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + doc.add(newField("text", text, customType)); writer.addDocument(doc); } Index: modules/join/src/test/org/apache/lucene/search/TestBlockJoin.java =================================================================== --- modules/join/src/test/org/apache/lucene/search/TestBlockJoin.java (revision 1158028) +++ modules/join/src/test/org/apache/lucene/search/TestBlockJoin.java (working copy) @@ -24,6 +24,7 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.NumericField; +import org.apache.lucene.document.StringField; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; @@ -42,16 +43,16 @@ // One resume... private Document makeResume(String name, String country) { Document resume = new Document(); - resume.add(newField("docType", "resume", Field.Index.NOT_ANALYZED)); - resume.add(newField("name", name, Field.Store.YES, Field.Index.NOT_ANALYZED)); - resume.add(newField("country", country, Field.Index.NOT_ANALYZED)); + resume.add(newField("docType", "resume", StringField.TYPE_UNSTORED)); + resume.add(newField("name", name, StringField.TYPE_STORED)); + resume.add(newField("country", country, StringField.TYPE_UNSTORED)); return resume; } // ... has multiple jobs private Document makeJob(String skill, int year) { Document job = new Document(); - job.add(newField("skill", skill, Field.Store.YES, Field.Index.NOT_ANALYZED)); + job.add(newField("skill", skill, StringField.TYPE_STORED)); job.add(new NumericField("year").setIntValue(year)); return job; } @@ -188,15 +189,15 @@ for(int parentDocID=0;parentDocID paths = new ArrayList(); Document doc = new Document(); if (i % 2 == 0) { // 50 - doc.add(new Field("content", "foo", Store.NO, Index.ANALYZED)); + doc.add(new TextField("content", "foo")); } if (i % 3 == 0) { // 33 - doc.add(new Field("content", "bar", Store.NO, Index.ANALYZED)); + doc.add(new TextField("content", "bar")); } if (i % 4 == 0) { // 25 paths.add(new CategoryPath("a")); Index: modules/facet/src/test/org/apache/lucene/facet/FacetTestBase.java =================================================================== --- modules/facet/src/test/org/apache/lucene/facet/FacetTestBase.java (revision 1158028) +++ modules/facet/src/test/org/apache/lucene/facet/FacetTestBase.java (working copy) @@ -15,9 +15,7 @@ import org.apache.lucene.analysis.MockTokenizer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; -import org.apache.lucene.document.Field.TermVector; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.IndexReader; @@ -247,7 +245,7 @@ CategoryDocumentBuilder builder = new CategoryDocumentBuilder(tw, iParams); builder.setCategoryPaths(categories); builder.build(d); - d.add(new Field("content", content, Store.YES, Index.ANALYZED, TermVector.NO)); + d.add(new Field("content", TextField.TYPE_STORED, content)); iw.addDocument(d); } Index: modules/facet/src/test/org/apache/lucene/facet/util/TestScoredDocIDsUtils.java =================================================================== --- modules/facet/src/test/org/apache/lucene/facet/util/TestScoredDocIDsUtils.java (revision 1158028) +++ modules/facet/src/test/org/apache/lucene/facet/util/TestScoredDocIDsUtils.java (working copy) @@ -7,8 +7,8 @@ import org.apache.lucene.analysis.MockTokenizer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.StringField; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.MultiFields; import org.apache.lucene.index.RandomIndexWriter; @@ -134,7 +134,7 @@ int docNum = it.getDocID(); assertNull( "Deleted docs must not appear in the allDocsScoredDocIds set: " + docNum, - reader.document(docNum).getFieldable("del")); + reader.document(docNum).getField("del")); } assertEquals("Wrong number of (live) documents", allDocs.size(), numIteratedDocs); @@ -166,7 +166,7 @@ live != null && !live.get(docNum)); assertNull( "Complement-Set must not contain docs from the original set (doc="+ docNum+")", - reader.document(docNum).getFieldable("del")); + reader.document(docNum).getField("del")); assertFalse( "Complement-Set must not contain docs from the original set (doc="+docNum+")", resultSet.fastGet(docNum)); @@ -189,8 +189,8 @@ protected final static String delTxt = "delete"; protected final static String alphaTxt = "alpha"; - private final static Field deletionMark = new Field(field, delTxt, Store.NO, Index.NOT_ANALYZED_NO_NORMS); - private final static Field alphaContent = new Field(field, alphaTxt, Store.NO, Index.NOT_ANALYZED_NO_NORMS); + private final static Field deletionMark = new StringField(field, delTxt); + private final static Field alphaContent = new StringField(field, alphaTxt); protected final int numDocs; @@ -208,7 +208,9 @@ doc.add(deletionMark); // Add a special field for docs that are marked for deletion. Later we // assert that those docs are not returned by all-scored-doc-IDs. - doc.add(new Field("del", Integer.toString(docNum), Store.YES, Index.NO)); + FieldType ft = new FieldType(); + ft.setStored(true); + doc.add(new Field("del", ft, Integer.toString(docNum))); } if (haveAlpha(docNum)) { Index: modules/facet/src/java/org/apache/lucene/facet/index/CategoryDocumentBuilder.java =================================================================== --- modules/facet/src/java/org/apache/lucene/facet/index/CategoryDocumentBuilder.java (revision 1158028) +++ modules/facet/src/java/org/apache/lucene/facet/index/CategoryDocumentBuilder.java (working copy) @@ -10,6 +10,8 @@ import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.DocumentBuilder; import org.apache.lucene.facet.index.attributes.CategoryAttribute; @@ -183,7 +185,9 @@ // Finally creating a suitable field with stream and adding it to a // master field-list, used during the build process (see // super.build()) - fieldList.add(new Field(e.getKey(), stream)); + FieldType ft = new FieldType(TextField.TYPE_UNSTORED); + ft.setOmitNorms(true); + fieldList.add(new Field(e.getKey(), ft, stream)); } return this; @@ -289,7 +293,6 @@ */ public Document build(Document doc) { for (Field f : fieldList) { - f.setOmitNorms(true); doc.add(f); } return doc; Index: modules/facet/src/java/org/apache/lucene/facet/taxonomy/lucene/LuceneTaxonomyWriter.java =================================================================== --- modules/facet/src/java/org/apache/lucene/facet/taxonomy/lucene/LuceneTaxonomyWriter.java (revision 1158028) +++ modules/facet/src/java/org/apache/lucene/facet/taxonomy/lucene/LuceneTaxonomyWriter.java (working copy) @@ -17,8 +17,9 @@ import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.StringField; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.FieldInfo.IndexOptions; @@ -179,10 +180,12 @@ openLuceneIndex(directory, openMode); reader = null; - parentStreamField = new Field(Consts.FIELD_PAYLOADS, parentStream); - parentStreamField.setOmitNorms(true); - fullPathField = new Field(Consts.FULL, "", Store.YES, Index.NOT_ANALYZED_NO_NORMS); - fullPathField.setIndexOptions(IndexOptions.DOCS_ONLY); + FieldType ft = new FieldType(TextField.TYPE_UNSTORED); + ft.setOmitNorms(true); + parentStreamField = new Field(Consts.FIELD_PAYLOADS, ft, parentStream); + FieldType ft2 = new FieldType(StringField.TYPE_STORED); + ft2.setIndexOptions(IndexOptions.DOCS_ONLY); + fullPathField = new Field(Consts.FULL, ft2, ""); this.nextID = indexWriter.maxDoc(); Index: modules/facet/src/java/org/apache/lucene/facet/taxonomy/lucene/Consts.java =================================================================== --- modules/facet/src/java/org/apache/lucene/facet/taxonomy/lucene/Consts.java (revision 1158028) +++ modules/facet/src/java/org/apache/lucene/facet/taxonomy/lucene/Consts.java (working copy) @@ -1,8 +1,11 @@ package org.apache.lucene.facet.taxonomy.lucene; -import org.apache.lucene.document.FieldSelector; -import org.apache.lucene.document.FieldSelectorResult; +import java.io.IOException; +import org.apache.lucene.index.FieldInfo; +import org.apache.lucene.index.StoredFieldVisitor; +import org.apache.lucene.store.IndexInput; + /** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -31,18 +34,27 @@ static final char[] PAYLOAD_PARENT_CHARS = PAYLOAD_PARENT.toCharArray(); /** - * The following is a "field selector", an object which tells Lucene to - * extract only a single field rather than a whole document. + * The following is a "stored field visitor", an object + * which tells Lucene to extract only a single field + * rather than a whole document. */ - public static final FieldSelector fullPathSelector = new FieldSelector() { - public FieldSelectorResult accept(String fieldName) { - if (fieldName.equals(FULL)) { - return FieldSelectorResult.LOAD_AND_BREAK; - } - return FieldSelectorResult.NO_LOAD; - } - }; + public static final class LoadFullPathOnly extends StoredFieldVisitor { + private String fullPath; + public boolean stringField(FieldInfo fieldInfo, IndexInput in, int numUTF8Bytes) throws IOException { + final byte[] bytes = new byte[numUTF8Bytes]; + in.readBytes(bytes, 0, bytes.length); + fullPath = new String(bytes, "UTF-8"); + + // Stop loading: + return true; + } + + public String getFullPath() { + return fullPath; + } + } + /** * Delimiter used for creating the full path of a category from the list of * its labels from root. It is forbidden for labels to contain this Index: modules/facet/src/java/org/apache/lucene/facet/taxonomy/lucene/LuceneTaxonomyReader.java =================================================================== --- modules/facet/src/java/org/apache/lucene/facet/taxonomy/lucene/LuceneTaxonomyReader.java (revision 1158028) +++ modules/facet/src/java/org/apache/lucene/facet/taxonomy/lucene/LuceneTaxonomyReader.java (working copy) @@ -21,6 +21,7 @@ import org.apache.lucene.facet.taxonomy.CategoryPath; import org.apache.lucene.facet.taxonomy.TaxonomyReader; +import org.apache.lucene.facet.taxonomy.lucene.Consts.LoadFullPathOnly; import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.collections.LRUHashMap; @@ -295,8 +296,9 @@ if (catID<0 || catID>=indexReader.maxDoc()) { return null; } - ret = indexReader.document(catID, Consts.fullPathSelector) - .get(Consts.FULL); + final LoadFullPathOnly loader = new LoadFullPathOnly(); + indexReader.document(catID, loader); + ret = loader.getFullPath(); } finally { indexReaderLock.readLock().unlock(); } Index: modules/facet/src/examples/org/apache/lucene/facet/example/multiCL/MultiCLIndexer.java =================================================================== --- modules/facet/src/examples/org/apache/lucene/facet/example/multiCL/MultiCLIndexer.java (revision 1158028) +++ modules/facet/src/examples/org/apache/lucene/facet/example/multiCL/MultiCLIndexer.java (working copy) @@ -6,8 +6,7 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.Term; @@ -174,8 +173,8 @@ // create a plain Lucene document and add some regular Lucene fields // to it Document doc = new Document(); - doc.add(new Field(SimpleUtils.TITLE, docTitles[docNum], Store.YES, Index.ANALYZED)); - doc.add(new Field(SimpleUtils.TEXT, docTexts[docNum], Store.NO, Index.ANALYZED)); + doc.add(new Field(SimpleUtils.TITLE, TextField.TYPE_STORED, docTitles[docNum])); + doc.add(new TextField(SimpleUtils.TEXT, docTexts[docNum])); // finally add the document to the index categoryDocBuilder.build(doc); Index: modules/facet/src/examples/org/apache/lucene/facet/example/simple/SimpleIndexer.java =================================================================== --- modules/facet/src/examples/org/apache/lucene/facet/example/simple/SimpleIndexer.java (revision 1158028) +++ modules/facet/src/examples/org/apache/lucene/facet/example/simple/SimpleIndexer.java (working copy) @@ -5,8 +5,7 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.IndexWriterConfig.OpenMode; @@ -71,8 +70,8 @@ // create a plain Lucene document and add some regular Lucene fields to it Document doc = new Document(); - doc.add(new Field(SimpleUtils.TITLE, SimpleUtils.docTitles[docNum], Store.YES, Index.ANALYZED)); - doc.add(new Field(SimpleUtils.TEXT, SimpleUtils.docTexts[docNum], Store.NO, Index.ANALYZED)); + doc.add(new Field(SimpleUtils.TITLE, TextField.TYPE_STORED, SimpleUtils.docTitles[docNum])); + doc.add(new TextField(SimpleUtils.TEXT, SimpleUtils.docTexts[docNum])); // invoke the category document builder for adding categories to the document and, // as required, to the taxonomy index Index: modules/facet/src/examples/org/apache/lucene/facet/example/association/AssociationIndexer.java =================================================================== --- modules/facet/src/examples/org/apache/lucene/facet/example/association/AssociationIndexer.java (revision 1158028) +++ modules/facet/src/examples/org/apache/lucene/facet/example/association/AssociationIndexer.java (working copy) @@ -2,8 +2,7 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.IndexWriterConfig.OpenMode; @@ -94,10 +93,8 @@ // create a plain Lucene document and add some regular Lucene fields // to it Document doc = new Document(); - doc.add(new Field(SimpleUtils.TITLE, SimpleUtils.docTitles[docNum], - Store.YES, Index.ANALYZED)); - doc.add(new Field(SimpleUtils.TEXT, SimpleUtils.docTexts[docNum], - Store.NO, Index.ANALYZED)); + doc.add(new Field(SimpleUtils.TITLE, TextField.TYPE_STORED, SimpleUtils.docTitles[docNum])); + doc.add(new TextField(SimpleUtils.TEXT, SimpleUtils.docTexts[docNum])); // invoke the category document builder for adding categories to the // document and, Index: modules/queryparser/src/test/org/apache/lucene/queryparser/classic/TestMultiFieldQueryParser.java =================================================================== --- modules/queryparser/src/test/org/apache/lucene/queryparser/classic/TestMultiFieldQueryParser.java (revision 1158028) +++ modules/queryparser/src/test/org/apache/lucene/queryparser/classic/TestMultiFieldQueryParser.java (working copy) @@ -26,7 +26,7 @@ import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.IndexSearcher; @@ -284,7 +284,7 @@ Directory ramDir = newDirectory(); IndexWriter iw = new IndexWriter(ramDir, newIndexWriterConfig(TEST_VERSION_CURRENT, analyzer)); Document doc = new Document(); - doc.add(newField("body", "blah the footest blah", Field.Store.NO, Field.Index.ANALYZED)); + doc.add(newField("body", "blah the footest blah", TextField.TYPE_UNSTORED)); iw.addDocument(doc); iw.close(); Index: modules/queryparser/src/test/org/apache/lucene/queryparser/classic/TestQueryParser.java =================================================================== --- modules/queryparser/src/test/org/apache/lucene/queryparser/classic/TestQueryParser.java (revision 1158028) +++ modules/queryparser/src/test/org/apache/lucene/queryparser/classic/TestQueryParser.java (working copy) @@ -37,7 +37,7 @@ import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute; import org.apache.lucene.document.DateTools; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.index.IndexReader; @@ -1092,7 +1092,7 @@ Analyzer a = new MockAnalyzer(random, MockTokenizer.SIMPLE, true, MockTokenFilter.ENGLISH_STOPSET, true); IndexWriter w = new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, a)); Document doc = new Document(); - doc.add(newField("f", "the wizard of ozzy", Field.Store.NO, Field.Index.ANALYZED)); + doc.add(newField("f", "the wizard of ozzy", TextField.TYPE_UNSTORED)); w.addDocument(doc); IndexReader r = IndexReader.open(w, true); w.close(); Index: modules/queryparser/src/test/org/apache/lucene/queryparser/surround/query/SingleFieldTestDb.java =================================================================== --- modules/queryparser/src/test/org/apache/lucene/queryparser/surround/query/SingleFieldTestDb.java (revision 1158028) +++ modules/queryparser/src/test/org/apache/lucene/queryparser/surround/query/SingleFieldTestDb.java (working copy) @@ -26,6 +26,7 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; @@ -44,7 +45,7 @@ new MockAnalyzer(random))); for (int j = 0; j < docs.length; j++) { Document d = new Document(); - d.add(new Field(fieldName, docs[j], Field.Store.NO, Field.Index.ANALYZED)); + d.add(new Field(fieldName, TextField.TYPE_UNSTORED, docs[j])); writer.addDocument(d); } writer.close(); Index: modules/queryparser/src/test/org/apache/lucene/queryparser/complexPhrase/TestComplexPhraseQuery.java =================================================================== --- modules/queryparser/src/test/org/apache/lucene/queryparser/complexPhrase/TestComplexPhraseQuery.java (revision 1158028) +++ modules/queryparser/src/test/org/apache/lucene/queryparser/complexPhrase/TestComplexPhraseQuery.java (working copy) @@ -22,7 +22,8 @@ import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.queryparser.classic.QueryParser; import org.apache.lucene.search.IndexSearcher; @@ -113,12 +114,12 @@ super.setUp(); rd = newDirectory(); IndexWriter w = new IndexWriter(rd, newIndexWriterConfig(TEST_VERSION_CURRENT, analyzer)); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); for (int i = 0; i < docsContent.length; i++) { Document doc = new Document(); - doc.add(newField("name", docsContent[i].name, Field.Store.YES, - Field.Index.ANALYZED)); - doc.add(newField("id", docsContent[i].id, Field.Store.YES, - Field.Index.ANALYZED)); + doc.add(newField("name", docsContent[i].name, customType)); + doc.add(newField("id", docsContent[i].id, customType)); w.addDocument(doc); } w.close(); Index: modules/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestMultiFieldQPHelper.java =================================================================== --- modules/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestMultiFieldQPHelper.java (revision 1158028) +++ modules/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestMultiFieldQPHelper.java (working copy) @@ -25,7 +25,7 @@ import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.queryparser.flexible.core.QueryNodeException; import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler; @@ -321,8 +321,7 @@ Directory ramDir = newDirectory(); IndexWriter iw = new IndexWriter(ramDir, newIndexWriterConfig(TEST_VERSION_CURRENT, analyzer)); Document doc = new Document(); - doc.add(newField("body", "blah the footest blah", Field.Store.NO, - Field.Index.ANALYZED)); + doc.add(newField("body", "blah the footest blah", TextField.TYPE_UNSTORED)); iw.addDocument(doc); iw.close(); Index: modules/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestQPHelper.java =================================================================== --- modules/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestQPHelper.java (revision 1158028) +++ modules/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestQPHelper.java (working copy) @@ -40,7 +40,7 @@ import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute; import org.apache.lucene.document.DateTools; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Term; @@ -1242,7 +1242,7 @@ Directory dir = newDirectory(); IndexWriter w = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new CannedAnalyzer())); Document doc = new Document(); - doc.add(newField("field", "", Field.Store.NO, Field.Index.ANALYZED)); + doc.add(newField("field", "", TextField.TYPE_UNSTORED)); w.addDocument(doc); IndexReader r = IndexReader.open(w, true); IndexSearcher s = newSearcher(r); Index: modules/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestNumericQueryParser.java =================================================================== --- modules/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestNumericQueryParser.java (revision 1158028) +++ modules/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestNumericQueryParser.java (working copy) @@ -194,8 +194,7 @@ numericConfigMap.put(type.name(), new NumericConfig(PRECISION_STEP, NUMBER_FORMAT, type)); - NumericField field = new NumericField(type.name(), PRECISION_STEP, - Field.Store.YES, true); + NumericField field = new NumericField(type.name(), PRECISION_STEP, NumericField.TYPE_STORED); numericFieldMap.put(type.name(), field); doc.add(field); @@ -204,8 +203,7 @@ numericConfigMap.put(DATE_FIELD_NAME, new NumericConfig(PRECISION_STEP, DATE_FORMAT, NumericField.DataType.LONG)); - NumericField dateField = new NumericField(DATE_FIELD_NAME, PRECISION_STEP, - Field.Store.YES, true); + NumericField dateField = new NumericField(DATE_FIELD_NAME, PRECISION_STEP, NumericField.TYPE_STORED); numericFieldMap.put(DATE_FIELD_NAME, dateField); doc.add(dateField); Index: modules/analysis/common/src/test/org/apache/lucene/analysis/core/TestClassicAnalyzer.java =================================================================== --- modules/analysis/common/src/test/org/apache/lucene/analysis/core/TestClassicAnalyzer.java (revision 1158028) +++ modules/analysis/common/src/test/org/apache/lucene/analysis/core/TestClassicAnalyzer.java (working copy) @@ -4,7 +4,7 @@ import org.apache.lucene.analysis.BaseTokenStreamTestCase; import org.apache.lucene.analysis.standard.ClassicAnalyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.DocsAndPositionsEnum; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.IndexReader; @@ -261,12 +261,12 @@ // This produces a too-long term: String contents = "abc xyz x" + bigTerm + " another term"; - doc.add(new Field("content", contents, Field.Store.NO, Field.Index.ANALYZED)); + doc.add(new TextField("content", contents)); writer.addDocument(doc); // Make sure we can add another normal document doc = new Document(); - doc.add(new Field("content", "abc bbb ccc", Field.Store.NO, Field.Index.ANALYZED)); + doc.add(new TextField("content", "abc bbb ccc")); writer.addDocument(doc); writer.close(); @@ -297,7 +297,7 @@ // Make sure we can add a document with exactly the // maximum length term, and search on that term: doc = new Document(); - doc.add(new Field("content", bigTerm, Field.Store.NO, Field.Index.ANALYZED)); + doc.add(new TextField("content", bigTerm)); ClassicAnalyzer sa = new ClassicAnalyzer(TEST_VERSION_CURRENT); sa.setMaxTokenLength(100000); writer = new IndexWriter(dir, new IndexWriterConfig(TEST_VERSION_CURRENT, sa)); Index: modules/analysis/common/src/test/org/apache/lucene/analysis/core/TestKeywordAnalyzer.java =================================================================== --- modules/analysis/common/src/test/org/apache/lucene/analysis/core/TestKeywordAnalyzer.java (revision 1158028) +++ modules/analysis/common/src/test/org/apache/lucene/analysis/core/TestKeywordAnalyzer.java (working copy) @@ -24,6 +24,8 @@ import org.apache.lucene.analysis.tokenattributes.OffsetAttribute; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.StringField; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; @@ -46,8 +48,8 @@ TEST_VERSION_CURRENT, new SimpleAnalyzer(TEST_VERSION_CURRENT))); Document doc = new Document(); - doc.add(new Field("partnum", "Q36", Field.Store.YES, Field.Index.NOT_ANALYZED)); - doc.add(new Field("description", "Illidium Space Modulator", Field.Store.YES, Field.Index.ANALYZED)); + doc.add(new Field("partnum", StringField.TYPE_STORED, "Q36")); + doc.add(new Field("description", TextField.TYPE_STORED, "Illidium Space Modulator")); writer.addDocument(doc); writer.close(); @@ -74,10 +76,10 @@ RAMDirectory dir = new RAMDirectory(); IndexWriter writer = new IndexWriter(dir, new IndexWriterConfig(TEST_VERSION_CURRENT, new KeywordAnalyzer())); Document doc = new Document(); - doc.add(new Field("partnum", "Q36", Field.Store.YES, Field.Index.ANALYZED)); + doc.add(new Field("partnum", TextField.TYPE_STORED, "Q36")); writer.addDocument(doc); doc = new Document(); - doc.add(new Field("partnum", "Q37", Field.Store.YES, Field.Index.ANALYZED)); + doc.add(new Field("partnum", TextField.TYPE_STORED, "Q37")); writer.addDocument(doc); writer.close(); Index: modules/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenCountAnalyzer.java =================================================================== --- modules/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenCountAnalyzer.java (revision 1158028) +++ modules/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenCountAnalyzer.java (working copy) @@ -26,7 +26,7 @@ import org.apache.lucene.analysis.core.WhitespaceAnalyzer; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; @@ -58,7 +58,7 @@ for(int i=0;i<10000;i++) b.append(" a"); b.append(" x"); - doc.add(newField("field", b.toString(), Field.Store.NO, Field.Index.ANALYZED)); + doc.add(newField("field", b.toString(), TextField.TYPE_UNSTORED)); writer.addDocument(doc); writer.close(); Index: modules/analysis/common/src/test/org/apache/lucene/analysis/query/QueryAutoStopWordAnalyzerTest.java =================================================================== --- modules/analysis/common/src/test/org/apache/lucene/analysis/query/QueryAutoStopWordAnalyzerTest.java (revision 1158028) +++ modules/analysis/common/src/test/org/apache/lucene/analysis/query/QueryAutoStopWordAnalyzerTest.java (working copy) @@ -26,6 +26,7 @@ import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; @@ -51,8 +52,8 @@ Document doc = new Document(); String variedFieldValue = variedFieldValues[i % variedFieldValues.length]; String repetitiveFieldValue = repetitiveFieldValues[i % repetitiveFieldValues.length]; - doc.add(new Field("variedField", variedFieldValue, Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("repetitiveField", repetitiveFieldValue, Field.Store.YES, Field.Index.ANALYZED)); + doc.add(new Field("variedField", TextField.TYPE_STORED, variedFieldValue)); + doc.add(new Field("repetitiveField", TextField.TYPE_STORED, repetitiveFieldValue)); writer.addDocument(doc); } writer.close(); Index: modules/analysis/common/src/test/org/apache/lucene/analysis/sinks/TestTeeSinkTokenFilter.java =================================================================== --- modules/analysis/common/src/test/org/apache/lucene/analysis/sinks/TestTeeSinkTokenFilter.java (revision 1158028) +++ modules/analysis/common/src/test/org/apache/lucene/analysis/sinks/TestTeeSinkTokenFilter.java (working copy) @@ -29,6 +29,8 @@ import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.TermPositionVector; @@ -89,8 +91,12 @@ Document doc = new Document(); TeeSinkTokenFilter tee = new TeeSinkTokenFilter(analyzer.tokenStream("field", new StringReader("abcd "))); TokenStream sink = tee.newSinkTokenStream(); - Field f1 = new Field("field", tee, Field.TermVector.WITH_POSITIONS_OFFSETS); - Field f2 = new Field("field", sink, Field.TermVector.WITH_POSITIONS_OFFSETS); + FieldType ft = new FieldType(TextField.TYPE_UNSTORED); + ft.setStoreTermVectors(true); + ft.setStoreTermVectorOffsets(true); + ft.setStoreTermVectorPositions(true); + Field f1 = new Field("field", ft, tee); + Field f2 = new Field("field", ft, sink); doc.add(f1); doc.add(f2); w.addDocument(doc); Index: modules/analysis/common/src/test/org/apache/lucene/analysis/shingle/ShingleAnalyzerWrapperTest.java =================================================================== --- modules/analysis/common/src/test/org/apache/lucene/analysis/shingle/ShingleAnalyzerWrapperTest.java (revision 1158028) +++ modules/analysis/common/src/test/org/apache/lucene/analysis/shingle/ShingleAnalyzerWrapperTest.java (working copy) @@ -29,6 +29,7 @@ import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.Term; @@ -56,18 +57,15 @@ Document doc; doc = new Document(); - doc.add(new Field("content", "please divide this sentence into shingles", - Field.Store.YES,Field.Index.ANALYZED)); + doc.add(new Field("content", TextField.TYPE_STORED, "please divide this sentence into shingles")); writer.addDocument(doc); doc = new Document(); - doc.add(new Field("content", "just another test sentence", - Field.Store.YES,Field.Index.ANALYZED)); + doc.add(new Field("content", TextField.TYPE_STORED, "just another test sentence")); writer.addDocument(doc); doc = new Document(); - doc.add(new Field("content", "a sentence which contains no test", - Field.Store.YES,Field.Index.ANALYZED)); + doc.add(new Field("content", TextField.TYPE_STORED, "a sentence which contains no test")); writer.addDocument(doc); writer.close(); Index: modules/analysis/common/src/test/org/apache/lucene/collation/CollationTestBase.java =================================================================== --- modules/analysis/common/src/test/org/apache/lucene/collation/CollationTestBase.java (revision 1158028) +++ modules/analysis/common/src/test/org/apache/lucene/collation/CollationTestBase.java (working copy) @@ -26,6 +26,7 @@ import org.apache.lucene.store.RAMDirectory; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.index.IndexableField; import org.apache.lucene.index.Term; import org.apache.lucene.index.IndexReader; import org.apache.lucene.search.ScoreDoc; @@ -36,8 +37,11 @@ import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Sort; import org.apache.lucene.search.SortField; +import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; -import org.apache.lucene.document.Document; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.StringField; +import org.apache.lucene.document.TextField; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IndexableBinaryStringTools; import org.apache.lucene.util.LuceneTestCase; @@ -81,10 +85,8 @@ IndexWriter writer = new IndexWriter(ramDir, new IndexWriterConfig( TEST_VERSION_CURRENT, analyzer)); Document doc = new Document(); - doc.add(new Field("content", "\u0633\u0627\u0628", - Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("body", "body", - Field.Store.YES, Field.Index.NOT_ANALYZED)); + doc.add(new Field("content", TextField.TYPE_STORED, "\u0633\u0627\u0628")); + doc.add(new Field("body", StringField.TYPE_STORED, "body")); writer.addDocument(doc); writer.close(); IndexSearcher searcher = new IndexSearcher(ramDir, true); @@ -118,8 +120,7 @@ // orders the U+0698 character before the U+0633 character, so the single // index Term below should NOT be returned by a TermRangeQuery with a Farsi // Collator (or an Arabic one for the case when Farsi is not supported). - doc.add(new Field("content", "\u0633\u0627\u0628", - Field.Store.YES, Field.Index.ANALYZED)); + doc.add(new Field("content", TextField.TYPE_STORED, "\u0633\u0627\u0628")); writer.addDocument(doc); writer.close(); IndexSearcher searcher = new IndexSearcher(ramDir, true); @@ -141,10 +142,8 @@ IndexWriter writer = new IndexWriter(farsiIndex, new IndexWriterConfig( TEST_VERSION_CURRENT, analyzer)); Document doc = new Document(); - doc.add(new Field("content", "\u0633\u0627\u0628", - Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("body", "body", - Field.Store.YES, Field.Index.NOT_ANALYZED)); + doc.add(new Field("content", TextField.TYPE_STORED, "\u0633\u0627\u0628")); + doc.add(new Field("body", StringField.TYPE_STORED, "body")); writer.addDocument(doc); writer.close(); @@ -204,20 +203,21 @@ { "J", "y", "HOT", "HOT", "HOT", "HOT" }, }; + FieldType customType = new FieldType(); + customType.setStored(true); + for (int i = 0 ; i < sortData.length ; ++i) { Document doc = new Document(); - doc.add(new Field("tracer", sortData[i][0], - Field.Store.YES, Field.Index.NO)); - doc.add(new Field("contents", sortData[i][1], - Field.Store.NO, Field.Index.ANALYZED)); + doc.add(new Field("tracer", customType, sortData[i][0])); + doc.add(new TextField("contents", sortData[i][1])); if (sortData[i][2] != null) - doc.add(new Field("US", usAnalyzer.reusableTokenStream("US", new StringReader(sortData[i][2])))); + doc.add(new TextField("US", usAnalyzer.reusableTokenStream("US", new StringReader(sortData[i][2])))); if (sortData[i][3] != null) - doc.add(new Field("France", franceAnalyzer.reusableTokenStream("France", new StringReader(sortData[i][3])))); + doc.add(new TextField("France", franceAnalyzer.reusableTokenStream("France", new StringReader(sortData[i][3])))); if (sortData[i][4] != null) - doc.add(new Field("Sweden", swedenAnalyzer.reusableTokenStream("Sweden", new StringReader(sortData[i][4])))); + doc.add(new TextField("Sweden", swedenAnalyzer.reusableTokenStream("Sweden", new StringReader(sortData[i][4])))); if (sortData[i][5] != null) - doc.add(new Field("Denmark", denmarkAnalyzer.reusableTokenStream("Denmark", new StringReader(sortData[i][5])))); + doc.add(new TextField("Denmark", denmarkAnalyzer.reusableTokenStream("Denmark", new StringReader(sortData[i][5])))); writer.addDocument(doc); } writer.optimize(); @@ -250,9 +250,9 @@ int n = result.length; for (int i = 0 ; i < n ; ++i) { Document doc = searcher.doc(result[i].doc); - String[] v = doc.getValues("tracer"); + IndexableField[] v = doc.getFields("tracer"); for (int j = 0 ; j < v.length ; ++j) { - buff.append(v[j]); + buff.append(v[j].stringValue()); } } assertEquals(expectedResult, buff.toString()); Index: modules/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/PerFieldAnalyzerWrapper.java =================================================================== --- modules/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/PerFieldAnalyzerWrapper.java (revision 1158028) +++ modules/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/PerFieldAnalyzerWrapper.java (working copy) @@ -19,7 +19,7 @@ import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; -import org.apache.lucene.document.Fieldable; +import org.apache.lucene.index.IndexableField; import java.io.Reader; import java.io.IOException; @@ -119,10 +119,11 @@ /** Return the offsetGap from the analyzer assigned to field */ @Override - public int getOffsetGap(Fieldable field) { + public int getOffsetGap(IndexableField field) { Analyzer analyzer = analyzerMap.get(field.name()); - if (analyzer == null) + if (analyzer == null) { analyzer = defaultAnalyzer; + } return analyzer.getOffsetGap(field); } Index: modules/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/LimitTokenCountAnalyzer.java =================================================================== --- modules/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/LimitTokenCountAnalyzer.java (revision 1158028) +++ modules/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/LimitTokenCountAnalyzer.java (working copy) @@ -17,9 +17,9 @@ * limitations under the License. */ -import org.apache.lucene.document.Fieldable; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.index.IndexableField; import java.io.Reader; import java.io.IOException; @@ -60,7 +60,7 @@ } @Override - public int getOffsetGap(Fieldable field) { + public int getOffsetGap(IndexableField field) { return delegate.getOffsetGap(field); } Index: modules/benchmark/src/test/org/apache/lucene/benchmark/byTask/tasks/WriteLineDocTaskTest.java =================================================================== --- modules/benchmark/src/test/org/apache/lucene/benchmark/byTask/tasks/WriteLineDocTaskTest.java (revision 1158028) +++ modules/benchmark/src/test/org/apache/lucene/benchmark/byTask/tasks/WriteLineDocTaskTest.java (working copy) @@ -34,8 +34,7 @@ import org.apache.lucene.benchmark.byTask.utils.StreamUtils.Type; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; +import org.apache.lucene.document.StringField; /** Tests the functionality of {@link WriteLineDocTask}. */ public class WriteLineDocTaskTest extends BenchmarkTestCase { @@ -46,9 +45,9 @@ @Override public Document makeDocument() throws Exception { Document doc = new Document(); - doc.add(new Field(BODY_FIELD, "body", Store.NO, Index.NOT_ANALYZED_NO_NORMS)); - doc.add(new Field(TITLE_FIELD, "title", Store.NO, Index.NOT_ANALYZED_NO_NORMS)); - doc.add(new Field(DATE_FIELD, "date", Store.NO, Index.NOT_ANALYZED_NO_NORMS)); + doc.add(new StringField(BODY_FIELD, "body")); + doc.add(new StringField(TITLE_FIELD, "title")); + doc.add(new StringField(DATE_FIELD, "date")); return doc; } @@ -60,9 +59,9 @@ @Override public Document makeDocument() throws Exception { Document doc = new Document(); - doc.add(new Field(BODY_FIELD, "body\r\ntext\ttwo", Store.NO, Index.NOT_ANALYZED_NO_NORMS)); - doc.add(new Field(TITLE_FIELD, "title\r\ntext", Store.NO, Index.NOT_ANALYZED_NO_NORMS)); - doc.add(new Field(DATE_FIELD, "date\r\ntext", Store.NO, Index.NOT_ANALYZED_NO_NORMS)); + doc.add(new StringField(BODY_FIELD, "body\r\ntext\ttwo")); + doc.add(new StringField(TITLE_FIELD, "title\r\ntext")); + doc.add(new StringField(DATE_FIELD, "date\r\ntext")); return doc; } @@ -73,8 +72,8 @@ @Override public Document makeDocument() throws Exception { Document doc = new Document(); - doc.add(new Field(TITLE_FIELD, "title", Store.NO, Index.NOT_ANALYZED_NO_NORMS)); - doc.add(new Field(DATE_FIELD, "date", Store.NO, Index.NOT_ANALYZED_NO_NORMS)); + doc.add(new StringField(TITLE_FIELD, "title")); + doc.add(new StringField(DATE_FIELD, "date")); return doc; } } @@ -84,8 +83,8 @@ @Override public Document makeDocument() throws Exception { Document doc = new Document(); - doc.add(new Field(BODY_FIELD, "body", Store.NO, Index.NOT_ANALYZED_NO_NORMS)); - doc.add(new Field(DATE_FIELD, "date", Store.NO, Index.NOT_ANALYZED_NO_NORMS)); + doc.add(new StringField(BODY_FIELD, "body")); + doc.add(new StringField(DATE_FIELD, "date")); return doc; } } @@ -95,7 +94,7 @@ @Override public Document makeDocument() throws Exception { Document doc = new Document(); - doc.add(new Field(DATE_FIELD, "date", Store.NO, Index.NOT_ANALYZED_NO_NORMS)); + doc.add(new StringField(DATE_FIELD, "date")); return doc; } } @@ -106,7 +105,7 @@ @Override public Document makeDocument() throws Exception { Document doc = new Document(); - doc.add(new Field(DATE_FIELD, "date", Store.NO, Index.NOT_ANALYZED_NO_NORMS)); + doc.add(new StringField(DATE_FIELD, "date")); return doc; } } @@ -126,9 +125,9 @@ public Document makeDocument() throws Exception { Document doc = new Document(); String name = Thread.currentThread().getName(); - doc.add(new Field(BODY_FIELD, "body_" + name, Store.NO, Index.NOT_ANALYZED_NO_NORMS)); - doc.add(new Field(TITLE_FIELD, "title_" + name, Store.NO, Index.NOT_ANALYZED_NO_NORMS)); - doc.add(new Field(DATE_FIELD, "date_" + name, Store.NO, Index.NOT_ANALYZED_NO_NORMS)); + doc.add(new StringField(BODY_FIELD, "body_" + name)); + doc.add(new StringField(TITLE_FIELD, "title_" + name)); + doc.add(new StringField(DATE_FIELD, "date_" + name)); return doc; } Index: modules/benchmark/src/test/org/apache/lucene/benchmark/byTask/feeds/DocMakerTest.java =================================================================== --- modules/benchmark/src/test/org/apache/lucene/benchmark/byTask/feeds/DocMakerTest.java (revision 1158028) +++ modules/benchmark/src/test/org/apache/lucene/benchmark/byTask/feeds/DocMakerTest.java (working copy) @@ -137,28 +137,28 @@ // Don't set anything, use the defaults doc = createTestNormsDocument(false, false, false, false); - assertTrue(doc.getField(DocMaker.TITLE_FIELD).getOmitNorms()); - assertFalse(doc.getField(DocMaker.BODY_FIELD).getOmitNorms()); + assertTrue(doc.getField(DocMaker.TITLE_FIELD).omitNorms()); + assertFalse(doc.getField(DocMaker.BODY_FIELD).omitNorms()); // Set norms to false doc = createTestNormsDocument(true, false, false, false); - assertTrue(doc.getField(DocMaker.TITLE_FIELD).getOmitNorms()); - assertFalse(doc.getField(DocMaker.BODY_FIELD).getOmitNorms()); + assertTrue(doc.getField(DocMaker.TITLE_FIELD).omitNorms()); + assertFalse(doc.getField(DocMaker.BODY_FIELD).omitNorms()); // Set norms to true doc = createTestNormsDocument(true, true, false, false); - assertFalse(doc.getField(DocMaker.TITLE_FIELD).getOmitNorms()); - assertFalse(doc.getField(DocMaker.BODY_FIELD).getOmitNorms()); + assertFalse(doc.getField(DocMaker.TITLE_FIELD).omitNorms()); + assertFalse(doc.getField(DocMaker.BODY_FIELD).omitNorms()); // Set body norms to false doc = createTestNormsDocument(false, false, true, false); - assertTrue(doc.getField(DocMaker.TITLE_FIELD).getOmitNorms()); - assertTrue(doc.getField(DocMaker.BODY_FIELD).getOmitNorms()); + assertTrue(doc.getField(DocMaker.TITLE_FIELD).omitNorms()); + assertTrue(doc.getField(DocMaker.BODY_FIELD).omitNorms()); // Set body norms to true doc = createTestNormsDocument(false, false, true, true); - assertTrue(doc.getField(DocMaker.TITLE_FIELD).getOmitNorms()); - assertFalse(doc.getField(DocMaker.BODY_FIELD).getOmitNorms()); + assertTrue(doc.getField(DocMaker.TITLE_FIELD).omitNorms()); + assertFalse(doc.getField(DocMaker.BODY_FIELD).omitNorms()); } } Index: modules/benchmark/src/java/org/apache/lucene/benchmark/quality/utils/DocNameExtractor.java =================================================================== --- modules/benchmark/src/java/org/apache/lucene/benchmark/quality/utils/DocNameExtractor.java (revision 1158028) +++ modules/benchmark/src/java/org/apache/lucene/benchmark/quality/utils/DocNameExtractor.java (working copy) @@ -17,18 +17,20 @@ package org.apache.lucene.benchmark.quality.utils; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; -import org.apache.lucene.document.FieldSelector; -import org.apache.lucene.document.FieldSelectorResult; +import org.apache.lucene.index.FieldInfo; +import org.apache.lucene.index.StoredFieldVisitor; import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.store.IndexInput; /** * Utility: extract doc names from an index */ public class DocNameExtractor { - private FieldSelector fldSel; - private String docNameField; + private final String docNameField; /** * Constructor for DocNameExtractor. @@ -36,13 +38,6 @@ */ public DocNameExtractor (final String docNameField) { this.docNameField = docNameField; - fldSel = new FieldSelector() { - public FieldSelectorResult accept(String fieldName) { - return fieldName.equals(docNameField) ? - FieldSelectorResult.LOAD_AND_BREAK : - FieldSelectorResult.NO_LOAD; - } - }; } /** @@ -53,7 +48,25 @@ * @throws IOException if cannot extract the doc name from the index. */ public String docName(IndexSearcher searcher, int docid) throws IOException { - return searcher.doc(docid,fldSel).get(docNameField); + final List name = new ArrayList(); + searcher.getIndexReader().document(docid, new StoredFieldVisitor() { + @Override + public boolean stringField(FieldInfo fieldInfo, IndexInput in, int numUTF8Bytes) throws IOException { + if (fieldInfo.name.equals(docNameField) && name.size() == 0) { + final byte[] b = new byte[numUTF8Bytes]; + in.readBytes(b, 0, b.length); + name.add(new String(b, "UTF-8")); + } else { + in.seek(in.getFilePointer() + numUTF8Bytes); + } + return false; + } + }); + if (name.size() != 0) { + return name.get(0); + } else { + return null; + } } } Index: modules/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/ReadTokensTask.java =================================================================== --- modules/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/ReadTokensTask.java (revision 1158028) +++ modules/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/ReadTokensTask.java (working copy) @@ -26,8 +26,8 @@ import org.apache.lucene.benchmark.byTask.PerfRunData; import org.apache.lucene.benchmark.byTask.feeds.DocMaker; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Fieldable; import org.apache.lucene.document.NumericField; +import org.apache.lucene.index.IndexableField; /** * Simple task to test performance of tokenizers. It just @@ -65,11 +65,11 @@ @Override public int doLogic() throws Exception { - List fields = doc.getFields(); + List fields = doc.getFields(); Analyzer analyzer = getRunData().getAnalyzer(); int tokenCount = 0; - for(final Fieldable field : fields) { - if (!field.isTokenized() || field instanceof NumericField) continue; + for(final IndexableField field : fields) { + if (!field.tokenized() || field instanceof NumericField) continue; final TokenStream stream; final TokenStream streamValue = field.tokenStreamValue(); Index: modules/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/SearchTravRetLoadFieldSelectorTask.java =================================================================== --- modules/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/SearchTravRetLoadFieldSelectorTask.java (revision 1158028) +++ modules/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/SearchTravRetLoadFieldSelectorTask.java (working copy) @@ -16,20 +16,20 @@ */ +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; +import java.util.StringTokenizer; + import org.apache.lucene.benchmark.byTask.PerfRunData; -import org.apache.lucene.document.FieldSelector; -import org.apache.lucene.document.SetBasedFieldSelector; import org.apache.lucene.document.Document; +import org.apache.lucene.index.DocumentStoredFieldVisitor; +import org.apache.lucene.index.DocumentStoredFieldVisitor; import org.apache.lucene.index.IndexReader; -import java.util.StringTokenizer; -import java.util.Set; -import java.util.HashSet; -import java.util.Collections; -import java.io.IOException; - /** - * Search and Traverse and Retrieve docs task using a SetBasedFieldSelector. + * Search and Traverse and Retrieve docs task using a + * FieldVisitor loading only the requested fields. * *

Note: This task reuses the reader if it is already open. * Otherwise a reader is opened at start and closed at the end. @@ -41,7 +41,8 @@ */ public class SearchTravRetLoadFieldSelectorTask extends SearchTravTask { - protected FieldSelector fieldSelector; + protected Set fieldsToLoad; + public SearchTravRetLoadFieldSelectorTask(PerfRunData runData) { super(runData); @@ -55,18 +56,23 @@ @Override protected Document retrieveDoc(IndexReader ir, int id) throws IOException { - return ir.document(id, fieldSelector); + if (fieldsToLoad == null) { + return ir.document(id); + } else { + DocumentStoredFieldVisitor visitor = new DocumentStoredFieldVisitor(fieldsToLoad); + ir.document(id, visitor); + return visitor.getDocument(); + } } @Override public void setParams(String params) { this.params = params; // cannot just call super.setParams(), b/c it's params differ. - Set fieldsToLoad = new HashSet(); + fieldsToLoad = new HashSet(); for (StringTokenizer tokenizer = new StringTokenizer(params, ","); tokenizer.hasMoreTokens();) { String s = tokenizer.nextToken(); fieldsToLoad.add(s); } - fieldSelector = new SetBasedFieldSelector(fieldsToLoad, Collections. emptySet()); } Index: modules/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/WriteLineDocTask.java =================================================================== --- modules/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/WriteLineDocTask.java (revision 1158028) +++ modules/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/WriteLineDocTask.java (working copy) @@ -33,6 +33,7 @@ import org.apache.lucene.benchmark.byTask.utils.StreamUtils; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.index.IndexableField; /** * A task which writes documents, one line per document. Each line is in the @@ -172,7 +173,7 @@ boolean sufficient = !checkSufficientFields; for (int i=0; i0 && sufficientFields[i]; Index: modules/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/ReadTask.java =================================================================== --- modules/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/ReadTask.java (revision 1158028) +++ modules/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/ReadTask.java (working copy) @@ -28,8 +28,8 @@ import org.apache.lucene.benchmark.byTask.PerfRunData; import org.apache.lucene.benchmark.byTask.feeds.QueryMaker; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Fieldable; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexableField; import org.apache.lucene.index.MultiFields; import org.apache.lucene.search.Collector; import org.apache.lucene.search.TopDocs; @@ -300,10 +300,10 @@ * @return A Collection of Field names (Strings) */ protected Collection getFieldsToHighlight(Document document) { - List fieldables = document.getFields(); - Set result = new HashSet(fieldables.size()); - for (final Fieldable fieldable : fieldables) { - result.add(fieldable.name()); + List fields = document.getFields(); + Set result = new HashSet(fields.size()); + for (final IndexableField f : fields) { + result.add(f.name()); } return result; } Index: modules/benchmark/src/java/org/apache/lucene/benchmark/byTask/feeds/DocMaker.java =================================================================== --- modules/benchmark/src/java/org/apache/lucene/benchmark/byTask/feeds/DocMaker.java (revision 1158028) +++ modules/benchmark/src/java/org/apache/lucene/benchmark/byTask/feeds/DocMaker.java (working copy) @@ -34,10 +34,10 @@ import org.apache.lucene.benchmark.byTask.utils.Format; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; import org.apache.lucene.document.NumericField; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; -import org.apache.lucene.document.Field.TermVector; +import org.apache.lucene.document.StringField; +import org.apache.lucene.document.TextField; /** * Creates {@link Document} objects. Uses a {@link ContentSource} to generate @@ -94,7 +94,7 @@ final Document doc; DocData docData = new DocData(); - public DocState(boolean reuseFields, Store store, Store bodyStore, Index index, Index bodyIndex, TermVector termVector) { + public DocState(boolean reuseFields, FieldType ft, FieldType bodyFt) { this.reuseFields = reuseFields; @@ -103,11 +103,11 @@ numericFields = new HashMap(); // Initialize the map with the default fields. - fields.put(BODY_FIELD, new Field(BODY_FIELD, "", bodyStore, bodyIndex, termVector)); - fields.put(TITLE_FIELD, new Field(TITLE_FIELD, "", store, index, termVector)); - fields.put(DATE_FIELD, new Field(DATE_FIELD, "", store, index, termVector)); - fields.put(ID_FIELD, new Field(ID_FIELD, "", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS)); - fields.put(NAME_FIELD, new Field(NAME_FIELD, "", store, index, termVector)); + fields.put(BODY_FIELD, new Field(BODY_FIELD, bodyFt, "")); + fields.put(TITLE_FIELD, new Field(TITLE_FIELD, ft, "")); + fields.put(DATE_FIELD, new Field(DATE_FIELD, ft, "")); + fields.put(ID_FIELD, new Field(ID_FIELD, StringField.TYPE_STORED, "")); + fields.put(NAME_FIELD, new Field(NAME_FIELD, ft, "")); numericFields.put(DATE_MSEC_FIELD, new NumericField(DATE_MSEC_FIELD)); numericFields.put(TIME_SEC_FIELD, new NumericField(TIME_SEC_FIELD)); @@ -125,14 +125,14 @@ * reuseFields was set to true, then it attempts to reuse a * Field instance. If such a field does not exist, it creates a new one. */ - Field getField(String name, Store store, Index index, TermVector termVector) { + Field getField(String name, FieldType ft) { if (!reuseFields) { - return new Field(name, "", store, index, termVector); + return new Field(name, ft, ""); } Field f = fields.get(name); if (f == null) { - f = new Field(name, "", store, index, termVector); + f = new Field(name, ft, ""); fields.put(name, f); } return f; @@ -179,12 +179,9 @@ protected Config config; - protected Store storeVal = Store.NO; - protected Store bodyStoreVal = Store.NO; - protected Index indexVal = Index.ANALYZED_NO_NORMS; - protected Index bodyIndexVal = Index.ANALYZED; - protected TermVector termVecVal = TermVector.NO; - + protected FieldType valType; + protected FieldType bodyValType; + protected ContentSource source; protected boolean reuseFields; protected boolean indexProperties; @@ -196,6 +193,13 @@ private int printNum = 0; + public DocMaker() { + valType = new FieldType(TextField.TYPE_UNSTORED); + valType.setOmitNorms(true); + + bodyValType = new FieldType(TextField.TYPE_UNSTORED); + } + // create a doc // use only part of the body, modify it to keep the rest (or use all if size==0). // reset the docdata properties so they are not added more than once. @@ -206,7 +210,10 @@ doc.getFields().clear(); // Set ID_FIELD - Field idField = ds.getField(ID_FIELD, storeVal, Index.NOT_ANALYZED_NO_NORMS, termVecVal); + FieldType ft = new FieldType(valType); + ft.setIndexed(true); + + Field idField = ds.getField(ID_FIELD, ft); int id; if (r != null) { id = r.nextInt(updateDocIDLimit); @@ -223,7 +230,7 @@ String name = docData.getName(); if (name == null) name = ""; name = cnt < 0 ? name : name + "_" + cnt; - Field nameField = ds.getField(NAME_FIELD, storeVal, indexVal, termVecVal); + Field nameField = ds.getField(NAME_FIELD, valType); nameField.setValue(name); doc.add(nameField); @@ -242,7 +249,7 @@ } else { dateString = ""; } - Field dateStringField = ds.getField(DATE_FIELD, storeVal, indexVal, termVecVal); + Field dateStringField = ds.getField(DATE_FIELD, valType); dateStringField.setValue(dateString); doc.add(dateStringField); @@ -264,7 +271,7 @@ // Set TITLE_FIELD String title = docData.getTitle(); - Field titleField = ds.getField(TITLE_FIELD, storeVal, indexVal, termVecVal); + Field titleField = ds.getField(TITLE_FIELD, valType); titleField.setValue(title == null ? "" : title); doc.add(titleField); @@ -285,12 +292,12 @@ bdy = body.substring(0, size); // use part docData.setBody(body.substring(size)); // some left } - Field bodyField = ds.getField(BODY_FIELD, bodyStoreVal, bodyIndexVal, termVecVal); + Field bodyField = ds.getField(BODY_FIELD, bodyValType); bodyField.setValue(bdy); doc.add(bodyField); if (storeBytes) { - Field bytesField = ds.getField(BYTES_FIELD, Store.YES, Index.NOT_ANALYZED_NO_NORMS, TermVector.NO); + Field bytesField = ds.getField(BYTES_FIELD, StringField.TYPE_STORED); bytesField.setValue(bdy.getBytes("UTF-8")); doc.add(bytesField); } @@ -300,7 +307,7 @@ Properties props = docData.getProps(); if (props != null) { for (final Map.Entry entry : props.entrySet()) { - Field f = ds.getField((String) entry.getKey(), storeVal, indexVal, termVecVal); + Field f = ds.getField((String) entry.getKey(), valType); f.setValue((String) entry.getValue()); doc.add(f); } @@ -319,7 +326,7 @@ protected DocState getDocState() { DocState ds = docState.get(); if (ds == null) { - ds = new DocState(reuseFields, storeVal, bodyStoreVal, indexVal, bodyIndexVal, termVecVal); + ds = new DocState(reuseFields, valType, bodyValType); docState.set(ds); } return ds; @@ -455,33 +462,23 @@ boolean norms = config.get("doc.tokenized.norms", false); boolean bodyNorms = config.get("doc.body.tokenized.norms", true); boolean termVec = config.get("doc.term.vector", false); - storeVal = (stored ? Field.Store.YES : Field.Store.NO); - bodyStoreVal = (bodyStored ? Field.Store.YES : Field.Store.NO); - if (tokenized) { - indexVal = norms ? Index.ANALYZED : Index.ANALYZED_NO_NORMS; - } else { - indexVal = norms ? Index.NOT_ANALYZED : Index.NOT_ANALYZED_NO_NORMS; - } - - if (bodyTokenized) { - bodyIndexVal = bodyNorms ? Index.ANALYZED : Index.ANALYZED_NO_NORMS; - } else { - bodyIndexVal = bodyNorms ? Index.NOT_ANALYZED : Index.NOT_ANALYZED_NO_NORMS; - } - boolean termVecPositions = config.get("doc.term.vector.positions", false); boolean termVecOffsets = config.get("doc.term.vector.offsets", false); - if (termVecPositions && termVecOffsets) { - termVecVal = TermVector.WITH_POSITIONS_OFFSETS; - } else if (termVecPositions) { - termVecVal = TermVector.WITH_POSITIONS; - } else if (termVecOffsets) { - termVecVal = TermVector.WITH_OFFSETS; - } else if (termVec) { - termVecVal = TermVector.YES; - } else { - termVecVal = TermVector.NO; - } + + valType.setStored(stored); + bodyValType.setStored(bodyStored); + valType.setTokenized(tokenized); + valType.setOmitNorms(!norms); + bodyValType.setTokenized(bodyTokenized); + bodyValType.setOmitNorms(!bodyNorms); + + valType.setStoreTermVectors(termVec); + valType.setStoreTermVectorPositions(termVecPositions); + valType.setStoreTermVectorOffsets(termVecOffsets); + bodyValType.setStoreTermVectors(termVec); + bodyValType.setStoreTermVectorPositions(termVecPositions); + bodyValType.setStoreTermVectorOffsets(termVecOffsets); + storeBytes = config.get("doc.store.body.bytes", false); reuseFields = config.get("doc.reuse.fields", true); Index: modules/grouping/src/test/org/apache/lucene/search/grouping/TermAllGroupsCollectorTest.java =================================================================== --- modules/grouping/src/test/org/apache/lucene/search/grouping/TermAllGroupsCollectorTest.java (revision 1158028) +++ modules/grouping/src/test/org/apache/lucene/search/grouping/TermAllGroupsCollectorTest.java (working copy) @@ -5,7 +5,7 @@ * 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 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 @@ -20,6 +20,8 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.search.IndexSearcher; @@ -32,6 +34,8 @@ public void testTotalGroupCount() throws Exception { final String groupField = "author"; + FieldType customType = new FieldType(); + customType.setStored(true); Directory dir = newDirectory(); RandomIndexWriter w = new RandomIndexWriter( @@ -41,51 +45,51 @@ new MockAnalyzer(random)).setMergePolicy(newLogMergePolicy())); // 0 Document doc = new Document(); - doc.add(new Field(groupField, "author1", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("content", "random text", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("id", "1", Field.Store.YES, Field.Index.NO)); + doc.add(new Field(groupField, TextField.TYPE_STORED, "author1")); + doc.add(new Field("content", TextField.TYPE_STORED, "random text")); + doc.add(new Field("id", customType, "1")); w.addDocument(doc); // 1 doc = new Document(); - doc.add(new Field(groupField, "author1", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("content", "some more random text blob", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("id", "2", Field.Store.YES, Field.Index.NO)); + doc.add(new Field(groupField, TextField.TYPE_STORED, "author1")); + doc.add(new Field("content", TextField.TYPE_STORED, "some more random text blob")); + doc.add(new Field("id", customType, "2")); w.addDocument(doc); // 2 doc = new Document(); - doc.add(new Field(groupField, "author1", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("content", "some more random textual data", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("id", "3", Field.Store.YES, Field.Index.NO)); + doc.add(new Field(groupField, TextField.TYPE_STORED, "author1")); + doc.add(new Field("content", TextField.TYPE_STORED, "some more random textual data")); + doc.add(new Field("id", customType, "3")); w.addDocument(doc); w.commit(); // To ensure a second segment // 3 doc = new Document(); - doc.add(new Field(groupField, "author2", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("content", "some random text", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("id", "4", Field.Store.YES, Field.Index.NO)); + doc.add(new Field(groupField, TextField.TYPE_STORED, "author2")); + doc.add(new Field("content", TextField.TYPE_STORED, "some random text")); + doc.add(new Field("id", customType, "4")); w.addDocument(doc); // 4 doc = new Document(); - doc.add(new Field(groupField, "author3", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("content", "some more random text", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("id", "5", Field.Store.YES, Field.Index.NO)); + doc.add(new Field(groupField, TextField.TYPE_STORED, "author3")); + doc.add(new Field("content", TextField.TYPE_STORED, "some more random text")); + doc.add(new Field("id", customType, "5")); w.addDocument(doc); // 5 doc = new Document(); - doc.add(new Field(groupField, "author3", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("content", "random blob", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("id", "6", Field.Store.YES, Field.Index.NO)); + doc.add(new Field(groupField, TextField.TYPE_STORED, "author3")); + doc.add(new Field("content", TextField.TYPE_STORED, "random blob")); + doc.add(new Field("id", customType, "6")); w.addDocument(doc); // 6 -- no author field doc = new Document(); - doc.add(new Field("content", "random word stuck in alot of other text", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("id", "6", Field.Store.YES, Field.Index.NO)); + doc.add(new Field("content", TextField.TYPE_STORED, "random word stuck in alot of other text")); + doc.add(new Field("id", customType, "6")); w.addDocument(doc); IndexSearcher indexSearcher = new IndexSearcher(w.getReader()); Index: modules/grouping/src/test/org/apache/lucene/search/grouping/TermAllGroupHeadsCollectorTest.java =================================================================== --- modules/grouping/src/test/org/apache/lucene/search/grouping/TermAllGroupHeadsCollectorTest.java (revision 1158028) +++ modules/grouping/src/test/org/apache/lucene/search/grouping/TermAllGroupHeadsCollectorTest.java (working copy) @@ -21,6 +21,8 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.NumericField; +import org.apache.lucene.document.StringField; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; @@ -47,57 +49,57 @@ // 0 Document doc = new Document(); - doc.add(new Field(groupField, "author1", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("content", "random text", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("id", "1", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS)); + doc.add(newField(groupField, "author1", TextField.TYPE_STORED)); + doc.add(newField("content", "random text", TextField.TYPE_STORED)); + doc.add(newField("id", "1", StringField.TYPE_STORED)); w.addDocument(doc); // 1 doc = new Document(); - doc.add(new Field(groupField, "author1", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("content", "some more random text blob", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("id", "2", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS)); + doc.add(newField(groupField, "author1", TextField.TYPE_STORED)); + doc.add(newField("content", "some more random text blob", TextField.TYPE_STORED)); + doc.add(newField("id", "2", StringField.TYPE_STORED)); w.addDocument(doc); // 2 doc = new Document(); - doc.add(new Field(groupField, "author1", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("content", "some more random textual data", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("id", "3", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS)); + doc.add(newField(groupField, "author1", TextField.TYPE_STORED)); + doc.add(newField("content", "some more random textual data", TextField.TYPE_STORED)); + doc.add(newField("id", "3", StringField.TYPE_STORED)); w.addDocument(doc); w.commit(); // To ensure a second segment // 3 doc = new Document(); - doc.add(new Field(groupField, "author2", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("content", "some random text", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("id", "4", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS)); + doc.add(newField(groupField, "author2", TextField.TYPE_STORED)); + doc.add(newField("content", "some random text", TextField.TYPE_STORED)); + doc.add(newField("id", "4", StringField.TYPE_STORED)); w.addDocument(doc); // 4 doc = new Document(); - doc.add(new Field(groupField, "author3", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("content", "some more random text", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("id", "5", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS)); + doc.add(newField(groupField, "author3", TextField.TYPE_STORED)); + doc.add(newField("content", "some more random text", TextField.TYPE_STORED)); + doc.add(newField("id", "5", StringField.TYPE_STORED)); w.addDocument(doc); // 5 doc = new Document(); - doc.add(new Field(groupField, "author3", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("content", "random blob", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("id", "6", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS)); + doc.add(newField(groupField, "author3", TextField.TYPE_STORED)); + doc.add(newField("content", "random blob", TextField.TYPE_STORED)); + doc.add(newField("id", "6", StringField.TYPE_STORED)); w.addDocument(doc); // 6 -- no author field doc = new Document(); - doc.add(new Field("content", "random word stuck in alot of other text", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("id", "6", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS)); + doc.add(newField("content", "random word stuck in alot of other text", TextField.TYPE_STORED)); + doc.add(newField("id", "6", StringField.TYPE_STORED)); w.addDocument(doc); // 7 -- no author field doc = new Document(); - doc.add(new Field("content", "random word stuck in alot of other text", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("id", "7", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS)); + doc.add(newField("content", "random word stuck in alot of other text", TextField.TYPE_STORED)); + doc.add(newField("id", "7", StringField.TYPE_STORED)); w.addDocument(doc); IndexSearcher indexSearcher = new IndexSearcher(w.getReader()); @@ -182,18 +184,18 @@ Document doc = new Document(); Document docNoGroup = new Document(); - Field group = newField("group", "", Field.Index.NOT_ANALYZED); + Field group = newField("group", "", StringField.TYPE_UNSTORED); doc.add(group); - Field sort1 = newField("sort1", "", Field.Index.NOT_ANALYZED); + Field sort1 = newField("sort1", "", StringField.TYPE_UNSTORED); doc.add(sort1); docNoGroup.add(sort1); - Field sort2 = newField("sort2", "", Field.Index.NOT_ANALYZED); + Field sort2 = newField("sort2", "", StringField.TYPE_UNSTORED); doc.add(sort2); docNoGroup.add(sort2); - Field sort3 = newField("sort3", "", Field.Index.NOT_ANALYZED); + Field sort3 = newField("sort3", "", StringField.TYPE_UNSTORED); doc.add(sort3); docNoGroup.add(sort3); - Field content = newField("content", "", Field.Index.ANALYZED); + Field content = newField("content", "", TextField.TYPE_UNSTORED); doc.add(content); docNoGroup.add(content); NumericField id = new NumericField("id"); Index: modules/grouping/src/test/org/apache/lucene/search/grouping/TestGrouping.java =================================================================== --- modules/grouping/src/test/org/apache/lucene/search/grouping/TestGrouping.java (revision 1158028) +++ modules/grouping/src/test/org/apache/lucene/search/grouping/TestGrouping.java (working copy) @@ -23,8 +23,11 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; import org.apache.lucene.document.NumericField; import org.apache.lucene.index.FieldInfo.IndexOptions; +import org.apache.lucene.document.StringField; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; @@ -47,6 +50,9 @@ final String groupField = "author"; + FieldType customType = new FieldType(); + customType.setStored(true); + Directory dir = newDirectory(); RandomIndexWriter w = new RandomIndexWriter( random, @@ -55,50 +61,50 @@ new MockAnalyzer(random)).setMergePolicy(newLogMergePolicy())); // 0 Document doc = new Document(); - doc.add(new Field(groupField, "author1", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("content", "random text", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("id", "1", Field.Store.YES, Field.Index.NO)); + doc.add(new Field(groupField, TextField.TYPE_STORED, "author1")); + doc.add(new Field("content", TextField.TYPE_STORED, "random text")); + doc.add(new Field("id", customType, "1")); w.addDocument(doc); // 1 doc = new Document(); - doc.add(new Field(groupField, "author1", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("content", "some more random text", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("id", "2", Field.Store.YES, Field.Index.NO)); + doc.add(new Field(groupField, TextField.TYPE_STORED, "author1")); + doc.add(new Field("content", TextField.TYPE_STORED, "some more random text")); + doc.add(new Field("id", customType, "2")); w.addDocument(doc); // 2 doc = new Document(); - doc.add(new Field(groupField, "author1", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("content", "some more random textual data", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("id", "3", Field.Store.YES, Field.Index.NO)); + doc.add(new Field(groupField, TextField.TYPE_STORED, "author1")); + doc.add(new Field("content", TextField.TYPE_STORED, "some more random textual data")); + doc.add(new Field("id", customType, "3")); w.addDocument(doc); // 3 doc = new Document(); - doc.add(new Field(groupField, "author2", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("content", "some random text", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("id", "4", Field.Store.YES, Field.Index.NO)); + doc.add(new Field(groupField, TextField.TYPE_STORED, "author2")); + doc.add(new Field("content", TextField.TYPE_STORED, "some random text")); + doc.add(new Field("id", customType, "4")); w.addDocument(doc); // 4 doc = new Document(); - doc.add(new Field(groupField, "author3", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("content", "some more random text", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("id", "5", Field.Store.YES, Field.Index.NO)); + doc.add(new Field(groupField, TextField.TYPE_STORED, "author3")); + doc.add(new Field("content", TextField.TYPE_STORED, "some more random text")); + doc.add(new Field("id", customType, "5")); w.addDocument(doc); // 5 doc = new Document(); - doc.add(new Field(groupField, "author3", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("content", "random", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("id", "6", Field.Store.YES, Field.Index.NO)); + doc.add(new Field(groupField, TextField.TYPE_STORED, "author3")); + doc.add(new Field("content", TextField.TYPE_STORED, "random")); + doc.add(new Field("id", customType, "6")); w.addDocument(doc); // 6 -- no author field doc = new Document(); - doc.add(new Field("content", "random word stuck in alot of other text", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(new Field("id", "6", Field.Store.YES, Field.Index.NO)); + doc.add(new Field("content", TextField.TYPE_STORED, "random word stuck in alot of other text")); + doc.add(new Field("id", customType, "6")); w.addDocument(doc); IndexSearcher indexSearcher = new IndexSearcher(w.getReader()); @@ -386,18 +392,19 @@ Document doc = new Document(); docs.add(doc); if (groupValue.group != null) { - doc.add(newField("group", groupValue.group.utf8ToString(), Field.Index.NOT_ANALYZED)); + doc.add(newField("group", groupValue.group.utf8ToString(), StringField.TYPE_UNSTORED)); } - doc.add(newField("sort1", groupValue.sort1.utf8ToString(), Field.Index.NOT_ANALYZED)); - doc.add(newField("sort2", groupValue.sort2.utf8ToString(), Field.Index.NOT_ANALYZED)); + doc.add(newField("sort1", groupValue.sort1.utf8ToString(), StringField.TYPE_UNSTORED)); + doc.add(newField("sort2", groupValue.sort2.utf8ToString(), StringField.TYPE_UNSTORED)); doc.add(new NumericField("id").setIntValue(groupValue.id)); - doc.add(newField("content", groupValue.content, Field.Index.ANALYZED)); + doc.add(newField("content", groupValue.content, TextField.TYPE_UNSTORED)); //System.out.println("TEST: doc content=" + groupValue.content + " group=" + (groupValue.group == null ? "null" : groupValue.group.utf8ToString()) + " sort1=" + groupValue.sort1.utf8ToString() + " id=" + groupValue.id); } // So we can pull filter marking last doc in block: - final Field groupEnd = newField("groupend", "x", Field.Index.NOT_ANALYZED); - groupEnd.setIndexOptions(IndexOptions.DOCS_ONLY); - groupEnd.setOmitNorms(true); + FieldType ft = new FieldType(StringField.TYPE_UNSTORED); + ft.setIndexOptions(IndexOptions.DOCS_ONLY); + ft.setOmitNorms(true); + final Field groupEnd = newField("groupend", "x", ft); docs.get(docs.size()-1).add(groupEnd); // Add as a doc block: w.addDocuments(docs); @@ -497,15 +504,15 @@ Document doc = new Document(); Document docNoGroup = new Document(); - Field group = newField("group", "", Field.Index.NOT_ANALYZED); + Field group = newField("group", "", StringField.TYPE_UNSTORED); doc.add(group); - Field sort1 = newField("sort1", "", Field.Index.NOT_ANALYZED); + Field sort1 = newField("sort1", "", StringField.TYPE_UNSTORED); doc.add(sort1); docNoGroup.add(sort1); - Field sort2 = newField("sort2", "", Field.Index.NOT_ANALYZED); + Field sort2 = newField("sort2", "", StringField.TYPE_UNSTORED); doc.add(sort2); docNoGroup.add(sort2); - Field content = newField("content", "", Field.Index.ANALYZED); + Field content = newField("content", "", TextField.TYPE_UNSTORED); doc.add(content); docNoGroup.add(content); NumericField id = new NumericField("id"); Index: modules/grouping/src/java/org/apache/lucene/search/grouping/package.html =================================================================== --- modules/grouping/src/java/org/apache/lucene/search/grouping/package.html (revision 1158028) +++ modules/grouping/src/java/org/apache/lucene/search/grouping/package.html (working copy) @@ -130,7 +130,7 @@ List<Document> oneGroup = ...; Field groupEndField = new Field("groupEnd", "x", Field.Store.NO, Field.Index.NOT_ANALYZED); - groupEndField.setOmitTermFreqAndPositions(true); + groupEndField.setIndexOptions(IndexOptions.DOCS_ONLY); groupEndField.setOmitNorms(true); oneGroup.get(oneGroup.size()-1).add(groupEndField); Index: lucene/contrib/CHANGES.txt =================================================================== --- lucene/contrib/CHANGES.txt (revision 1158028) +++ lucene/contrib/CHANGES.txt (working copy) @@ -4,7 +4,15 @@ http://s.apache.org/luceneversions ======================= Trunk (not yet released) ======================= + +Changes in Runtime Behavior + * LUCENE-3309: Fast vector highlighter now inserts the + MultiValuedSeparator for NOT_ANALYZED fields (in addition to + ANALYZED fields). To ensure your offsets are correct you should + provide an analyzer that returns 1 from the offsetGap method. + (Mike McCandless) + Build * LUCENE-2845: Moved contrib/benchmark to modules. Index: lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexWriter.java =================================================================== --- lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexWriter.java (revision 1158028) +++ lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexWriter.java (working copy) @@ -37,9 +37,9 @@ import org.apache.lucene.analysis.Token; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Fieldable; import org.apache.lucene.index.FieldInvertState; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexableField; import org.apache.lucene.index.Term; import org.apache.lucene.index.TermVectorOffsetInfo; import org.apache.lucene.search.IndexSearcher; @@ -238,7 +238,7 @@ if (eFieldTermDocInfoFactoriesByTermText.getKey().indexed && !eFieldTermDocInfoFactoriesByTermText.getKey().omitNorms) { final String fieldName = eFieldTermDocInfoFactoriesByTermText.getKey().fieldName; final FieldInvertState invertState = new FieldInvertState(); - invertState.setBoost(eFieldTermDocInfoFactoriesByTermText.getKey().boost * document.getDocument().getBoost()); + invertState.setBoost(eFieldTermDocInfoFactoriesByTermText.getKey().boost); invertState.setLength(eFieldTermDocInfoFactoriesByTermText.getKey().fieldLength); normsByFieldNameAndDocumentNumber.get(fieldName)[document.getDocumentNumber()] = similarityProvider.get(fieldName).computeNorm(invertState); } else { @@ -469,7 +469,7 @@ // normalize settings per field name in document Map fieldSettingsByFieldName = new HashMap(); - for (Fieldable field : document.getDocument().getFields()) { + for (IndexableField field : document.getDocument()) { FieldSetting fieldSetting = fieldSettingsByFieldName.get(field.name()); if (fieldSetting == null) { fieldSetting = new FieldSetting(); @@ -479,52 +479,52 @@ } // todo: fixme: multiple fields with the same name does not mean field boost += more boost. - fieldSetting.boost *= field.getBoost(); + fieldSetting.boost *= field.boost(); //fieldSettings.dimensions++; // once fieldSettings, always fieldSettings. - if (field.getOmitNorms()) { + if (field.omitNorms()) { fieldSetting.omitNorms = true; } - if (field.isIndexed() ) { + if (field.indexed() ) { fieldSetting.indexed = true; } - if (field.isTokenized()) { + if (field.tokenized()) { fieldSetting.tokenized = true; } - if (field.isStored()) { + if (field.stored()) { fieldSetting.stored = true; } - if (field.isBinary()) { + if (field.binaryValue() != null) { fieldSetting.isBinary = true; } - if (field.isTermVectorStored()) { + if (field.storeTermVectors()) { fieldSetting.storeTermVector = true; } - if (field.isStorePositionWithTermVector()) { + if (field.storeTermVectorPositions()) { fieldSetting.storePositionWithTermVector = true; } - if (field.isStoreOffsetWithTermVector()) { + if (field.storeTermVectorOffsets()) { fieldSetting.storeOffsetWithTermVector = true; } } - Map> tokensByField = new LinkedHashMap>(20); + Map> tokensByField = new LinkedHashMap>(20); // tokenize indexed fields. - for (Iterator it = document.getDocument().getFields().iterator(); it.hasNext();) { + for (Iterator it = document.getDocument().iterator(); it.hasNext();) { - Fieldable field = it.next(); + IndexableField field = it.next(); FieldSetting fieldSetting = fieldSettingsByFieldName.get(field.name()); - if (field.isIndexed()) { + if (field.indexed()) { LinkedList tokens = new LinkedList(); tokensByField.put(field, tokens); - if (field.isTokenized()) { + if (field.tokenized()) { final TokenStream tokenStream; // todo readerValue(), binaryValue() if (field.tokenStreamValue() != null) { @@ -564,8 +564,8 @@ } } - if (!field.isStored()) { - it.remove(); + if (!field.stored()) { + //it.remove(); } } @@ -574,7 +574,7 @@ termDocumentInformationFactoryByDocument.put(document, termDocumentInformationFactoryByTermTextAndFieldSetting); // build term vector, term positions and term offsets - for (Map.Entry> eField_Tokens : tokensByField.entrySet()) { + for (Map.Entry> eField_Tokens : tokensByField.entrySet()) { FieldSetting fieldSetting = fieldSettingsByFieldName.get(eField_Tokens.getKey().name()); Map termDocumentInformationFactoryByTermText = termDocumentInformationFactoryByTermTextAndFieldSetting.get(fieldSettingsByFieldName.get(eField_Tokens.getKey().name())); @@ -610,7 +610,7 @@ termDocumentInformationFactory.payloads.add(null); } - if (eField_Tokens.getKey().isStoreOffsetWithTermVector()) { + if (eField_Tokens.getKey().storeTermVectorOffsets()) { termDocumentInformationFactory.termOffsets.add(new TermVectorOffsetInfo(fieldSetting.offset + token.startOffset(), fieldSetting.offset + token.endOffset())); lastOffset = fieldSetting.offset + token.endOffset(); @@ -619,7 +619,7 @@ } - if (eField_Tokens.getKey().isStoreOffsetWithTermVector()) { + if (eField_Tokens.getKey().storeTermVectorOffsets()) { fieldSetting.offset = lastOffset + 1; } Index: lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndex.java =================================================================== --- lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndex.java (revision 1158028) +++ lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndex.java (working copy) @@ -27,8 +27,8 @@ import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Fieldable; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexableField; import org.apache.lucene.index.MultiNorms; import org.apache.lucene.index.Term; import org.apache.lucene.index.TermsEnum; @@ -190,16 +190,16 @@ InstantiatedDocument document = new InstantiatedDocument(); // copy stored fields from source reader Document sourceDocument = sourceIndexReader.document(i); - for (Fieldable field : sourceDocument.getFields()) { + for (IndexableField field : sourceDocument) { if (fields == null || fields.contains(field.name())) { document.getDocument().add(field); } } document.setDocumentNumber(i); documentsByNumber[i] = document; - for (Fieldable field : document.getDocument().getFields()) { + for (IndexableField field : document.getDocument()) { if (fields == null || fields.contains(field.name())) { - if (field.isTermVectorStored()) { + if (field.storeTermVectors()) { if (document.getVectorSpace() == null) { document.setVectorSpace(new HashMap>()); } @@ -290,8 +290,8 @@ if (document == null) { continue; // deleted } - for (Fieldable field : document.getDocument().getFields()) { - if (field.isTermVectorStored() && field.isStoreOffsetWithTermVector()) { + for (IndexableField field : document.getDocument()) { + if (field.storeTermVectors() && field.storeTermVectorOffsets()) { TermPositionVector termPositionVector = (TermPositionVector) sourceIndexReader.getTermFreqVector(document.getDocumentNumber(), field.name()); if (termPositionVector != null) { for (int i = 0; i < termPositionVector.getTerms().length; i++) { Index: lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexReader.java =================================================================== --- lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexReader.java (revision 1158028) +++ lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexReader.java (working copy) @@ -30,7 +30,6 @@ import java.util.Comparator; import org.apache.lucene.document.Document; -import org.apache.lucene.document.FieldSelector; import org.apache.lucene.index.*; import org.apache.lucene.index.codecs.PerDocValues; import org.apache.lucene.store.Directory; @@ -252,42 +251,6 @@ } /** - * Return the {@link org.apache.lucene.document.Document} at the nth - * position. -

- * Warning! - * The resulting document is the actual stored document instance - * and not a deserialized clone as retuned by an IndexReader - * over a {@link org.apache.lucene.store.Directory}. - * I.e., if you need to touch the document, clone it first! - *

- * This can also be seen as a feature for live changes of stored values, - * but be careful! Adding a field with an name unknown to the index - * or to a field with previously no stored values will make - * {@link org.apache.lucene.store.instantiated.InstantiatedIndexReader#getFieldNames(org.apache.lucene.index.IndexReader.FieldOption)} - * out of sync, causing problems for instance when merging the - * instantiated index to another index. -

- * This implementation ignores the field selector! All stored fields are always returned! - *

- * - * @param n document number - * @param fieldSelector ignored - * @return The stored fields of the {@link org.apache.lucene.document.Document} at the nth position - * @throws CorruptIndexException if the index is corrupt - * @throws IOException if there is a low-level IO error - * - * @see org.apache.lucene.document.Fieldable - * @see org.apache.lucene.document.FieldSelector - * @see org.apache.lucene.document.SetBasedFieldSelector - * @see org.apache.lucene.document.LoadFirstFieldSelector - */ - @Override - public Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException { - return document(n); - } - - /** * Returns the stored fields of the nth * Document in this index. *

@@ -313,6 +276,11 @@ return getIndex().getDocumentsByNumber()[n].getDocument(); } + @Override + public void document(int docID, StoredFieldVisitor visitor) throws IOException { + throw new UnsupportedOperationException(); + } + /** * never ever touch these values. it is the true values, unless norms have * been touched. Index: lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedDocument.java =================================================================== --- lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedDocument.java (revision 1158028) +++ lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedDocument.java (working copy) @@ -68,7 +68,6 @@ return document; } - @Override public String toString() { return document.toString(); Index: lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestRealTime.java =================================================================== --- lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestRealTime.java (revision 1158028) +++ lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestRealTime.java (working copy) @@ -20,6 +20,7 @@ import org.apache.lucene.search.Scorer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.StringField; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.util.LuceneTestCase; @@ -43,7 +44,7 @@ Collector collector; doc = new Document(); - doc.add(new Field("f", "a", Field.Store.NO, Field.Index.NOT_ANALYZED)); + doc.add(new StringField("f", "a")); writer.addDocument(doc); writer.commit(); @@ -52,7 +53,7 @@ assertEquals(1, collector.hits); doc = new Document(); - doc.add(new Field("f", "a", Field.Store.NO, Field.Index.NOT_ANALYZED)); + doc.add(new StringField("f", "a")); writer.addDocument(doc); writer.commit(); Index: lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestIndicesEquals.java =================================================================== --- lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestIndicesEquals.java (revision 1158028) +++ lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestIndicesEquals.java (working copy) @@ -29,6 +29,8 @@ import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.MultiNorms; @@ -204,19 +206,47 @@ private void assembleDocument(Document document, int i) { - document.add(new Field("a", i + " Do you really want to go and live in that house all winter?", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + customType.setStoreTermVectors(true); + customType.setStoreTermVectorOffsets(true); + customType.setStoreTermVectorPositions(true); + //document.add(new Field("a", i + " Do you really want to go and live in that house all winter?", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); + document.add(new Field("a", customType, i + " Do you really want to go and live in that house all winter?")); if (i > 0) { - document.add(new Field("b0", i + " All work and no play makes Jack a dull boy", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); - document.add(new Field("b1", i + " All work and no play makes Jack a dull boy", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS, Field.TermVector.NO)); - document.add(new Field("b2", i + " All work and no play makes Jack a dull boy", Field.Store.NO, Field.Index.NOT_ANALYZED, Field.TermVector.NO)); - document.add(new Field("b3", i + " All work and no play makes Jack a dull boy", Field.Store.YES, Field.Index.NO, Field.TermVector.NO)); + //document.add(new Field("b0", i + " All work and no play makes Jack a dull boy", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); + document.add(new Field("b0", customType, i + " All work and no play makes Jack a dull boy")); + + //document.add(new Field("b1", i + " All work and no play makes Jack a dull boy", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS, Field.TermVector.NO)); + FieldType customType2 = new FieldType(TextField.TYPE_UNSTORED); + customType2.setStored(true); + customType2.setTokenized(false); + customType2.setOmitNorms(true); + document.add(new Field("b1", customType2, i + " All work and no play makes Jack a dull boy")); + + //document.add(new Field("b2", i + " All work and no play makes Jack a dull boy", Field.Store.NO, Field.Index.NOT_ANALYZED, Field.TermVector.NO)); + FieldType customType3 = new FieldType(TextField.TYPE_UNSTORED); + customType3.setTokenized(false); + document.add(new Field("b1", customType3, i + " All work and no play makes Jack a dull boy")); + + //document.add(new Field("b3", i + " All work and no play makes Jack a dull boy", Field.Store.YES, Field.Index.NO, Field.TermVector.NO)); + FieldType customType4 = new FieldType(TextField.TYPE_UNSTORED); + customType4.setStored(true); + customType4.setIndexed(false); + customType4.setTokenized(false); + document.add(new Field("b1", customType4, i + " All work and no play makes Jack a dull boy")); if (i > 1) { - document.add(new Field("c", i + " Redrum redrum", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); + //document.add(new Field("c", i + " Redrum redrum", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); + document.add(new Field("c", customType, i + " Redrum redrum")); if (i > 2) { - document.add(new Field("d", i + " Hello Danny, come and play with us... forever and ever. and ever.", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); + //document.add(new Field("d", i + " Hello Danny, come and play with us... forever and ever. and ever.", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); + document.add(new Field("d", customType, i + " Hello Danny, come and play with us... forever and ever. and ever.")); if (i > 3) { - Field f = new Field("e", i + " Heres Johnny!", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS); - f.setOmitNorms(true); + //Field f = new Field("e", i + " Heres Johnny!", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS); + //f.setOmitNorms(true); + FieldType customType5 = new FieldType(TextField.TYPE_UNSTORED); + customType5.setOmitNorms(true); + Field f = new Field("e", customType5, i + " Heres Johnny!"); document.add(f); if (i > 4) { final List tokens = new ArrayList(2); @@ -247,7 +277,8 @@ } }; - document.add(new Field("f", ts)); + //document.add(new Field("f", ts)); + document.add(new TextField("f", ts)); } } } Index: lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestUnoptimizedReaderOnConstructor.java =================================================================== --- lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestUnoptimizedReaderOnConstructor.java (revision 1158028) +++ lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestUnoptimizedReaderOnConstructor.java (working copy) @@ -25,7 +25,7 @@ import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; +import org.apache.lucene.document.TextField; /** * @since 2009-mar-30 13:15:49 @@ -66,7 +66,7 @@ private void addDocument(IndexWriter iw, String text) throws IOException { Document doc = new Document(); - doc.add(new Field("field", text, Field.Store.NO, Field.Index.ANALYZED)); + doc.add(new TextField("field", text)); iw.addDocument(doc); } } Index: lucene/contrib/misc/src/test/org/apache/lucene/index/TestContribFieldsReader.java =================================================================== --- lucene/contrib/misc/src/test/org/apache/lucene/index/TestContribFieldsReader.java (revision 0) +++ lucene/contrib/misc/src/test/org/apache/lucene/index/TestContribFieldsReader.java (revision 1160484) @@ -0,0 +1,319 @@ +package org.apache.lucene.index; + +/** + * 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. + */ + +import java.io.File; +import java.io.IOException; +import java.util.*; + +import org.apache.lucene.analysis.MockAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldSelector; +import org.apache.lucene.document.FieldSelectorResult; +import org.apache.lucene.document.FieldSelectorVisitor; +import org.apache.lucene.document.LoadFirstFieldSelector; +import org.apache.lucene.document.SetBasedFieldSelector; +import org.apache.lucene.index.IndexWriterConfig.OpenMode; +import org.apache.lucene.store.AlreadyClosedException; +import org.apache.lucene.store.Directory; +import org.apache.lucene.util.LuceneTestCase; +import org.apache.lucene.util._TestUtil; +import org.junit.AfterClass; +import org.junit.BeforeClass; + + +public class TestContribFieldsReader extends LuceneTestCase { + private static Directory dir; + private static org.apache.lucene.document.Document testDoc = new org.apache.lucene.document.Document(); + private static FieldInfos fieldInfos = null; + + @BeforeClass + public static void beforeClass() throws Exception { + fieldInfos = new FieldInfos(); + DocHelper.setupDoc(testDoc); + _TestUtil.add(testDoc, fieldInfos); + dir = newDirectory(); + IndexWriterConfig conf = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMergePolicy(newLogMergePolicy()); + ((LogMergePolicy) conf.getMergePolicy()).setUseCompoundFile(false); + IndexWriter writer = new IndexWriter(dir, conf); + writer.addDocument(testDoc); + writer.close(); + } + + @AfterClass + public static void afterClass() throws Exception { + dir.close(); + dir = null; + fieldInfos = null; + testDoc = null; + } + + private Document getDocument(IndexReader ir, int docID, FieldSelector selector) throws IOException { + final FieldSelectorVisitor visitor = new FieldSelectorVisitor(selector); + ir.document(docID, visitor); + return visitor.getDocument(); + } + + public void testLazyFields() throws Exception { + assertTrue(dir != null); + assertTrue(fieldInfos != null); + IndexReader reader = IndexReader.open(dir); + Set loadFieldNames = new HashSet(); + loadFieldNames.add(DocHelper.TEXT_FIELD_1_KEY); + loadFieldNames.add(DocHelper.TEXT_FIELD_UTF1_KEY); + Set lazyFieldNames = new HashSet(); + //new String[]{DocHelper.LARGE_LAZY_FIELD_KEY, DocHelper.LAZY_FIELD_KEY, DocHelper.LAZY_FIELD_BINARY_KEY}; + lazyFieldNames.add(DocHelper.LARGE_LAZY_FIELD_KEY); + lazyFieldNames.add(DocHelper.LAZY_FIELD_KEY); + lazyFieldNames.add(DocHelper.LAZY_FIELD_BINARY_KEY); + lazyFieldNames.add(DocHelper.TEXT_FIELD_UTF2_KEY); + SetBasedFieldSelector fieldSelector = new SetBasedFieldSelector(loadFieldNames, lazyFieldNames); + Document doc = getDocument(reader, 0, fieldSelector); + assertTrue("doc is null and it shouldn't be", doc != null); + IndexableField field = doc.getField(DocHelper.LAZY_FIELD_KEY); + assertTrue("field is null and it shouldn't be", field != null); + assertTrue("field is not lazy and it should be", field.getClass().getSimpleName().equals("LazyField")); + String value = field.stringValue(); + assertTrue("value is null and it shouldn't be", value != null); + assertTrue(value + " is not equal to " + DocHelper.LAZY_FIELD_TEXT, value.equals(DocHelper.LAZY_FIELD_TEXT) == true); + assertTrue("calling stringValue() twice should give same reference", field.stringValue() == field.stringValue()); + + field = doc.getField(DocHelper.TEXT_FIELD_1_KEY); + assertTrue("field is null and it shouldn't be", field != null); + assertFalse("Field is lazy and it should not be", field.getClass().getSimpleName().equals("LazyField")); + field = doc.getField(DocHelper.TEXT_FIELD_UTF1_KEY); + assertTrue("field is null and it shouldn't be", field != null); + assertFalse("Field is lazy and it should not be", field.getClass().getSimpleName().equals("LazyField")); + assertTrue(field.stringValue() + " is not equal to " + DocHelper.FIELD_UTF1_TEXT, field.stringValue().equals(DocHelper.FIELD_UTF1_TEXT) == true); + + field = doc.getField(DocHelper.TEXT_FIELD_UTF2_KEY); + assertTrue("field is null and it shouldn't be", field != null); + assertTrue("Field is lazy and it should not be", field.getClass().getSimpleName().equals("LazyField")); + assertTrue(field.stringValue() + " is not equal to " + DocHelper.FIELD_UTF2_TEXT, field.stringValue().equals(DocHelper.FIELD_UTF2_TEXT) == true); + + field = doc.getField(DocHelper.LAZY_FIELD_BINARY_KEY); + assertTrue("field is null and it shouldn't be", field != null); + assertTrue("stringValue isn't null for lazy binary field", field.stringValue() == null); + + byte [] bytes = field.binaryValue().bytes; + assertTrue("bytes is null and it shouldn't be", bytes != null); + assertTrue("", DocHelper.LAZY_FIELD_BINARY_BYTES.length == bytes.length); + assertTrue("calling binaryValue() twice should give same reference", field.binaryValue().bytes == field.binaryValue().bytes); + for (int i = 0; i < bytes.length; i++) { + assertTrue("byte[" + i + "] is mismatched", bytes[i] == DocHelper.LAZY_FIELD_BINARY_BYTES[i]); + + } + reader.close(); + } + + public void testLatentFields() throws Exception { + assertTrue(dir != null); + assertTrue(fieldInfos != null); + IndexReader reader = IndexReader.open(dir); + Set loadFieldNames = new HashSet(); + loadFieldNames.add(DocHelper.TEXT_FIELD_1_KEY); + loadFieldNames.add(DocHelper.TEXT_FIELD_UTF1_KEY); + Set lazyFieldNames = new HashSet(); + //new String[]{DocHelper.LARGE_LAZY_FIELD_KEY, DocHelper.LAZY_FIELD_KEY, DocHelper.LAZY_FIELD_BINARY_KEY}; + lazyFieldNames.add(DocHelper.LARGE_LAZY_FIELD_KEY); + lazyFieldNames.add(DocHelper.LAZY_FIELD_KEY); + lazyFieldNames.add(DocHelper.LAZY_FIELD_BINARY_KEY); + lazyFieldNames.add(DocHelper.TEXT_FIELD_UTF2_KEY); + + // Use LATENT instead of LAZY + SetBasedFieldSelector fieldSelector = new SetBasedFieldSelector(loadFieldNames, lazyFieldNames) { + @Override + public FieldSelectorResult accept(String fieldName) { + final FieldSelectorResult result = super.accept(fieldName); + if (result == FieldSelectorResult.LAZY_LOAD) { + return FieldSelectorResult.LATENT; + } else { + return result; + } + } + }; + + Document doc = getDocument(reader, 0, fieldSelector); + assertTrue("doc is null and it shouldn't be", doc != null); + IndexableField field = doc.getField(DocHelper.LAZY_FIELD_KEY); + assertTrue("field is null and it shouldn't be", field != null); + assertTrue("field is not lazy and it should be", field.getClass().getSimpleName().equals("LazyField")); + String value = field.stringValue(); + assertTrue("value is null and it shouldn't be", value != null); + assertTrue(value + " is not equal to " + DocHelper.LAZY_FIELD_TEXT, value.equals(DocHelper.LAZY_FIELD_TEXT) == true); + assertTrue("calling stringValue() twice should give different references", field.stringValue() != field.stringValue()); + + field = doc.getField(DocHelper.TEXT_FIELD_1_KEY); + assertTrue("field is null and it shouldn't be", field != null); + assertFalse("Field is lazy and it should not be", field.getClass().getSimpleName().equals("LazyField")); + assertTrue("calling stringValue() twice should give same reference", field.stringValue() == field.stringValue()); + + field = doc.getField(DocHelper.TEXT_FIELD_UTF1_KEY); + assertTrue("field is null and it shouldn't be", field != null); + assertFalse("Field is lazy and it should not be", field.getClass().getSimpleName().equals("LazyField")); + assertTrue(field.stringValue() + " is not equal to " + DocHelper.FIELD_UTF1_TEXT, field.stringValue().equals(DocHelper.FIELD_UTF1_TEXT) == true); + assertTrue("calling stringValue() twice should give same reference", field.stringValue() == field.stringValue()); + + field = doc.getField(DocHelper.TEXT_FIELD_UTF2_KEY); + assertTrue("field is null and it shouldn't be", field != null); + assertTrue("Field is lazy and it should not be", field.getClass().getSimpleName().equals("LazyField")); + assertTrue(field.stringValue() + " is not equal to " + DocHelper.FIELD_UTF2_TEXT, field.stringValue().equals(DocHelper.FIELD_UTF2_TEXT) == true); + assertTrue("calling stringValue() twice should give different references", field.stringValue() != field.stringValue()); + + field = doc.getField(DocHelper.LAZY_FIELD_BINARY_KEY); + assertTrue("field is null and it shouldn't be", field != null); + assertTrue("stringValue isn't null for lazy binary field", field.stringValue() == null); + assertTrue("calling binaryValue() twice should give different references", field.binaryValue().bytes != field.binaryValue().bytes); + + byte [] bytes = field.binaryValue().bytes; + assertTrue("bytes is null and it shouldn't be", bytes != null); + assertTrue("", DocHelper.LAZY_FIELD_BINARY_BYTES.length == bytes.length); + for (int i = 0; i < bytes.length; i++) { + assertTrue("byte[" + i + "] is mismatched", bytes[i] == DocHelper.LAZY_FIELD_BINARY_BYTES[i]); + + } + reader.close(); + } + + public void testLoadFirst() throws Exception { + assertTrue(dir != null); + assertTrue(fieldInfos != null); + IndexReader reader = IndexReader.open(dir); + LoadFirstFieldSelector fieldSelector = new LoadFirstFieldSelector(); + Document doc = getDocument(reader, 0, fieldSelector); + assertTrue("doc is null and it shouldn't be", doc != null); + int count = 0; + List l = doc.getFields(); + for (final IndexableField IndexableField : l ) { + Field field = (Field) IndexableField; + + assertTrue("field is null and it shouldn't be", field != null); + String sv = field.stringValue(); + assertTrue("sv is null and it shouldn't be", sv != null); + count++; + } + assertTrue(count + " does not equal: " + 1, count == 1); + reader.close(); + } + + /** + * Not really a test per se, but we should have some way of assessing whether this is worthwhile. + *

+ * Must test using a File based directory + * + * @throws Exception + */ + public void testLazyPerformance() throws Exception { + String userName = System.getProperty("user.name"); + File file = _TestUtil.getTempDir("lazyDir" + userName); + Directory tmpDir = newFSDirectory(file); + assertTrue(tmpDir != null); + + IndexWriterConfig conf = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setOpenMode(OpenMode.CREATE).setMergePolicy(newLogMergePolicy()); + ((LogMergePolicy) conf.getMergePolicy()).setUseCompoundFile(false); + IndexWriter writer = new IndexWriter(tmpDir, conf); + writer.addDocument(testDoc); + writer.close(); + + assertTrue(fieldInfos != null); + long lazyTime = 0; + long regularTime = 0; + int length = 10; + Set lazyFieldNames = new HashSet(); + lazyFieldNames.add(DocHelper.LARGE_LAZY_FIELD_KEY); + SetBasedFieldSelector fieldSelector = new SetBasedFieldSelector(Collections. emptySet(), lazyFieldNames); + + for (int i = 0; i < length; i++) { + IndexReader reader = IndexReader.open(tmpDir); + + Document doc; + doc = reader.document(0);//Load all of them + assertTrue("doc is null and it shouldn't be", doc != null); + IndexableField field = doc.getField(DocHelper.LARGE_LAZY_FIELD_KEY); + assertTrue("field is null and it shouldn't be", field != null); + assertFalse("field is lazy", field.getClass().getSimpleName().equals("LazyField")); + String value; + long start; + long finish; + start = System.currentTimeMillis(); + //On my machine this was always 0ms. + value = field.stringValue(); + finish = System.currentTimeMillis(); + assertTrue("value is null and it shouldn't be", value != null); + regularTime += (finish - start); + reader.close(); + reader = null; + doc = null; + //Hmmm, are we still in cache??? + System.gc(); + reader = IndexReader.open(tmpDir); + doc = getDocument(reader, 0, fieldSelector); + field = doc.getField(DocHelper.LARGE_LAZY_FIELD_KEY); + assertTrue("field is not lazy", field.getClass().getSimpleName().equals("LazyField")); + start = System.currentTimeMillis(); + //On my machine this took around 50 - 70ms + value = field.stringValue(); + finish = System.currentTimeMillis(); + assertTrue("value is null and it shouldn't be", value != null); + lazyTime += (finish - start); + reader.close(); + + } + tmpDir.close(); + if (VERBOSE) { + System.out.println("Average Non-lazy time (should be very close to zero): " + regularTime / length + " ms for " + length + " reads"); + System.out.println("Average Lazy Time (should be greater than zero): " + lazyTime / length + " ms for " + length + " reads"); + } + } + + public void testLoadSize() throws IOException { + IndexReader reader = IndexReader.open(dir); + Document doc; + + doc = getDocument(reader, 0, new FieldSelector(){ + public FieldSelectorResult accept(String fieldName) { + if (fieldName.equals(DocHelper.TEXT_FIELD_1_KEY) || + fieldName.equals(DocHelper.LAZY_FIELD_BINARY_KEY)) + return FieldSelectorResult.SIZE; + else if (fieldName.equals(DocHelper.TEXT_FIELD_3_KEY)) + return FieldSelectorResult.LOAD; + else + return FieldSelectorResult.NO_LOAD; + } + }); + IndexableField f1 = doc.getField(DocHelper.TEXT_FIELD_1_KEY); + IndexableField f3 = doc.getField(DocHelper.TEXT_FIELD_3_KEY); + IndexableField fb = doc.getField(DocHelper.LAZY_FIELD_BINARY_KEY); + assertTrue(f1.binaryValue()!=null); + assertTrue(f3.binaryValue()==null); + assertTrue(fb.binaryValue()!=null); + assertSizeEquals(2*DocHelper.FIELD_1_TEXT.length(), f1.binaryValue().bytes); + assertEquals(DocHelper.FIELD_3_TEXT, f3.stringValue()); + assertSizeEquals(DocHelper.LAZY_FIELD_BINARY_BYTES.length, fb.binaryValue().bytes); + + reader.close(); + } + + private void assertSizeEquals(int size, byte[] sizebytes) { + assertEquals((byte) (size>>>24), sizebytes[0]); + assertEquals((byte) (size>>>16), sizebytes[1]); + assertEquals((byte) (size>>> 8), sizebytes[2]); + assertEquals((byte) size , sizebytes[3]); + } +} \ No newline at end of file Property changes on: lucene/contrib/misc/src/test/org/apache/lucene/index/TestContribFieldsReader.java ___________________________________________________________________ Added: svn:eol-style + native Index: lucene/contrib/misc/src/test/org/apache/lucene/index/TestContribIndexReader.java =================================================================== --- lucene/contrib/misc/src/test/org/apache/lucene/index/TestContribIndexReader.java (revision 0) +++ lucene/contrib/misc/src/test/org/apache/lucene/index/TestContribIndexReader.java (revision 1160484) @@ -0,0 +1,188 @@ +package org.apache.lucene.index; + +/** + * 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. + */ + + +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; + +import org.apache.lucene.analysis.MockAnalyzer; +import org.apache.lucene.document.BinaryField; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldSelector; +import org.apache.lucene.document.FieldSelectorVisitor; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.SetBasedFieldSelector; +import org.apache.lucene.document.TextField; +import org.apache.lucene.index.IndexWriterConfig.OpenMode; +import org.apache.lucene.store.Directory; +import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.LuceneTestCase; + +public class TestContribIndexReader extends LuceneTestCase { + private Document getDocument(IndexReader ir, int docID, FieldSelector selector) throws IOException { + final FieldSelectorVisitor visitor = new FieldSelectorVisitor(selector); + ir.document(docID, visitor); + return visitor.getDocument(); + } + + static void addDoc(IndexWriter writer, String value) throws IOException { + Document doc = new Document(); + doc.add(newField("content", value, TextField.TYPE_UNSTORED)); + writer.addDocument(doc); + } + + static void addDocumentWithFields(IndexWriter writer) throws IOException { + Document doc = new Document(); + + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + customType.setTokenized(false); + + FieldType customType2 = new FieldType(TextField.TYPE_UNSTORED); + customType2.setStored(true); + + FieldType customType3 = new FieldType(); + customType3.setStored(true); + doc.add(newField("keyword", "test1", customType)); + doc.add(newField("text", "test1", customType2)); + doc.add(newField("unindexed", "test1", customType3)); + doc.add(new TextField("unstored","test1")); + writer.addDocument(doc); + } + + + static void addDocumentWithDifferentFields(IndexWriter writer) throws IOException { + Document doc = new Document(); + + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + customType.setTokenized(false); + + FieldType customType2 = new FieldType(TextField.TYPE_UNSTORED); + customType2.setStored(true); + + FieldType customType3 = new FieldType(); + customType3.setStored(true); + doc.add(newField("keyword2", "test1", customType)); + doc.add(newField("text2", "test1", customType2)); + doc.add(newField("unindexed2", "test1", customType3)); + doc.add(new TextField("unstored2","test1")); + writer.addDocument(doc); + } + + static void addDocumentWithTermVectorFields(IndexWriter writer) throws IOException { + Document doc = new Document(); + FieldType customType4 = new FieldType(TextField.TYPE_UNSTORED); + customType4.setStored(true); + FieldType customType5 = new FieldType(TextField.TYPE_UNSTORED); + customType5.setStored(true); + customType5.setStoreTermVectors(true); + FieldType customType6 = new FieldType(TextField.TYPE_UNSTORED); + customType6.setStored(true); + customType6.setStoreTermVectors(true); + customType6.setStoreTermVectorOffsets(true); + FieldType customType7 = new FieldType(TextField.TYPE_UNSTORED); + customType7.setStored(true); + customType7.setStoreTermVectors(true); + customType7.setStoreTermVectorPositions(true); + FieldType customType8 = new FieldType(TextField.TYPE_UNSTORED); + customType8.setStored(true); + customType8.setStoreTermVectors(true); + customType8.setStoreTermVectorOffsets(true); + customType8.setStoreTermVectorPositions(true); + doc.add(newField("tvnot","tvnot",customType4)); + doc.add(newField("termvector","termvector",customType5)); + doc.add(newField("tvoffset","tvoffset", customType6)); + doc.add(newField("tvposition","tvposition", customType7)); + doc.add(newField("tvpositionoffset","tvpositionoffset", customType8)); + + writer.addDocument(doc); + } + + public void testBinaryFields() throws IOException { + Directory dir = newDirectory(); + byte[] bin = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + + IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMergePolicy(newLogMergePolicy())); + + for (int i = 0; i < 10; i++) { + addDoc(writer, "document number " + (i + 1)); + addDocumentWithFields(writer); + addDocumentWithDifferentFields(writer); + addDocumentWithTermVectorFields(writer); + } + writer.close(); + writer = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setOpenMode(OpenMode.APPEND).setMergePolicy(newLogMergePolicy())); + Document doc = new Document(); + doc.add(new BinaryField("bin1", bin)); + doc.add(new TextField("junk", "junk text")); + writer.addDocument(doc); + writer.close(); + IndexReader reader = IndexReader.open(dir, false); + Document doc2 = reader.document(reader.maxDoc() - 1); + IndexableField[] fields = doc2.getFields("bin1"); + assertNotNull(fields); + assertEquals(1, fields.length); + Field b1 = (Field) fields[0]; + assertTrue(b1.isBinary()); + BytesRef bytesRef = b1.binaryValue(); + assertEquals(bin.length, bytesRef.length); + for (int i = 0; i < bin.length; i++) { + assertEquals(bin[i], bytesRef.bytes[i + bytesRef.offset]); + } + Set lazyFields = new HashSet(); + lazyFields.add("bin1"); + FieldSelector sel = new SetBasedFieldSelector(new HashSet(), lazyFields); + doc2 = getDocument(reader, reader.maxDoc() - 1, sel); + fields = doc2.getFields("bin1"); + assertNotNull(fields); + assertEquals(1, fields.length); + IndexableField fb1 = fields[0]; + assertTrue(fb1.binaryValue()!=null); + bytesRef = fb1.binaryValue(); + assertEquals(bin.length, bytesRef.bytes.length); + assertEquals(bin.length, bytesRef.length); + for (int i = 0; i < bin.length; i++) { + assertEquals(bin[i], bytesRef.bytes[i + bytesRef.offset]); + } + reader.close(); + // force optimize + + + writer = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setOpenMode(OpenMode.APPEND).setMergePolicy(newLogMergePolicy())); + writer.optimize(); + writer.close(); + reader = IndexReader.open(dir, false); + doc2 = reader.document(reader.maxDoc() - 1); + fields = doc2.getFields("bin1"); + assertNotNull(fields); + assertEquals(1, fields.length); + b1 = (Field) fields[0]; + assertTrue(b1.isBinary()); + bytesRef = b1.binaryValue(); + assertEquals(bin.length, bytesRef.length); + for (int i = 0; i < bin.length; i++) { + assertEquals(bin[i], bytesRef.bytes[i + bytesRef.offset]); + } + reader.close(); + dir.close(); + } +} Property changes on: lucene/contrib/misc/src/test/org/apache/lucene/index/TestContribIndexReader.java ___________________________________________________________________ Added: svn:eol-style + native Index: lucene/contrib/misc/src/test/org/apache/lucene/index/TestContribParallelReader.java =================================================================== --- lucene/contrib/misc/src/test/org/apache/lucene/index/TestContribParallelReader.java (revision 0) +++ lucene/contrib/misc/src/test/org/apache/lucene/index/TestContribParallelReader.java (revision 1159961) @@ -0,0 +1,156 @@ +package org.apache.lucene.index; + +/** + * 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. + */ + +import java.io.IOException; +import java.util.Arrays; +import java.util.Random; + +import org.apache.lucene.analysis.MockAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.FieldSelector; +import org.apache.lucene.document.FieldSelectorVisitor; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.MapFieldSelector; +import org.apache.lucene.document.TextField; +import org.apache.lucene.search.*; +import org.apache.lucene.store.Directory; +import org.apache.lucene.util.LuceneTestCase; + +public class TestContribParallelReader extends LuceneTestCase { + + private IndexSearcher parallel; + private IndexSearcher single; + private Directory dir, dir1, dir2; + + @Override + public void setUp() throws Exception { + super.setUp(); + single = single(random); + parallel = parallel(random); + } + + @Override + public void tearDown() throws Exception { + single.getIndexReader().close(); + single.close(); + parallel.getIndexReader().close(); + parallel.close(); + dir.close(); + dir1.close(); + dir2.close(); + super.tearDown(); + } + + // Fields 1-4 indexed together: + private IndexSearcher single(Random random) throws IOException { + dir = newDirectory(); + IndexWriter w = new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random))); + Document d1 = new Document(); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + d1.add(newField("f1", "v1", customType)); + d1.add(newField("f2", "v1", customType)); + d1.add(newField("f3", "v1", customType)); + d1.add(newField("f4", "v1", customType)); + w.addDocument(d1); + Document d2 = new Document(); + d2.add(newField("f1", "v2", customType)); + d2.add(newField("f2", "v2", customType)); + d2.add(newField("f3", "v2", customType)); + d2.add(newField("f4", "v2", customType)); + w.addDocument(d2); + w.close(); + + return new IndexSearcher(dir, false); + } + + // Fields 1 & 2 in one index, 3 & 4 in other, with ParallelReader: + private IndexSearcher parallel(Random random) throws IOException { + dir1 = getDir1(random); + dir2 = getDir2(random); + ParallelReader pr = new ParallelReader(); + pr.add(IndexReader.open(dir1, false)); + pr.add(IndexReader.open(dir2, false)); + return newSearcher(pr); + } + + private Document getDocument(IndexReader ir, int docID, FieldSelector selector) throws IOException { + final FieldSelectorVisitor visitor = new FieldSelectorVisitor(selector); + ir.document(docID, visitor); + return visitor.getDocument(); + } + + public void testDocument() throws IOException { + Directory dir1 = getDir1(random); + Directory dir2 = getDir2(random); + ParallelReader pr = new ParallelReader(); + pr.add(IndexReader.open(dir1, false)); + pr.add(IndexReader.open(dir2, false)); + + Document doc11 = getDocument(pr, 0, new MapFieldSelector("f1")); + Document doc24 = getDocument(pr, 1, new MapFieldSelector(Arrays.asList("f4"))); + Document doc223 = getDocument(pr, 1, new MapFieldSelector("f2", "f3")); + + assertEquals(1, doc11.getFields().size()); + assertEquals(1, doc24.getFields().size()); + assertEquals(2, doc223.getFields().size()); + + assertEquals("v1", doc11.get("f1")); + assertEquals("v2", doc24.get("f4")); + assertEquals("v2", doc223.get("f2")); + assertEquals("v2", doc223.get("f3")); + pr.close(); + dir1.close(); + dir2.close(); + } + + private Directory getDir1(Random random) throws IOException { + Directory dir1 = newDirectory(); + IndexWriter w1 = new IndexWriter(dir1, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random))); + Document d1 = new Document(); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + d1.add(newField("f1", "v1", customType)); + d1.add(newField("f2", "v1", customType)); + w1.addDocument(d1); + Document d2 = new Document(); + d2.add(newField("f1", "v2", customType)); + d2.add(newField("f2", "v2", customType)); + w1.addDocument(d2); + w1.close(); + return dir1; + } + + private Directory getDir2(Random random) throws IOException { + Directory dir2 = newDirectory(); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + IndexWriter w2 = new IndexWriter(dir2, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random))); + Document d3 = new Document(); + d3.add(newField("f3", "v1", customType)); + d3.add(newField("f4", "v1", customType)); + w2.addDocument(d3); + Document d4 = new Document(); + d4.add(newField("f3", "v2", customType)); + d4.add(newField("f4", "v2", customType)); + w2.addDocument(d4); + w2.close(); + return dir2; + } +} Property changes on: lucene/contrib/misc/src/test/org/apache/lucene/index/TestContribParallelReader.java ___________________________________________________________________ Added: svn:eol-style + native Index: lucene/contrib/misc/src/test/org/apache/lucene/index/TestLazyBug.java =================================================================== --- lucene/contrib/misc/src/test/org/apache/lucene/index/TestLazyBug.java (revision 0) +++ lucene/contrib/misc/src/test/org/apache/lucene/index/TestLazyBug.java (revision 1159961) @@ -0,0 +1,145 @@ +package org.apache.lucene.index; + +/** + * 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. + */ + +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.apache.lucene.analysis.MockAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.FieldSelector; +import org.apache.lucene.document.FieldSelectorResult; +import org.apache.lucene.document.FieldSelectorVisitor; +import org.apache.lucene.document.TextField; +import org.apache.lucene.store.Directory; +import org.apache.lucene.util.LuceneTestCase; +import org.junit.AfterClass; +import org.junit.BeforeClass; + + +/** + * Test demonstrating EOF bug on the last field of the last doc + * if other docs have allready been accessed. + */ +public class TestLazyBug extends LuceneTestCase { + + public static int NUM_DOCS = TEST_NIGHTLY ? 500 : 50; + public static int NUM_FIELDS = TEST_NIGHTLY ? 100 : 10; + + private static String[] data = new String[] { + "now", + "is the time", + "for all good men", + "to come to the aid", + "of their country!", + "this string contains big chars:{\u0111 \u0222 \u0333 \u1111 \u2222 \u3333}", + "this string is a bigger string, mary had a little lamb, little lamb, little lamb!" + }; + + private static Set dataset = asSet(data); + + private static String MAGIC_FIELD = "f"+(NUM_FIELDS/3); + + private static Directory directory; + + @BeforeClass + public static void beforeClass() throws Exception { + directory = makeIndex(); + } + + @AfterClass + public static void afterClass() throws Exception { + directory.close(); + directory = null; + } + + private static FieldSelector SELECTOR = new FieldSelector() { + public FieldSelectorResult accept(String f) { + if (f.equals(MAGIC_FIELD)) { + return FieldSelectorResult.LOAD; + } + return FieldSelectorResult.LAZY_LOAD; + } + }; + + private static Directory makeIndex() throws Exception { + Directory dir = newDirectory(); + try { + IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig( + TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMergePolicy(newLogMergePolicy())); + LogMergePolicy lmp = (LogMergePolicy) writer.getConfig().getMergePolicy(); + lmp.setUseCompoundFile(false); + for (int d = 1; d <= NUM_DOCS; d++) { + Document doc = new Document(); + for (int f = 1; f <= NUM_FIELDS; f++ ) { + doc.add(newField("f"+f, + data[f % data.length] + + '#' + data[random.nextInt(data.length)], + TextField.TYPE_UNSTORED)); + } + writer.addDocument(doc); + } + writer.close(); + } catch (Exception e) { + throw new RuntimeException(e); + } + return dir; + } + + public void doTest(int[] docs) throws Exception { + IndexReader reader = IndexReader.open(directory, true); + for (int i = 0; i < docs.length; i++) { + final FieldSelectorVisitor visitor = new FieldSelectorVisitor(SELECTOR); + reader.document(docs[i], visitor); + Document d = visitor.getDocument(); + d.get(MAGIC_FIELD); + + List fields = d.getFields(); + for (Iterator fi = fields.iterator(); fi.hasNext(); ) { + IndexableField f=null; + try { + f = fi.next(); + String fname = f.name(); + String fval = f.stringValue(); + assertNotNull(docs[i]+" FIELD: "+fname, fval); + String[] vals = fval.split("#"); + if (!dataset.contains(vals[0]) || !dataset.contains(vals[1])) { + fail("FIELD:"+fname+",VAL:"+fval); + } + } catch (Exception e) { + throw new Exception(docs[i]+" WTF: "+f.name(), e); + } + } + } + reader.close(); + } + + public void testLazyWorks() throws Exception { + doTest(new int[] { NUM_DOCS-1 }); + } + + public void testLazyAlsoWorks() throws Exception { + doTest(new int[] { NUM_DOCS-1, NUM_DOCS/2 }); + } + + public void testLazyBroken() throws Exception { + doTest(new int[] { NUM_DOCS/2, NUM_DOCS-1 }); + } + +} Property changes on: lucene/contrib/misc/src/test/org/apache/lucene/index/TestLazyBug.java ___________________________________________________________________ Added: svn:eol-style + native Index: lucene/contrib/misc/src/test/org/apache/lucene/index/TestMultiPassIndexSplitter.java =================================================================== --- lucene/contrib/misc/src/test/org/apache/lucene/index/TestMultiPassIndexSplitter.java (revision 1158028) +++ lucene/contrib/misc/src/test/org/apache/lucene/index/TestMultiPassIndexSplitter.java (working copy) @@ -19,6 +19,8 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.store.Directory; import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.util.BytesRef; @@ -36,8 +38,13 @@ Document doc; for (int i = 0; i < NUM_DOCS; i++) { doc = new Document(); - doc.add(newField("id", i + "", Field.Store.YES, Field.Index.NOT_ANALYZED)); - doc.add(newField("f", i + " " + i, Field.Store.YES, Field.Index.ANALYZED)); + FieldType storedTextType = new FieldType(TextField.TYPE_UNSTORED); + storedTextType.setStored(true); + storedTextType.setTokenized(false); + FieldType storedTextType2 = new FieldType(TextField.TYPE_UNSTORED); + storedTextType.setStored(true); + doc.add(newField("id", i + "", storedTextType)); + doc.add(newField("f", i + " " + i, storedTextType2)); w.addDocument(doc); } w.close(); Index: lucene/contrib/misc/src/test/org/apache/lucene/index/codecs/appending/TestAppendingCodec.java =================================================================== --- lucene/contrib/misc/src/test/org/apache/lucene/index/codecs/appending/TestAppendingCodec.java (revision 1158028) +++ lucene/contrib/misc/src/test/org/apache/lucene/index/codecs/appending/TestAppendingCodec.java (working copy) @@ -22,9 +22,8 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; -import org.apache.lucene.document.Field.TermVector; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.Fields; import org.apache.lucene.index.IndexReader; @@ -141,7 +140,12 @@ ((TieredMergePolicy)cfg.getMergePolicy()).setUseCompoundFile(false); IndexWriter writer = new IndexWriter(dir, cfg); Document doc = new Document(); - doc.add(newField("f", text, Store.YES, Index.ANALYZED, TermVector.WITH_POSITIONS_OFFSETS)); + FieldType storedTextType = new FieldType(TextField.TYPE_UNSTORED); + storedTextType.setStored(true); + storedTextType.setStoreTermVectors(true); + storedTextType.setStoreTermVectorPositions(true); + storedTextType.setStoreTermVectorOffsets(true); + doc.add(newField("f", text, storedTextType)); writer.addDocument(doc); writer.commit(); writer.addDocument(doc); @@ -149,8 +153,8 @@ writer.close(); IndexReader reader = IndexReader.open(dir, null, true, 1, new AppendingCodecProvider()); assertEquals(2, reader.numDocs()); - doc = reader.document(0); - assertEquals(text, doc.get("f")); + Document doc2 = reader.document(0); + assertEquals(text, doc2.get("f")); Fields fields = MultiFields.getFields(reader); Terms terms = fields.terms("f"); assertNotNull(terms); Index: lucene/contrib/misc/src/test/org/apache/lucene/index/TestPKIndexSplitter.java =================================================================== --- lucene/contrib/misc/src/test/org/apache/lucene/index/TestPKIndexSplitter.java (revision 1158028) +++ lucene/contrib/misc/src/test/org/apache/lucene/index/TestPKIndexSplitter.java (working copy) @@ -23,8 +23,8 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.analysis.MockTokenizer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; +import org.apache.lucene.document.StringField; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriterConfig.OpenMode; import org.apache.lucene.store.Directory; import org.apache.lucene.util.Bits; @@ -102,15 +102,15 @@ StringBuilder sb = new StringBuilder(); Document doc = new Document(); String id = format.format(n); - doc.add(newField("id", id, Store.YES, Index.NOT_ANALYZED)); - doc.add(newField("indexname", indexName, Store.YES, Index.NOT_ANALYZED)); + doc.add(newField("id", id, StringField.TYPE_STORED)); + doc.add(newField("indexname", indexName, StringField.TYPE_STORED)); sb.append("a"); sb.append(n); - doc.add(newField("field1", sb.toString(), Store.YES, Index.ANALYZED)); + doc.add(newField("field1", sb.toString(), TextField.TYPE_STORED)); sb.append(" b"); sb.append(n); for (int i = 1; i < numFields; i++) { - doc.add(newField("field" + (i + 1), sb.toString(), Store.YES, Index.ANALYZED)); + doc.add(newField("field" + (i + 1), sb.toString(), TextField.TYPE_STORED)); } return doc; } Index: lucene/contrib/misc/src/test/org/apache/lucene/index/TestTermVectorAccessor.java =================================================================== --- lucene/contrib/misc/src/test/org/apache/lucene/index/TestTermVectorAccessor.java (revision 1158028) +++ lucene/contrib/misc/src/test/org/apache/lucene/index/TestTermVectorAccessor.java (working copy) @@ -3,6 +3,8 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.store.Directory; import org.apache.lucene.util.LuceneTestCase; @@ -30,33 +32,42 @@ Document doc; doc = new Document(); - doc.add(newField("a", "a b a c a d a e a f a g a h a", Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); - doc.add(newField("b", "a b c b d b e b f b g b h b", Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); - doc.add(newField("c", "a c b c d c e c f c g c h c", Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStoreTermVectors(true); + customType.setStoreTermVectorPositions(true); + customType.setStoreTermVectorOffsets(true); + doc.add(newField("a", "a b a c a d a e a f a g a h a", customType)); + doc.add(newField("b", "a b c b d b e b f b g b h b", customType)); + doc.add(newField("c", "a c b c d c e c f c g c h c", customType)); iw.addDocument(doc); doc = new Document(); - doc.add(newField("a", "a b a c a d a e a f a g a h a", Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS)); - doc.add(newField("b", "a b c b d b e b f b g b h b", Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS)); - doc.add(newField("c", "a c b c d c e c f c g c h c", Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS)); + FieldType customType2 = new FieldType(TextField.TYPE_UNSTORED); + customType2.setStoreTermVectors(true); + customType2.setStoreTermVectorPositions(true); + doc.add(newField("a", "a b a c a d a e a f a g a h a", customType2)); + doc.add(newField("b", "a b c b d b e b f b g b h b", customType2)); + doc.add(newField("c", "a c b c d c e c f c g c h c", customType2)); iw.addDocument(doc); doc = new Document(); - doc.add(newField("a", "a b a c a d a e a f a g a h a", Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.YES)); - doc.add(newField("b", "a b c b d b e b f b g b h b", Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.YES)); - doc.add(newField("c", "a c b c d c e c f c g c h c", Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.YES)); + FieldType customType3 = new FieldType(TextField.TYPE_UNSTORED); + customType3.setStoreTermVectors(true); + doc.add(newField("a", "a b a c a d a e a f a g a h a", customType3)); + doc.add(newField("b", "a b c b d b e b f b g b h b", customType3)); + doc.add(newField("c", "a c b c d c e c f c g c h c", customType3)); iw.addDocument(doc); doc = new Document(); - doc.add(newField("a", "a b a c a d a e a f a g a h a", Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.NO)); - doc.add(newField("b", "a b c b d b e b f b g b h b", Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.NO)); - doc.add(newField("c", "a c b c d c e c f c g c h c", Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.NO)); + doc.add(newField("a", "a b a c a d a e a f a g a h a", TextField.TYPE_UNSTORED)); + doc.add(newField("b", "a b c b d b e b f b g b h b", TextField.TYPE_UNSTORED)); + doc.add(newField("c", "a c b c d c e c f c g c h c", TextField.TYPE_UNSTORED)); iw.addDocument(doc); doc = new Document(); - doc.add(newField("a", "a b a c a d a e a f a g a h a", Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); - doc.add(newField("b", "a b c b d b e b f b g b h b", Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.NO)); - doc.add(newField("c", "a c b c d c e c f c g c h c", Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.YES)); + doc.add(newField("a", "a b a c a d a e a f a g a h a", customType)); + doc.add(newField("b", "a b c b d b e b f b g b h b", TextField.TYPE_UNSTORED)); + doc.add(newField("c", "a c b c d c e c f c g c h c", customType3)); iw.addDocument(doc); iw.close(); Index: lucene/contrib/misc/src/test/org/apache/lucene/index/TestFieldNormModifier.java =================================================================== --- lucene/contrib/misc/src/test/org/apache/lucene/index/TestFieldNormModifier.java (revision 1158028) +++ lucene/contrib/misc/src/test/org/apache/lucene/index/TestFieldNormModifier.java (working copy) @@ -23,6 +23,8 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.Collector; import org.apache.lucene.search.DefaultSimilarity; @@ -65,13 +67,21 @@ for (int i = 0; i < NUM_DOCS; i++) { Document d = new Document(); - d.add(newField("field", "word", Field.Store.YES, Field.Index.ANALYZED)); - d.add(newField("nonorm", "word", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS)); - d.add(newField("untokfield", "20061212 20071212", Field.Store.YES, Field.Index.ANALYZED)); + FieldType storedTextType = new FieldType(TextField.TYPE_UNSTORED); + storedTextType.setStored(true); + d.add(newField("field", "word", storedTextType)); + + FieldType storedTextType2 = new FieldType(TextField.TYPE_UNSTORED); + storedTextType2.setStored(true); + storedTextType2.setTokenized(false); + storedTextType2.setOmitNorms(true); + d.add(newField("nonorm", "word", storedTextType2)); + d.add(newField("untokfield", "20061212 20071212", storedTextType)); + for (int j = 1; j <= i; j++) { - d.add(newField("field", "crap", Field.Store.YES, Field.Index.ANALYZED)); - d.add(newField("nonorm", "more words", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS)); + d.add(newField("field", "crap", storedTextType)); + d.add(newField("nonorm", "more words", storedTextType2)); } writer.addDocument(d); } Index: lucene/contrib/misc/src/test/org/apache/lucene/index/TestIndexSplitter.java =================================================================== --- lucene/contrib/misc/src/test/org/apache/lucene/index/TestIndexSplitter.java (revision 1158028) +++ lucene/contrib/misc/src/test/org/apache/lucene/index/TestIndexSplitter.java (working copy) @@ -21,6 +21,7 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.StringField; import org.apache.lucene.index.IndexWriterConfig.OpenMode; import org.apache.lucene.store.Directory; import org.apache.lucene.util.LuceneTestCase; @@ -112,10 +113,10 @@ Directory fsDir = newFSDirectory(indexPath); IndexWriter indexWriter = new IndexWriter(fsDir, iwConfig); Document doc = new Document(); - doc.add(new Field("content", "doc 1", Field.Store.YES, Field.Index.ANALYZED_NO_NORMS)); + doc.add(new Field("content", StringField.TYPE_STORED, "doc 1")); indexWriter.addDocument(doc); doc = new Document(); - doc.add(new Field("content", "doc 2", Field.Store.YES, Field.Index.ANALYZED_NO_NORMS)); + doc.add(new Field("content", StringField.TYPE_STORED, "doc 2")); indexWriter.addDocument(doc); indexWriter.close(); fsDir.close(); Index: lucene/contrib/misc/src/test/org/apache/lucene/index/TestNRTManager.java =================================================================== --- lucene/contrib/misc/src/test/org/apache/lucene/index/TestNRTManager.java (revision 1158028) +++ lucene/contrib/misc/src/test/org/apache/lucene/index/TestNRTManager.java (working copy) @@ -33,7 +33,8 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; -import org.apache.lucene.document.Fieldable; +import org.apache.lucene.document.StringField; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.codecs.CodecProvider; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.PhraseQuery; @@ -77,17 +78,12 @@ // TODO: is there a pre-existing way to do this!!! private Document cloneDoc(Document doc1) { final Document doc2 = new Document(); - for(Fieldable f : doc1.getFields()) { + for(IndexableField f : doc1) { Field field1 = (Field) f; Field field2 = new Field(field1.name(), - field1.stringValue(), - field1.isStored() ? Field.Store.YES : Field.Store.NO, - field1.isIndexed() ? (field1.isTokenized() ? Field.Index.ANALYZED : Field.Index.NOT_ANALYZED) : Field.Index.NO); - if (field1.getOmitNorms()) { - field2.setOmitNorms(true); - } - field2.setIndexOptions(field1.getIndexOptions()); + ((Field) f).getFieldType(), + field1.stringValue()); doc2.add(field2); } @@ -240,7 +236,7 @@ final String addedField; if (random.nextBoolean()) { addedField = "extra" + random.nextInt(10); - doc.add(new Field(addedField, "a random field", Field.Store.NO, Field.Index.ANALYZED)); + doc.add(new TextField(addedField, "a random field")); } else { addedField = null; } @@ -262,7 +258,7 @@ packID = packCount.getAndIncrement() + ""; } - final Field packIDField = newField("packID", packID, Field.Store.YES, Field.Index.NOT_ANALYZED); + final Field packIDField = newField("packID", packID, StringField.TYPE_STORED); final List docIDs = new ArrayList(); final SubDocs subDocs = new SubDocs(packID, docIDs); final List docsList = new ArrayList(); Index: lucene/contrib/misc/src/test/org/apache/lucene/search/TestThreadSafe.java =================================================================== --- lucene/contrib/misc/src/test/org/apache/lucene/search/TestThreadSafe.java (revision 0) +++ lucene/contrib/misc/src/test/org/apache/lucene/search/TestThreadSafe.java (revision 1159961) @@ -0,0 +1,158 @@ +package org.apache.lucene.search; +/** + * 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. + */ + +import org.apache.lucene.util.LuceneTestCase; +import org.apache.lucene.store.Directory; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.index.IndexWriterConfig.OpenMode; +import org.apache.lucene.index.IndexableField; +import org.apache.lucene.analysis.MockAnalyzer; +import org.apache.lucene.document.*; + +import java.util.Random; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.io.IOException; + +public class TestThreadSafe extends LuceneTestCase { + Directory dir1; + + IndexReader ir1; + + class Thr extends Thread { + final int iter; + final Random rand; + final AtomicBoolean failed; + + // pass in random in case we want to make things reproducable + public Thr(int iter, Random rand, AtomicBoolean failed) { + this.iter = iter; + this.rand = rand; + this.failed = failed; + } + + @Override + public void run() { + try { + for (int i=0; i fieldsToLoad; + private Set lazyFieldsToLoad; + + /** + * Pass in the Set of {@link Field} names to load and the Set of {@link Field} names to load lazily. If both are null, the + * Document will not have any {@link Field} on it. + * @param fieldsToLoad A Set of {@link String} field names to load. May be empty, but not null + * @param lazyFieldsToLoad A Set of {@link String} field names to load lazily. May be empty, but not null + */ + public SetBasedFieldSelector(Set fieldsToLoad, Set lazyFieldsToLoad) { + this.fieldsToLoad = fieldsToLoad; + this.lazyFieldsToLoad = lazyFieldsToLoad; + } + + /** + * Indicate whether to load the field with the given name or not. If the {@link Field#name()} is not in either of the + * initializing Sets, then {@link org.apache.lucene.document.FieldSelectorResult#NO_LOAD} is returned. If a Field name + * is in both fieldsToLoad and lazyFieldsToLoad, lazy has precedence. + * + * @param fieldName The {@link Field} name to check + * @return The {@link FieldSelectorResult} + */ + public FieldSelectorResult accept(String fieldName) { + FieldSelectorResult result = FieldSelectorResult.NO_LOAD; + if (fieldsToLoad.contains(fieldName) == true){ + result = FieldSelectorResult.LOAD; + } + if (lazyFieldsToLoad.contains(fieldName) == true){ + result = FieldSelectorResult.LAZY_LOAD; + } + return result; + } +} Property changes on: lucene/contrib/misc/src/java/org/apache/lucene/document/SetBasedFieldSelector.java ___________________________________________________________________ Added: svn:eol-style + native Index: lucene/contrib/misc/src/java/org/apache/lucene/document/MapFieldSelector.java =================================================================== --- lucene/contrib/misc/src/java/org/apache/lucene/document/MapFieldSelector.java (revision 0) +++ lucene/contrib/misc/src/java/org/apache/lucene/document/MapFieldSelector.java (revision 1159961) @@ -0,0 +1,67 @@ +package org.apache.lucene.document; + +/** + * 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. + */ + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * A {@link FieldSelector} based on a Map of field names to {@link FieldSelectorResult}s + * + */ +public class MapFieldSelector implements FieldSelector { + + Map fieldSelections; + + /** Create a a MapFieldSelector + * @param fieldSelections maps from field names (String) to {@link FieldSelectorResult}s + */ + public MapFieldSelector(Map fieldSelections) { + this.fieldSelections = fieldSelections; + } + + /** Create a a MapFieldSelector + * @param fields fields to LOAD. List of Strings. All other fields are NO_LOAD. + */ + public MapFieldSelector(List fields) { + fieldSelections = new HashMap(fields.size()*5/3); + for (final String field : fields) + fieldSelections.put(field, FieldSelectorResult.LOAD); + } + + /** Create a a MapFieldSelector + * @param fields fields to LOAD. All other fields are NO_LOAD. + */ + public MapFieldSelector(String... fields) { + this(Arrays.asList(fields)); + } + + + + /** Load field according to its associated value in fieldSelections + * @param field a field name + * @return the fieldSelections value that field maps to or NO_LOAD if none. + */ + public FieldSelectorResult accept(String field) { + FieldSelectorResult selection = fieldSelections.get(field); + return selection!=null ? selection : FieldSelectorResult.NO_LOAD; + } + +} Property changes on: lucene/contrib/misc/src/java/org/apache/lucene/document/MapFieldSelector.java ___________________________________________________________________ Added: svn:eol-style + native Index: lucene/contrib/misc/src/java/org/apache/lucene/document/FieldSelectorResult.java =================================================================== --- lucene/contrib/misc/src/java/org/apache/lucene/document/FieldSelectorResult.java (revision 0) +++ lucene/contrib/misc/src/java/org/apache/lucene/document/FieldSelectorResult.java (revision 1159961) @@ -0,0 +1,78 @@ +package org.apache.lucene.document; + +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed 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. + */ + +/** + * Provides information about what should be done with this Field + * + **/ +import org.apache.lucene.index.IndexableField; // for javadocs + +public enum FieldSelectorResult { + + /** + * Load this {@link Field} every time the {@link Document} is loaded, reading in the data as it is encountered. + * {@link Document#getField(String)} should not return null. + *

+ * {@link Document#add(IndexableField)} should be called by the Reader. + */ + LOAD, + + /** + * Lazily load this {@link Field}. This means the {@link Field} is valid, but it may not actually contain its data until + * invoked. {@link Document#getField(String)} is safe to use and should + * return a valid instance of a {@link IndexableField}. + *

+ * {@link Document#add(IndexableField)} should be called by the Reader. + */ + LAZY_LOAD, + + /** + * Do not load the {@link Field}. {@link Document#getField(String)} should return null. + * {@link Document#add(IndexableField)} is not called. + *

+ * {@link Document#add(IndexableField)} should not be called by the Reader. + */ + NO_LOAD, + + /** + * Load this field as in the {@link #LOAD} case, but immediately return from {@link Field} loading for the {@link Document}. Thus, the + * Document may not have its complete set of Fields. {@link Document#getField(String)} should + * both be valid for this {@link Field} + *

+ * {@link Document#add(IndexableField)} should be called by the Reader. + */ + LOAD_AND_BREAK, + + /** Expert: Load the size of this {@link Field} rather than its value. + * Size is measured as number of bytes required to store the field == bytes for a binary or any compressed value, and 2*chars for a String value. + * The size is stored as a binary value, represented as an int in a byte[], with the higher order byte first in [0] + */ + SIZE, + + /** Expert: Like {@link #SIZE} but immediately break from the field loading loop, i.e., stop loading further fields, after the size is loaded */ + SIZE_AND_BREAK, + + /** + * Lazily load this {@link Field}, but do not cache the result. This means the {@link Field} is valid, but it may not actually contain its data until + * invoked. {@link Document#getField(String)} is safe to use and should + * return a valid instance of a {@link IndexableField}. + *

+ * {@link Document#add(IndexableField)} should be called by the Reader. + */ + LATENT +} Property changes on: lucene/contrib/misc/src/java/org/apache/lucene/document/FieldSelectorResult.java ___________________________________________________________________ Added: svn:eol-style + native Index: lucene/contrib/misc/src/java/org/apache/lucene/document/FieldSelector.java =================================================================== --- lucene/contrib/misc/src/java/org/apache/lucene/document/FieldSelector.java (revision 0) +++ lucene/contrib/misc/src/java/org/apache/lucene/document/FieldSelector.java (revision 1159961) @@ -0,0 +1,36 @@ +package org.apache.lucene.document; + +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; + +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed 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. + */ + +/** + * Similar to a {@link java.io.FileFilter}, the FieldSelector allows one to make decisions about + * what Fields get loaded on a {@link Document} by {@link FieldSelectorVisitor} + * + **/ +public interface FieldSelector { + + /** + * + * @param fieldName the field to accept or reject + * @return an instance of {@link FieldSelectorResult} + * if the {@link Field} named fieldName should be loaded. + */ + FieldSelectorResult accept(String fieldName); +} Property changes on: lucene/contrib/misc/src/java/org/apache/lucene/document/FieldSelector.java ___________________________________________________________________ Added: svn:eol-style + native Index: lucene/contrib/misc/src/java/org/apache/lucene/document/FieldSelectorVisitor.java =================================================================== --- lucene/contrib/misc/src/java/org/apache/lucene/document/FieldSelectorVisitor.java (revision 0) +++ lucene/contrib/misc/src/java/org/apache/lucene/document/FieldSelectorVisitor.java (revision 1160484) @@ -0,0 +1,325 @@ +package org.apache.lucene.document; + +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed 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. + */ + +import java.io.IOException; +import java.io.Reader; + +import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.document.BinaryField; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.NumericField; +import org.apache.lucene.document.TextField; +import org.apache.lucene.document.NumericField.DataType; +import org.apache.lucene.index.FieldInfo; +import org.apache.lucene.index.FieldReaderException; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexableField; +import org.apache.lucene.index.StoredFieldVisitor; +import org.apache.lucene.store.IndexInput; +import org.apache.lucene.util.BytesRef; + +/** Create this, passing a legacy {@link FieldSelector} to it, then + * pass this class to {@link IndexReader#document(int, + * StoredFieldVisitor)}, then call {@link #getDocument} to + * retrieve the loaded document. + + *

NOTE: If you use Lazy fields, you should not + * access the returned document after the reader has been + * closed! + */ + +public class FieldSelectorVisitor extends StoredFieldVisitor { + + private final FieldSelector selector; + private final Document doc; + + public FieldSelectorVisitor(FieldSelector selector) { + this.selector = selector; + doc = new Document(); + } + + public Document getDocument() { + return doc; + } + + @Override + public boolean binaryField(FieldInfo fieldInfo, IndexInput in, int numBytes) throws IOException { + final FieldSelectorResult accept = selector.accept(fieldInfo.name); + switch (accept) { + case LOAD: + case LOAD_AND_BREAK: + final byte[] b = new byte[numBytes]; + in.readBytes(b, 0, b.length); + doc.add(new BinaryField(fieldInfo.name, b)); + return accept != FieldSelectorResult.LOAD; + case LAZY_LOAD: + case LATENT: + addFieldLazy(in, fieldInfo, true, accept == FieldSelectorResult.LAZY_LOAD, numBytes); + return false; + case SIZE: + case SIZE_AND_BREAK: + in.seek(in.getFilePointer() + numBytes); + addFieldSize(fieldInfo, numBytes); + return accept != FieldSelectorResult.SIZE; + default: + // skip + in.seek(in.getFilePointer() + numBytes); + return false; + } + } + + @Override + public boolean stringField(FieldInfo fieldInfo, IndexInput in, int numUTF8Bytes) throws IOException { + final FieldSelectorResult accept = selector.accept(fieldInfo.name); + switch (accept) { + case LOAD: + case LOAD_AND_BREAK: + final byte[] b = new byte[numUTF8Bytes]; + in.readBytes(b, 0, b.length); + FieldType ft = new FieldType(TextField.TYPE_STORED); + ft.setStoreTermVectors(fieldInfo.storeTermVector); + ft.setStoreTermVectorOffsets(fieldInfo.storeOffsetWithTermVector); + ft.setStoreTermVectorPositions(fieldInfo.storePositionWithTermVector); + doc.add(new Field(fieldInfo.name, ft, new String(b, "UTF-8"))); + return accept != FieldSelectorResult.LOAD; + case LAZY_LOAD: + case LATENT: + addFieldLazy(in, fieldInfo, false, accept == FieldSelectorResult.LAZY_LOAD, numUTF8Bytes); + return false; + case SIZE: + case SIZE_AND_BREAK: + in.seek(in.getFilePointer() + numUTF8Bytes); + addFieldSize(fieldInfo, 2*numUTF8Bytes); + return accept != FieldSelectorResult.SIZE; + default: + // skip + in.seek(in.getFilePointer() + numUTF8Bytes); + return false; + } + } + + @Override + public boolean intField(FieldInfo fieldInfo, int value) throws IOException { + FieldType ft = new FieldType(NumericField.TYPE_STORED); + ft.setIndexed(fieldInfo.isIndexed); + ft.setOmitNorms(fieldInfo.omitNorms); + ft.setIndexOptions(fieldInfo.indexOptions); + return addNumericField(fieldInfo, new NumericField(fieldInfo.name, ft).setIntValue(value)); + } + + @Override + public boolean longField(FieldInfo fieldInfo, long value) throws IOException { + FieldType ft = new FieldType(NumericField.TYPE_STORED); + ft.setIndexed(fieldInfo.isIndexed); + ft.setOmitNorms(fieldInfo.omitNorms); + ft.setIndexOptions(fieldInfo.indexOptions); + return addNumericField(fieldInfo, new NumericField(fieldInfo.name, ft).setLongValue(value)); + } + + @Override + public boolean floatField(FieldInfo fieldInfo, float value) throws IOException { + FieldType ft = new FieldType(NumericField.TYPE_STORED); + ft.setIndexed(fieldInfo.isIndexed); + ft.setOmitNorms(fieldInfo.omitNorms); + ft.setIndexOptions(fieldInfo.indexOptions); + return addNumericField(fieldInfo, new NumericField(fieldInfo.name, ft).setFloatValue(value)); + } + + @Override + public boolean doubleField(FieldInfo fieldInfo, double value) throws IOException { + FieldType ft = new FieldType(NumericField.TYPE_STORED); + ft.setIndexed(fieldInfo.isIndexed); + ft.setOmitNorms(fieldInfo.omitNorms); + ft.setIndexOptions(fieldInfo.indexOptions); + return addNumericField(fieldInfo, new NumericField(fieldInfo.name, ft).setDoubleValue(value)); + } + + private boolean addNumericField(FieldInfo fieldInfo, NumericField f) { + doc.add(f); + final FieldSelectorResult accept = selector.accept(fieldInfo.name); + switch (accept) { + case LOAD: + return false; + case LOAD_AND_BREAK: + return true; + case LAZY_LOAD: + case LATENT: + return false; + case SIZE: + return false; + case SIZE_AND_BREAK: + return true; + default: + return false; + } + } + + private void addFieldLazy(IndexInput in, FieldInfo fi, boolean binary, boolean cacheResult, int numBytes) throws IOException { + final IndexableField f; + final long pointer = in.getFilePointer(); + // Need to move the pointer ahead by toRead positions + in.seek(pointer+numBytes); + FieldType ft = new FieldType(); + ft.setStored(true); + ft.setOmitNorms(fi.omitNorms); + ft.setIndexOptions(fi.indexOptions); + ft.setLazy(true); + + if (binary) { + f = new LazyField(in, fi.name, ft, numBytes, pointer, binary, cacheResult); + } else { + ft.setStoreTermVectors(fi.storeTermVector); + ft.setStoreTermVectorOffsets(fi.storeOffsetWithTermVector); + ft.setStoreTermVectorPositions(fi.storePositionWithTermVector); + f = new LazyField(in, fi.name, ft, numBytes, pointer, binary, cacheResult); + } + + doc.add(f); + } + + // Add the size of field as a byte[] containing the 4 bytes of the integer byte size (high order byte first; char = 2 bytes) + // Read just the size -- caller must skip the field content to continue reading fields + // Return the size in bytes or chars, depending on field type + private void addFieldSize(FieldInfo fi, int numBytes) throws IOException { + byte[] sizebytes = new byte[4]; + sizebytes[0] = (byte) (numBytes>>>24); + sizebytes[1] = (byte) (numBytes>>>16); + sizebytes[2] = (byte) (numBytes>>> 8); + sizebytes[3] = (byte) numBytes ; + doc.add(new BinaryField(fi.name, sizebytes)); + } + + /** + * A Lazy field implementation that defers loading of fields until asked for, instead of when the Document is + * loaded. + */ + private static class LazyField extends Field { + private int toRead; + private long pointer; + private final boolean cacheResult; + private final IndexInput in; + private boolean isBinary; + + public LazyField(IndexInput in, String name, FieldType ft, int toRead, long pointer, boolean isBinary, boolean cacheResult) { + super(name, ft); + this.in = in; + this.toRead = toRead; + this.pointer = pointer; + this.isBinary = isBinary; + this.cacheResult = cacheResult; + } + + @Override + public Number numericValue() { + return null; + } + + @Override + public DataType numericDataType() { + return null; + } + + private IndexInput localFieldsStream; + + private IndexInput getFieldStream() { + if (localFieldsStream == null) { + localFieldsStream = (IndexInput) in.clone(); + } + return localFieldsStream; + } + + /** The value of the field as a Reader, or null. If null, the String value, + * binary value, or TokenStream value is used. Exactly one of stringValue(), + * readerValue(), getBinaryValue(), and tokenStreamValue() must be set. */ + @Override + public Reader readerValue() { + return null; + } + + /** The value of the field as a TokenStream, or null. If null, the Reader value, + * String value, or binary value is used. Exactly one of stringValue(), + * readerValue(), getBinaryValue(), and tokenStreamValue() must be set. */ + @Override + public TokenStream tokenStreamValue() { + return null; + } + + /** The value of the field as a String, or null. If null, the Reader value, + * binary value, or TokenStream value is used. Exactly one of stringValue(), + * readerValue(), getBinaryValue(), and tokenStreamValue() must be set. */ + @Override + synchronized public String stringValue() { + if (isBinary) { + return null; + } else { + if (fieldsData == null) { + String result = null; + IndexInput localFieldsStream = getFieldStream(); + try { + localFieldsStream.seek(pointer); + byte[] bytes = new byte[toRead]; + localFieldsStream.readBytes(bytes, 0, toRead); + result = new String(bytes, "UTF-8"); + } catch (IOException e) { + throw new FieldReaderException(e); + } + if (cacheResult == true){ + fieldsData = result; + } + return result; + } else { + return (String) fieldsData; + } + } + } + + @Override + synchronized public BytesRef binaryValue() { + if (isBinary) { + if (fieldsData == null) { + // Allocate new buffer if result is null or too small + final byte[] b = new byte[toRead]; + + IndexInput localFieldsStream = getFieldStream(); + + // Throw this IOException since IndexReader.document does so anyway, so probably not that big of a change for people + // since they are already handling this exception when getting the document + try { + localFieldsStream.seek(pointer); + localFieldsStream.readBytes(b, 0, toRead); + } catch (IOException e) { + throw new FieldReaderException(e); + } + + final BytesRef result = new BytesRef(b); + result.length = toRead; + if (cacheResult == true){ + fieldsData = result; + } + return result; + } else { + return (BytesRef) fieldsData; + } + } else { + return null; + } + } + } +} \ No newline at end of file Property changes on: lucene/contrib/misc/src/java/org/apache/lucene/document/FieldSelectorVisitor.java ___________________________________________________________________ Added: svn:eol-style + native Index: lucene/contrib/misc/src/java/org/apache/lucene/document/LoadFirstFieldSelector.java =================================================================== --- lucene/contrib/misc/src/java/org/apache/lucene/document/LoadFirstFieldSelector.java (revision 0) +++ lucene/contrib/misc/src/java/org/apache/lucene/document/LoadFirstFieldSelector.java (revision 1160484) @@ -0,0 +1,29 @@ +package org.apache.lucene.document; +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed 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. + */ + + +/** + * Load the First field and break. + *

+ * See {@link FieldSelectorResult#LOAD_AND_BREAK} + */ +public class LoadFirstFieldSelector implements FieldSelector { + + public FieldSelectorResult accept(String fieldName) { + return FieldSelectorResult.LOAD_AND_BREAK; + } +} Property changes on: lucene/contrib/misc/src/java/org/apache/lucene/document/LoadFirstFieldSelector.java ___________________________________________________________________ Added: svn:eol-style + native Index: lucene/contrib/misc/src/java/org/apache/lucene/index/FieldNormModifier.java =================================================================== --- lucene/contrib/misc/src/java/org/apache/lucene/index/FieldNormModifier.java (revision 1158028) +++ lucene/contrib/misc/src/java/org/apache/lucene/index/FieldNormModifier.java (working copy) @@ -35,7 +35,7 @@ * * If Similarity class is specified, uses its computeNorm method to set norms. * If -n command line argument is used, removed field norms, as if - * {@link org.apache.lucene.document.Field.Index}.NO_NORMS was used. + * {@link org.apache.lucene.document.FieldType#setOmitNorms(boolean)} was used. * *

* NOTE: This will overwrite any length normalization or field/document boosts. Index: lucene/contrib/demo/src/java/org/apache/lucene/demo/IndexFiles.java =================================================================== --- lucene/contrib/demo/src/java/org/apache/lucene/demo/IndexFiles.java (revision 1158028) +++ lucene/contrib/demo/src/java/org/apache/lucene/demo/IndexFiles.java (working copy) @@ -21,8 +21,11 @@ import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; import org.apache.lucene.document.NumericField; import org.apache.lucene.index.FieldInfo.IndexOptions; +import org.apache.lucene.document.StringField; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig.OpenMode; import org.apache.lucene.index.IndexWriterConfig; @@ -173,8 +176,9 @@ // field that is indexed (i.e. searchable), but don't tokenize // the field into separate words and don't index term frequency // or positional information: - Field pathField = new Field("path", file.getPath(), Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS); - pathField.setIndexOptions(IndexOptions.DOCS_ONLY); + FieldType ft = new FieldType(TextField.TYPE_STORED); + ft.setIndexOptions(IndexOptions.DOCS_ONLY); + Field pathField = new Field("path", StringField.TYPE_STORED, file.getPath()); doc.add(pathField); // Add the last modified date of the file a field named "modified". @@ -192,7 +196,7 @@ // so that the text of the file is tokenized and indexed, but not stored. // Note that FileReader expects the file to be in UTF-8 encoding. // If that's not the case searching for special characters will fail. - doc.add(new Field("contents", new BufferedReader(new InputStreamReader(fis, "UTF-8")))); + doc.add(new TextField("contents", new BufferedReader(new InputStreamReader(fis, "UTF-8")))); if (writer.getConfig().getOpenMode() == OpenMode.CREATE) { // New index, so we just add the document (no old document can be there): Index: lucene/contrib/memory/src/test/org/apache/lucene/index/memory/MemoryIndexTest.java =================================================================== --- lucene/contrib/memory/src/test/org/apache/lucene/index/memory/MemoryIndexTest.java (revision 1158028) +++ lucene/contrib/memory/src/test/org/apache/lucene/index/memory/MemoryIndexTest.java (working copy) @@ -31,6 +31,7 @@ import org.apache.lucene.analysis.MockTokenizer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.queryparser.classic.QueryParser; @@ -108,8 +109,8 @@ IndexWriter writer = new IndexWriter(ramdir, new IndexWriterConfig(TEST_VERSION_CURRENT, analyzer).setCodecProvider(_TestUtil.alwaysCodec("Standard"))); Document doc = new Document(); - Field field1 = newField("foo", fooField.toString(), Field.Store.NO, Field.Index.ANALYZED); - Field field2 = newField("term", termField.toString(), Field.Store.NO, Field.Index.ANALYZED); + Field field1 = newField("foo", fooField.toString(), TextField.TYPE_UNSTORED); + Field field2 = newField("term", termField.toString(), TextField.TYPE_UNSTORED); doc.add(field1); doc.add(field2); writer.addDocument(doc); Index: lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java =================================================================== --- lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java (revision 1158028) +++ lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java (working copy) @@ -35,23 +35,25 @@ import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute; import org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute; import org.apache.lucene.document.Document; -import org.apache.lucene.document.FieldSelector; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.DocsAndPositionsEnum; +import org.apache.lucene.index.DocsEnum; +import org.apache.lucene.index.FieldInvertState; import org.apache.lucene.index.Fields; +import org.apache.lucene.index.FieldsEnum; import org.apache.lucene.index.IndexReader.AtomicReaderContext; +import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.OrdTermState; -import org.apache.lucene.index.TermState; -import org.apache.lucene.index.Terms; -import org.apache.lucene.index.TermsEnum; -import org.apache.lucene.index.FieldsEnum; -import org.apache.lucene.index.DocsEnum; -import org.apache.lucene.index.DocsAndPositionsEnum; +import org.apache.lucene.index.StoredFieldVisitor; import org.apache.lucene.index.Term; import org.apache.lucene.index.TermFreqVector; import org.apache.lucene.index.TermPositionVector; +import org.apache.lucene.index.TermState; import org.apache.lucene.index.TermVectorMapper; import org.apache.lucene.index.FieldInvertState; import org.apache.lucene.index.codecs.PerDocValues; +import org.apache.lucene.index.Terms; +import org.apache.lucene.index.TermsEnum; import org.apache.lucene.search.Collector; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; @@ -60,8 +62,8 @@ import org.apache.lucene.search.SimilarityProvider; import org.apache.lucene.store.RAMDirectory; // for javadocs import org.apache.lucene.util.ArrayUtil; -import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.Bits; +import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.Constants; // for javadocs /** @@ -240,11 +242,8 @@ /** * Convenience method; Tokenizes the given field text and adds the resulting * terms to the index; Equivalent to adding an indexed non-keyword Lucene - * {@link org.apache.lucene.document.Field} that is - * {@link org.apache.lucene.document.Field.Index#ANALYZED tokenized}, - * {@link org.apache.lucene.document.Field.Store#NO not stored}, - * {@link org.apache.lucene.document.Field.TermVector#WITH_POSITIONS termVectorStored with positions} (or - * {@link org.apache.lucene.document.Field.TermVector#WITH_POSITIONS termVectorStored with positions and offsets}), + * {@link org.apache.lucene.document.Field} that is tokenized, not stored, + * termVectorStored with positions (or termVectorStored with positions and offsets), * * @param fieldName * a name to be associated with the text @@ -1237,19 +1236,12 @@ } @Override - public Document document(int n) { + public void document(int docID, StoredFieldVisitor visitor) { if (DEBUG) System.err.println("MemoryIndexReader.document"); - return new Document(); // there are no stored fields + // no-op: there are no stored fields } - - //When we convert to JDK 1.5 make this Set + @Override - public Document document(int n, FieldSelector fieldSelector) throws IOException { - if (DEBUG) System.err.println("MemoryIndexReader.document"); - return new Document(); // there are no stored fields - } - - @Override public boolean hasDeletions() { if (DEBUG) System.err.println("MemoryIndexReader.hasDeletions"); return false; Index: lucene/contrib/queries/src/test/org/apache/lucene/search/DuplicateFilterTest.java =================================================================== --- lucene/contrib/queries/src/test/org/apache/lucene/search/DuplicateFilterTest.java (revision 1158028) +++ lucene/contrib/queries/src/test/org/apache/lucene/search/DuplicateFilterTest.java (working copy) @@ -19,7 +19,11 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; +import org.apache.lucene.document.StringField; +import org.apache.lucene.document.TextField; +import org.apache.lucene.index.DocsEnum; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.MultiFields; import org.apache.lucene.index.*; import org.apache.lucene.store.Directory; import org.apache.lucene.util.BytesRef; @@ -71,9 +75,9 @@ private void addDoc(RandomIndexWriter writer, String url, String text, String date) throws IOException { Document doc = new Document(); - doc.add(newField(KEY_FIELD, url, Field.Store.YES, Field.Index.NOT_ANALYZED)); - doc.add(newField("text", text, Field.Store.YES, Field.Index.ANALYZED)); - doc.add(newField("date", date, Field.Store.YES, Field.Index.ANALYZED)); + doc.add(newField(KEY_FIELD, url, StringField.TYPE_STORED)); + doc.add(newField("text", text, TextField.TYPE_STORED)); + doc.add(newField("date", date, TextField.TYPE_STORED)); writer.addDocument(doc); } Index: lucene/contrib/queries/src/test/org/apache/lucene/search/TermsFilterTest.java =================================================================== --- lucene/contrib/queries/src/test/org/apache/lucene/search/TermsFilterTest.java (revision 1158028) +++ lucene/contrib/queries/src/test/org/apache/lucene/search/TermsFilterTest.java (working copy) @@ -17,8 +17,12 @@ * limitations under the License. */ +import java.util.HashSet; + import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.StringField; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.RandomIndexWriter; @@ -56,7 +60,7 @@ for (int i = 0; i < 100; i++) { Document doc = new Document(); int term = i * 10; //terms are units of 10; - doc.add(newField(fieldName, "" + term, Field.Store.YES, Field.Index.NOT_ANALYZED)); + doc.add(newField(fieldName, "" + term, StringField.TYPE_STORED)); w.addDocument(doc); } IndexReader reader = new SlowMultiReaderWrapper(w.getReader()); Index: lucene/contrib/queries/src/test/org/apache/lucene/search/ChainedFilterTest.java =================================================================== --- lucene/contrib/queries/src/test/org/apache/lucene/search/ChainedFilterTest.java (revision 1158028) +++ lucene/contrib/queries/src/test/org/apache/lucene/search/ChainedFilterTest.java (working copy) @@ -21,7 +21,8 @@ import java.util.GregorianCalendar; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; @@ -62,9 +63,12 @@ for (int i = 0; i < MAX; i++) { Document doc = new Document(); - doc.add(newField("key", "" + (i + 1), Field.Store.YES, Field.Index.NOT_ANALYZED)); - doc.add(newField("owner", (i < MAX / 2) ? "bob" : "sue", Field.Store.YES, Field.Index.NOT_ANALYZED)); - doc.add(newField("date", cal.getTime().toString(), Field.Store.YES, Field.Index.NOT_ANALYZED)); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + customType.setTokenized(false); + doc.add(newField("key", "" + (i + 1), customType)); + doc.add(newField("owner", (i < MAX / 2) ? "bob" : "sue", customType)); + doc.add(newField("date", cal.getTime().toString(), customType)); writer.addDocument(doc); cal.add(Calendar.DATE, 1); Index: lucene/contrib/queries/src/test/org/apache/lucene/search/BooleanFilterTest.java =================================================================== --- lucene/contrib/queries/src/test/org/apache/lucene/search/BooleanFilterTest.java (revision 1158028) +++ lucene/contrib/queries/src/test/org/apache/lucene/search/BooleanFilterTest.java (working copy) @@ -20,7 +20,8 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.analysis.MockTokenizer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.RandomIndexWriter; @@ -60,10 +61,10 @@ private void addDoc(RandomIndexWriter writer, String accessRights, String price, String date, String inStock) throws IOException { Document doc = new Document(); - doc.add(newField("accessRights", accessRights, Field.Store.YES, Field.Index.ANALYZED)); - doc.add(newField("price", price, Field.Store.YES, Field.Index.ANALYZED)); - doc.add(newField("date", date, Field.Store.YES, Field.Index.ANALYZED)); - doc.add(newField("inStock", inStock, Field.Store.YES, Field.Index.ANALYZED)); + doc.add(newField("accessRights", accessRights, TextField.TYPE_STORED)); + doc.add(newField("price", price, TextField.TYPE_STORED)); + doc.add(newField("date", date, TextField.TYPE_STORED)); + doc.add(newField("inStock", inStock, TextField.TYPE_STORED)); writer.addDocument(doc); } Index: lucene/contrib/queries/src/test/org/apache/lucene/search/FuzzyLikeThisQueryTest.java =================================================================== --- lucene/contrib/queries/src/test/org/apache/lucene/search/FuzzyLikeThisQueryTest.java (revision 1158028) +++ lucene/contrib/queries/src/test/org/apache/lucene/search/FuzzyLikeThisQueryTest.java (working copy) @@ -20,7 +20,8 @@ import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; @@ -64,8 +65,8 @@ private void addDoc(RandomIndexWriter writer, String name, String id) throws IOException { Document doc = new Document(); - doc.add(newField("name", name, Field.Store.YES, Field.Index.ANALYZED)); - doc.add(newField("id", id, Field.Store.YES, Field.Index.ANALYZED)); + doc.add(newField("name", name, TextField.TYPE_STORED)); + doc.add(newField("id", id, TextField.TYPE_STORED)); writer.addDocument(doc); } Index: lucene/contrib/queries/src/test/org/apache/lucene/search/regex/TestRegexQuery.java =================================================================== --- lucene/contrib/queries/src/test/org/apache/lucene/search/regex/TestRegexQuery.java (revision 1158028) +++ lucene/contrib/queries/src/test/org/apache/lucene/search/regex/TestRegexQuery.java (working copy) @@ -26,6 +26,7 @@ import org.apache.lucene.index.Terms; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.TextField; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.index.TermsEnum; @@ -47,7 +48,7 @@ directory = newDirectory(); RandomIndexWriter writer = new RandomIndexWriter(random, directory); Document doc = new Document(); - doc.add(newField(FN, "the quick brown fox jumps over the lazy dog", Field.Store.NO, Field.Index.ANALYZED)); + doc.add(newField(FN, "the quick brown fox jumps over the lazy dog", TextField.TYPE_UNSTORED)); writer.addDocument(doc); reader = writer.getReader(); writer.close(); Index: lucene/contrib/queries/src/test/org/apache/lucene/search/regex/TestSpanRegexQuery.java =================================================================== --- lucene/contrib/queries/src/test/org/apache/lucene/search/regex/TestSpanRegexQuery.java (revision 1158028) +++ lucene/contrib/queries/src/test/org/apache/lucene/search/regex/TestSpanRegexQuery.java (working copy) @@ -22,6 +22,8 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.Term; @@ -62,12 +64,10 @@ // Field.Store.NO, Field.Index.ANALYZED)); // writer.addDocument(doc); // doc = new Document(); - doc.add(newField("field", "auto update", Field.Store.NO, - Field.Index.ANALYZED)); + doc.add(newField("field", "auto update", TextField.TYPE_UNSTORED)); writer.addDocument(doc); doc = new Document(); - doc.add(newField("field", "first auto update", Field.Store.NO, - Field.Index.ANALYZED)); + doc.add(newField("field", "first auto update", TextField.TYPE_UNSTORED)); writer.addDocument(doc); writer.optimize(); writer.close(); @@ -87,13 +87,13 @@ LockObtainFailedException, IOException { // creating a document to store Document lDoc = new Document(); - lDoc.add(newField("field", "a1 b1", Field.Store.NO, - Field.Index.ANALYZED_NO_NORMS)); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setOmitNorms(true); + lDoc.add(newField("field", "a1 b1", customType)); // creating a document to store Document lDoc2 = new Document(); - lDoc2.add(newField("field", "a2 b2", Field.Store.NO, - Field.Index.ANALYZED_NO_NORMS)); + lDoc2.add(newField("field", "a2 b2", customType)); // creating first index writer IndexWriter writerA = new IndexWriter(indexStoreA, newIndexWriterConfig( Index: lucene/contrib/queries/src/test/org/apache/lucene/search/TestSlowCollationMethods.java =================================================================== --- lucene/contrib/queries/src/test/org/apache/lucene/search/TestSlowCollationMethods.java (revision 1158028) +++ lucene/contrib/queries/src/test/org/apache/lucene/search/TestSlowCollationMethods.java (working copy) @@ -6,6 +6,8 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.search.BooleanClause.Occur; @@ -56,7 +58,11 @@ for (int i = 0; i < numDocs; i++) { Document doc = new Document(); String value = _TestUtil.randomUnicodeString(random); - Field field = newField("field", value, Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + customType.setOmitNorms(true); + customType.setTokenized(false); + Field field = newField("field", value, customType); doc.add(field); iw.addDocument(doc); } Index: lucene/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestCartesian.java =================================================================== --- lucene/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestCartesian.java (revision 1158028) +++ lucene/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestCartesian.java (working copy) @@ -24,7 +24,9 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; import org.apache.lucene.document.NumericField; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; @@ -93,26 +95,30 @@ private void addPoint(IndexWriter writer, String name, double lat, double lng) throws IOException{ Document doc = new Document(); + + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + doc.add(newField("name", name, customType)); - doc.add(newField("name", name,Field.Store.YES, Field.Index.ANALYZED)); - // convert the lat / long to lucene fields - doc.add(new NumericField(latField, Integer.MAX_VALUE, Field.Store.YES, true).setDoubleValue(lat)); - doc.add(new NumericField(lngField, Integer.MAX_VALUE, Field.Store.YES, true).setDoubleValue(lng)); + FieldType customType2 = new FieldType(NumericField.TYPE_UNSTORED); + customType2.setStored(true); + doc.add(new NumericField(latField, Integer.MAX_VALUE, customType2).setDoubleValue(lat)); + doc.add(new NumericField(lngField, Integer.MAX_VALUE, customType2).setDoubleValue(lng)); // add a default meta field to make searching all documents easy - doc.add(newField("metafile", "doc",Field.Store.YES, Field.Index.ANALYZED)); + doc.add(newField("metafile", "doc", customType)); int ctpsize = ctps.size(); + FieldType customType3 = new FieldType(TextField.TYPE_UNSTORED); + customType3.setStored(true); + customType3.setTokenized(false); + customType3.setOmitNorms(true); for (int i =0; i < ctpsize; i++){ CartesianTierPlotter ctp = ctps.get(i); - doc.add(new NumericField(ctp.getTierFieldName(), Integer.MAX_VALUE, - Field.Store.YES, - true).setDoubleValue(ctp.getTierBoxId(lat,lng))); + doc.add(new NumericField(ctp.getTierFieldName(), Integer.MAX_VALUE, customType).setDoubleValue(ctp.getTierBoxId(lat,lng))); - doc.add(newField(geoHashPrefix, GeoHashUtils.encode(lat,lng), - Field.Store.YES, - Field.Index.NOT_ANALYZED_NO_NORMS)); + doc.add(newField(geoHashPrefix, GeoHashUtils.encode(lat,lng), customType3)); } writer.addDocument(doc); Index: lucene/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestDistance.java =================================================================== --- lucene/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestDistance.java (revision 1158028) +++ lucene/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestDistance.java (working copy) @@ -21,7 +21,9 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; import org.apache.lucene.document.NumericField; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.Term; @@ -62,15 +64,19 @@ private void addPoint(IndexWriter writer, String name, double lat, double lng) throws IOException{ Document doc = new Document(); + + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + doc.add(newField("name", name, customType)); - doc.add(newField("name", name,Field.Store.YES, Field.Index.ANALYZED)); - // convert the lat / long to lucene fields - doc.add(new NumericField(latField, Integer.MAX_VALUE, Field.Store.YES, true).setDoubleValue(lat)); - doc.add(new NumericField(lngField, Integer.MAX_VALUE,Field.Store.YES, true).setDoubleValue(lng)); + FieldType customType2 = new FieldType(NumericField.TYPE_UNSTORED); + customType.setStored(true); + doc.add(new NumericField(latField, Integer.MAX_VALUE, customType2).setDoubleValue(lat)); + doc.add(new NumericField(lngField, Integer.MAX_VALUE, customType2).setDoubleValue(lng)); // add a default meta field to make searching all documents easy - doc.add(newField("metafile", "doc",Field.Store.YES, Field.Index.ANALYZED)); + doc.add(newField("metafile", "doc", customType)); writer.addDocument(doc); } Index: lucene/contrib/xml-query-parser/src/test/org/apache/lucene/xmlparser/TestParser.java =================================================================== --- lucene/contrib/xml-query-parser/src/test/org/apache/lucene/xmlparser/TestParser.java (revision 1158028) +++ lucene/contrib/xml-query-parser/src/test/org/apache/lucene/xmlparser/TestParser.java (working copy) @@ -9,8 +9,10 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.analysis.MockTokenFilter; import org.apache.lucene.analysis.MockTokenizer; -import org.apache.lucene.document.Field; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.FieldType; import org.apache.lucene.document.NumericField; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.search.IndexSearcher; @@ -41,201 +43,202 @@ */ public class TestParser extends LuceneTestCase { - private static CoreParser builder; - private static Directory dir; - private static IndexReader reader; - private static IndexSearcher searcher; + private static CoreParser builder; + private static Directory dir; + private static IndexReader reader; + private static IndexSearcher searcher; - @BeforeClass - public static void beforeClass() throws Exception { - // TODO: rewrite test (this needs to set QueryParser.enablePositionIncrements, too, for work with CURRENT): - Analyzer analyzer=new MockAnalyzer(random, MockTokenizer.WHITESPACE, true, MockTokenFilter.ENGLISH_STOPSET, false); + @BeforeClass + public static void beforeClass() throws Exception { + // TODO: rewrite test (this needs to set QueryParser.enablePositionIncrements, too, for work with CURRENT): + Analyzer analyzer=new MockAnalyzer(random, MockTokenizer.WHITESPACE, true, MockTokenFilter.ENGLISH_STOPSET, false); //initialize the parser - builder=new CorePlusExtensionsParser("contents",analyzer); - - BufferedReader d = new BufferedReader(new InputStreamReader(TestParser.class.getResourceAsStream("reuters21578.txt"))); - dir=newDirectory(); - IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(Version.LUCENE_40, analyzer)); - String line = d.readLine(); - while(line!=null) - { - int endOfDate=line.indexOf('\t'); - String date=line.substring(0,endOfDate).trim(); - String content=line.substring(endOfDate).trim(); - org.apache.lucene.document.Document doc =new org.apache.lucene.document.Document(); - doc.add(newField("date",date,Field.Store.YES,Field.Index.ANALYZED)); - doc.add(newField("contents",content,Field.Store.YES,Field.Index.ANALYZED)); - NumericField numericField = new NumericField("date2"); - numericField.setIntValue(Integer.valueOf(date)); - doc.add(numericField); - writer.addDocument(doc); - line=d.readLine(); - } - d.close(); + builder=new CorePlusExtensionsParser("contents",analyzer); + + BufferedReader d = new BufferedReader(new InputStreamReader(TestParser.class.getResourceAsStream("reuters21578.txt"))); + dir=newDirectory(); + IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(Version.LUCENE_40, analyzer)); + String line = d.readLine(); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + while(line!=null) + { + int endOfDate=line.indexOf('\t'); + String date=line.substring(0,endOfDate).trim(); + String content=line.substring(endOfDate).trim(); + Document doc = new Document(); + doc.add(newField("date",date,customType)); + doc.add(newField("contents",content,customType)); + NumericField numericField = new NumericField("date2"); + numericField.setIntValue(Integer.valueOf(date)); + doc.add(numericField); + writer.addDocument(doc); + line=d.readLine(); + } + d.close(); writer.close(); - reader=IndexReader.open(dir, true); - searcher=newSearcher(reader); - - } - - - - - @AfterClass - public static void afterClass() throws Exception { - reader.close(); - searcher.close(); - dir.close(); - reader = null; - searcher = null; - dir = null; - builder = null; - } - - public void testSimpleXML() throws ParserException, IOException - { - Query q=parse("TermQuery.xml"); - dumpResults("TermQuery", q, 5); - } - public void testSimpleTermsQueryXML() throws ParserException, IOException - { - Query q=parse("TermsQuery.xml"); - dumpResults("TermsQuery", q, 5); - } - public void testBooleanQueryXML() throws ParserException, IOException - { - Query q=parse("BooleanQuery.xml"); - dumpResults("BooleanQuery", q, 5); - } - public void testRangeFilterQueryXML() throws ParserException, IOException - { - Query q=parse("RangeFilterQuery.xml"); - dumpResults("RangeFilter", q, 5); - } - public void testUserQueryXML() throws ParserException, IOException - { - Query q=parse("UserInputQuery.xml"); - dumpResults("UserInput with Filter", q, 5); - } - - public void testCustomFieldUserQueryXML() throws ParserException, IOException - { - Query q=parse("UserInputQueryCustomField.xml"); - assertEquals(20.0f, q.getBoost()); - int h = searcher.search(q, null, 1000).totalHits; - assertEquals("UserInputQueryCustomField should produce 0 result ", 0,h); - } - - public void testLikeThisQueryXML() throws Exception - { - Query q=parse("LikeThisQuery.xml"); - dumpResults("like this", q, 5); - } - public void testBoostingQueryXML() throws Exception - { - Query q=parse("BoostingQuery.xml"); - dumpResults("boosting ",q, 5); - } - public void testFuzzyLikeThisQueryXML() throws Exception - { - Query q=parse("FuzzyLikeThisQuery.xml"); - //show rewritten fuzzyLikeThisQuery - see what is being matched on - if(VERBOSE) - { - System.out.println(q.rewrite(reader)); - } - dumpResults("FuzzyLikeThis", q, 5); - } - public void testTermsFilterXML() throws Exception - { - Query q=parse("TermsFilterQuery.xml"); - dumpResults("Terms Filter",q, 5); - } + reader=IndexReader.open(dir, true); + searcher=newSearcher(reader); + + } + + + + + @AfterClass + public static void afterClass() throws Exception { + reader.close(); + searcher.close(); + dir.close(); + reader = null; + searcher = null; + dir = null; + builder = null; + } + + public void testSimpleXML() throws ParserException, IOException + { + Query q=parse("TermQuery.xml"); + dumpResults("TermQuery", q, 5); + } + public void testSimpleTermsQueryXML() throws ParserException, IOException + { + Query q=parse("TermsQuery.xml"); + dumpResults("TermsQuery", q, 5); + } + public void testBooleanQueryXML() throws ParserException, IOException + { + Query q=parse("BooleanQuery.xml"); + dumpResults("BooleanQuery", q, 5); + } + public void testRangeFilterQueryXML() throws ParserException, IOException + { + Query q=parse("RangeFilterQuery.xml"); + dumpResults("RangeFilter", q, 5); + } + public void testUserQueryXML() throws ParserException, IOException + { + Query q=parse("UserInputQuery.xml"); + dumpResults("UserInput with Filter", q, 5); + } + + public void testCustomFieldUserQueryXML() throws ParserException, IOException + { + Query q=parse("UserInputQueryCustomField.xml"); + int h = searcher.search(q, null, 1000).totalHits; + assertEquals("UserInputQueryCustomField should produce 0 result ", 0,h); + } + + public void testLikeThisQueryXML() throws Exception + { + Query q=parse("LikeThisQuery.xml"); + dumpResults("like this", q, 5); + } + public void testBoostingQueryXML() throws Exception + { + Query q=parse("BoostingQuery.xml"); + dumpResults("boosting ",q, 5); + } + public void testFuzzyLikeThisQueryXML() throws Exception + { + Query q=parse("FuzzyLikeThisQuery.xml"); + //show rewritten fuzzyLikeThisQuery - see what is being matched on + if(VERBOSE) + { + System.out.println(q.rewrite(reader)); + } + dumpResults("FuzzyLikeThis", q, 5); + } + public void testTermsFilterXML() throws Exception + { + Query q=parse("TermsFilterQuery.xml"); + dumpResults("Terms Filter",q, 5); + } public void testBoostingTermQueryXML() throws Exception - { - Query q=parse("BoostingTermQuery.xml"); - dumpResults("BoostingTermQuery",q, 5); - } + { + Query q=parse("BoostingTermQuery.xml"); + dumpResults("BoostingTermQuery",q, 5); + } public void testSpanTermXML() throws Exception - { - Query q=parse("SpanQuery.xml"); - dumpResults("Span Query",q, 5); - } - public void testConstantScoreQueryXML() throws Exception - { - Query q=parse("ConstantScoreQuery.xml"); - dumpResults("ConstantScoreQuery",q, 5); - } - public void testMatchAllDocsPlusFilterXML() throws ParserException, IOException - { - Query q=parse("MatchAllDocsQuery.xml"); - dumpResults("MatchAllDocsQuery with range filter", q, 5); - } - public void testBooleanFilterXML() throws ParserException, IOException - { - Query q=parse("BooleanFilter.xml"); - dumpResults("Boolean filter", q, 5); - } - public void testNestedBooleanQuery() throws ParserException, IOException - { - Query q=parse("NestedBooleanQuery.xml"); - dumpResults("Nested Boolean query", q, 5); - } - public void testCachedFilterXML() throws ParserException, IOException - { - Query q=parse("CachedFilter.xml"); - dumpResults("Cached filter", q, 5); - } - public void testDuplicateFilterQueryXML() throws ParserException, IOException - { + { + Query q=parse("SpanQuery.xml"); + dumpResults("Span Query",q, 5); + } + public void testConstantScoreQueryXML() throws Exception + { + Query q=parse("ConstantScoreQuery.xml"); + dumpResults("ConstantScoreQuery",q, 5); + } + public void testMatchAllDocsPlusFilterXML() throws ParserException, IOException + { + Query q=parse("MatchAllDocsQuery.xml"); + dumpResults("MatchAllDocsQuery with range filter", q, 5); + } + public void testBooleanFilterXML() throws ParserException, IOException + { + Query q=parse("BooleanFilter.xml"); + dumpResults("Boolean filter", q, 5); + } + public void testNestedBooleanQuery() throws ParserException, IOException + { + Query q=parse("NestedBooleanQuery.xml"); + dumpResults("Nested Boolean query", q, 5); + } + public void testCachedFilterXML() throws ParserException, IOException + { + Query q=parse("CachedFilter.xml"); + dumpResults("Cached filter", q, 5); + } + public void testDuplicateFilterQueryXML() throws ParserException, IOException + { Assume.assumeTrue(searcher.getIndexReader().getSequentialSubReaders() == null || searcher.getIndexReader().getSequentialSubReaders().length == 1); - Query q=parse("DuplicateFilterQuery.xml"); - int h = searcher.search(q, null, 1000).totalHits; - assertEquals("DuplicateFilterQuery should produce 1 result ", 1,h); - } - - public void testNumericRangeFilterQueryXML() throws ParserException, IOException - { - Query q=parse("NumericRangeFilterQuery.xml"); - dumpResults("NumericRangeFilter", q, 5); - } - - public void testNumericRangeQueryQueryXML() throws ParserException, IOException - { - Query q=parse("NumericRangeQueryQuery.xml"); - dumpResults("NumericRangeQuery", q, 5); - } - + Query q=parse("DuplicateFilterQuery.xml"); + int h = searcher.search(q, null, 1000).totalHits; + assertEquals("DuplicateFilterQuery should produce 1 result ", 1,h); + } + + public void testNumericRangeFilterQueryXML() throws ParserException, IOException + { + Query q=parse("NumericRangeFilterQuery.xml"); + dumpResults("NumericRangeFilter", q, 5); + } + + public void testNumericRangeQueryQueryXML() throws ParserException, IOException + { + Query q=parse("NumericRangeQueryQuery.xml"); + dumpResults("NumericRangeQuery", q, 5); + } + - //================= Helper methods =================================== - private Query parse(String xmlFileName) throws ParserException, IOException - { - InputStream xmlStream=TestParser.class.getResourceAsStream(xmlFileName); - Query result=builder.parse(xmlStream); - xmlStream.close(); - return result; - } - private void dumpResults(String qType,Query q, int numDocs) throws IOException - { + //================= Helper methods =================================== + private Query parse(String xmlFileName) throws ParserException, IOException + { + InputStream xmlStream=TestParser.class.getResourceAsStream(xmlFileName); + Query result=builder.parse(xmlStream); + xmlStream.close(); + return result; + } + private void dumpResults(String qType,Query q, int numDocs) throws IOException + { if (VERBOSE) { System.out.println("TEST: query=" + q); } TopDocs hits = searcher.search(q, null, numDocs); - assertTrue(qType +" should produce results ", hits.totalHits>0); - if(VERBOSE) - { - System.out.println("========="+qType+"============"); - ScoreDoc[] scoreDocs = hits.scoreDocs; - for(int i=0;i0); + if(VERBOSE) + { + System.out.println("========="+qType+"============"); + ScoreDoc[] scoreDocs = hits.scoreDocs; + for(int i=0;idefghijkl", sfb.createFragment( reader, 0, F, ffl ) ); + assertEquals( "abc/defg/hijkl/", sfb.createFragment( reader, 0, F, ffl ) ); } public void testMVSeparator() throws Exception { Index: lucene/contrib/highlighter/src/java/org/apache/lucene/search/highlight/TokenSources.java =================================================================== --- lucene/contrib/highlighter/src/java/org/apache/lucene/search/highlight/TokenSources.java (revision 1158028) +++ lucene/contrib/highlighter/src/java/org/apache/lucene/search/highlight/TokenSources.java (working copy) @@ -60,10 +60,11 @@ * @param analyzer The analyzer to use for creating the TokenStream if the * vector doesn't exist * @return The {@link org.apache.lucene.analysis.TokenStream} for the - * {@link org.apache.lucene.document.Fieldable} on the + * {@link org.apache.lucene.index.IndexableField} on the * {@link org.apache.lucene.document.Document} * @throws IOException if there was an error loading */ + public static TokenStream getAnyTokenStream(IndexReader reader, int docId, String field, Document doc, Analyzer analyzer) throws IOException { TokenStream ts = null; Index: lucene/contrib/highlighter/src/java/org/apache/lucene/search/vectorhighlight/FieldTermStack.java =================================================================== --- lucene/contrib/highlighter/src/java/org/apache/lucene/search/vectorhighlight/FieldTermStack.java (revision 1158028) +++ lucene/contrib/highlighter/src/java/org/apache/lucene/search/vectorhighlight/FieldTermStack.java (working copy) @@ -21,6 +21,7 @@ import java.util.LinkedList; import java.util.Set; +import org.apache.lucene.document.FieldType; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.TermFreqVector; import org.apache.lucene.index.TermPositionVector; @@ -46,8 +47,12 @@ // Directory dir = new RAMDirectory(); // IndexWriter writer = new IndexWriter(dir, new IndexWriterConfig(Version.LUCENE_CURRENT, analyzer)); // Document doc = new Document(); - // doc.add( new Field( "f", "a a a b b c a b b c d e f", Store.YES, Index.ANALYZED, TermVector.WITH_POSITIONS_OFFSETS ) ); - // doc.add( new Field( "f", "b a b a f", Store.YES, Index.ANALYZED, TermVector.WITH_POSITIONS_OFFSETS ) ); + // FieldType ft = new FieldType(TextField.TYPE_STORED); + // ft.setStoreTermVectors(true); + // ft.setStoreTermVectorOffsets(true); + // ft.setStoreTermVectorPositions(true); + // doc.add( new Field( "f", ft, "a a a b b c a b b c d e f" ) ); + // doc.add( new Field( "f", ft, "b a b a f" ) ); // writer.addDocument( doc ); // writer.close(); @@ -67,7 +72,7 @@ */ public FieldTermStack( IndexReader reader, int docId, String fieldName, final FieldQuery fieldQuery ) throws IOException { this.fieldName = fieldName; - + TermFreqVector tfv = reader.getTermFreqVector( docId, fieldName ); if( tfv == null ) return; // just return to make null snippets TermPositionVector tpv = null; Index: lucene/contrib/highlighter/src/java/org/apache/lucene/search/vectorhighlight/BaseFragmentsBuilder.java =================================================================== --- lucene/contrib/highlighter/src/java/org/apache/lucene/search/vectorhighlight/BaseFragmentsBuilder.java (revision 1158028) +++ lucene/contrib/highlighter/src/java/org/apache/lucene/search/vectorhighlight/BaseFragmentsBuilder.java (working copy) @@ -21,15 +21,18 @@ import java.util.ArrayList; import java.util.List; -import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; -import org.apache.lucene.document.MapFieldSelector; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; +import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.StoredFieldVisitor; import org.apache.lucene.search.highlight.DefaultEncoder; import org.apache.lucene.search.highlight.Encoder; +import org.apache.lucene.search.vectorhighlight.FieldFragList.WeightedFragInfo.SubInfo; import org.apache.lucene.search.vectorhighlight.FieldFragList.WeightedFragInfo; -import org.apache.lucene.search.vectorhighlight.FieldFragList.WeightedFragInfo.SubInfo; import org.apache.lucene.search.vectorhighlight.FieldPhraseList.WeightedPhraseInfo.Toffs; +import org.apache.lucene.store.IndexInput; public abstract class BaseFragmentsBuilder implements FragmentsBuilder { @@ -107,10 +110,27 @@ return fragments.toArray( new String[fragments.size()] ); } - protected Field[] getFields( IndexReader reader, int docId, String fieldName) throws IOException { + protected Field[] getFields( IndexReader reader, int docId, final String fieldName) throws IOException { // according to javadoc, doc.getFields(fieldName) cannot be used with lazy loaded field??? - Document doc = reader.document( docId, new MapFieldSelector(fieldName) ); - return doc.getFields( fieldName ); // according to Document class javadoc, this never returns null + final List fields = new ArrayList(); + reader.document(docId, new StoredFieldVisitor() { + @Override + public boolean stringField(FieldInfo fieldInfo, IndexInput in, int numUTF8Bytes) throws IOException { + if (fieldInfo.name.equals(fieldName)) { + final byte[] b = new byte[numUTF8Bytes]; + in.readBytes(b, 0, b.length); + FieldType ft = new FieldType(TextField.TYPE_STORED); + ft.setStoreTermVectors(fieldInfo.storeTermVector); + ft.setStoreTermVectorOffsets(fieldInfo.storeOffsetWithTermVector); + ft.setStoreTermVectorPositions(fieldInfo.storePositionWithTermVector); + fields.add(new Field(fieldInfo.name, ft, new String(b, "UTF-8"))); + } else { + in.seek(in.getFilePointer() + numUTF8Bytes); + } + return false; + } + }); + return fields.toArray(new Field[fields.size()]); } protected String makeFragment( StringBuilder buffer, int[] index, Field[] values, WeightedFragInfo fragInfo, @@ -142,8 +162,7 @@ int startOffset, int endOffset ){ while( buffer.length() < endOffset && index[0] < values.length ){ buffer.append( values[index[0]].stringValue() ); - if( values[index[0]].isTokenized() ) - buffer.append( multiValuedSeparator ); + buffer.append( multiValuedSeparator ); index[0]++; } int eo = buffer.length() < endOffset ? buffer.length() : endOffset; Index: lucene/contrib/highlighter/src/java/org/apache/lucene/search/vectorhighlight/package.html =================================================================== --- lucene/contrib/highlighter/src/java/org/apache/lucene/search/vectorhighlight/package.html (revision 1158028) +++ lucene/contrib/highlighter/src/java/org/apache/lucene/search/vectorhighlight/package.html (working copy) @@ -25,7 +25,7 @@

  • support N-gram fields
  • support phrase-unit highlighting with slops
  • need Java 1.5
  • -
  • highlight fields need to be TermVector.WITH_POSITIONS_OFFSETS
  • +
  • highlight fields need to be stored with Positions and Offsets
  • take into account query boost to score fragments
  • support colored highlight tags
  • pluggable FragListBuilder
  • @@ -95,7 +95,7 @@

    Step 2.

    In Step 2, Fast Vector Highlighter generates {@link org.apache.lucene.search.vectorhighlight.FieldTermStack}. Fast Vector Highlighter uses {@link org.apache.lucene.index.TermFreqVector} data -(must be stored {@link org.apache.lucene.document.Field.TermVector#WITH_POSITIONS_OFFSETS}) +(must be stored {@link org.apache.lucene.document.FieldType#setStoreTermVectorOffsets(boolean)} and {@link org.apache.lucene.document.FieldType#setStoreTermVectorPositions(boolean)}) to generate it. FieldTermStack keeps the terms in the user query. Therefore, in this sample case, Fast Vector Highlighter generates the following FieldTermStack:

    Index: lucene/src/test/org/apache/lucene/search/TestSort.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestSort.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestSort.java	(working copy)
    @@ -28,11 +28,15 @@
     import org.apache.lucene.document.IndexDocValuesField;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.FieldType;
    +import org.apache.lucene.document.StringField;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.CorruptIndexException;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.IndexReader.AtomicReaderContext;
     import org.apache.lucene.index.IndexWriter;
     import org.apache.lucene.index.IndexWriterConfig;
    +import org.apache.lucene.index.IndexableField;
     import org.apache.lucene.index.MultiReader;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.index.Term;
    @@ -121,37 +125,48 @@
         dirs.add(indexStore);
         RandomIndexWriter writer = new RandomIndexWriter(random, indexStore, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMergePolicy(newLogMergePolicy()));
     
    +    FieldType ft1 = new FieldType();
    +    ft1.setStored(true);
    +    FieldType ft2 = new FieldType();
    +    ft2.setIndexed(true);
         for (int i=0; i= 0)) { // ensure first field is in order
                 fail = true;
                 System.out.println("fail:" + v[j] + " < " + last);
               }
               if (cmp == 0) { // ensure second field is in reverse order
    -            cmp = v2[j].compareTo(lastSub);
    +            cmp = v2[j].stringValue().compareTo(lastSub);
                 if (cmp > 0) {
                   fail = true;
                   System.out.println("rev field fail:" + v2[j] + " > " + lastSub);
    @@ -409,8 +427,8 @@
                 }
               }
             }
    -        last = v[j];
    -        lastSub = v2[j];
    +        last = v[j].stringValue();
    +        lastSub = v2[j].stringValue();
             lastDocId = result[x].doc;
             buff.append(v[j] + "(" + v2[j] + ")(" + result[x].doc+") ");
           }
    @@ -1051,9 +1069,9 @@
         int n = result.length;
         for (int i=0; i lastScore);
           lastScore = scores[i];
         }
    Index: lucene/src/test/org/apache/lucene/search/TestFuzzyQuery2.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestFuzzyQuery2.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestFuzzyQuery2.java	(working copy)
    @@ -25,6 +25,7 @@
     import org.apache.lucene.analysis.MockTokenizer;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.index.Term;
    @@ -85,7 +86,7 @@
         RandomIndexWriter writer = new RandomIndexWriter(random, dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random, MockTokenizer.KEYWORD, false)).setMergePolicy(newLogMergePolicy()));
         
         Document doc = new Document();
    -    Field field = newField("field", "", Field.Store.NO, Field.Index.ANALYZED);
    +    Field field = newField("field", "", TextField.TYPE_UNSTORED);
         doc.add(field);
         
         for (int i = 0; i < terms; i++) {
    Index: lucene/src/test/org/apache/lucene/search/TestNot.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestNot.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestNot.java	(working copy)
    @@ -25,7 +25,7 @@
     import org.apache.lucene.store.Directory;
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
    -import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.TextField;
     
     /** Similarity unit test.
      *
    @@ -38,7 +38,7 @@
         RandomIndexWriter writer = new RandomIndexWriter(random, store);
     
         Document d1 = new Document();
    -    d1.add(newField("field", "a b", Field.Store.YES, Field.Index.ANALYZED));
    +    d1.add(newField("field", "a b", TextField.TYPE_STORED));
     
         writer.addDocument(d1);
         IndexReader reader = writer.getReader();
    Index: lucene/src/test/org/apache/lucene/search/TestTimeLimitingCollector.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestTimeLimitingCollector.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestTimeLimitingCollector.java	(working copy)
    @@ -22,7 +22,7 @@
     
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
    -import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.IndexReader.AtomicReaderContext;
     import org.apache.lucene.index.RandomIndexWriter;
    @@ -111,7 +111,7 @@
     
       private void add(String value, RandomIndexWriter iw) throws IOException {
         Document d = new Document();
    -    d.add(newField(FIELD_NAME, value, Field.Store.NO, Field.Index.ANALYZED));
    +    d.add(newField(FIELD_NAME, value, TextField.TYPE_UNSTORED));
         iw.addDocument(d);
       }
     
    Index: lucene/src/test/org/apache/lucene/search/TestCachingWrapperFilter.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestCachingWrapperFilter.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestCachingWrapperFilter.java	(working copy)
    @@ -22,6 +22,8 @@
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.FieldType;
    +import org.apache.lucene.document.StringField;
     import org.apache.lucene.index.IndexReader.AtomicReaderContext;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
    @@ -175,7 +177,10 @@
     
         // add a doc, refresh the reader, and check that its there
         Document doc = new Document();
    -    doc.add(newField("id", "1", Field.Store.YES, Field.Index.NOT_ANALYZED));
    +    FieldType customType = new FieldType(StringField.TYPE_UNSTORED);
    +    customType.setStored(true);
    +    customType.setTokenized(false);
    +    doc.add(newField("id", "1", customType));
         writer.addDocument(doc);
     
         reader = refreshReader(reader);
    Index: lucene/src/test/org/apache/lucene/search/TestPrefixFilter.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestPrefixFilter.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestPrefixFilter.java	(working copy)
    @@ -23,7 +23,7 @@
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.index.Term;
     import org.apache.lucene.document.Document;
    -import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.StringField;
     
     /**
      * Tests {@link PrefixFilter} class.
    @@ -40,7 +40,7 @@
         RandomIndexWriter writer = new RandomIndexWriter(random, directory);
         for (int i = 0; i < categories.length; i++) {
           Document doc = new Document();
    -      doc.add(newField("category", categories[i], Field.Store.YES, Field.Index.NOT_ANALYZED));
    +      doc.add(newField("category", categories[i], StringField.TYPE_STORED));
           writer.addDocument(doc);
         }
         IndexReader reader = writer.getReader();
    Index: lucene/src/test/org/apache/lucene/search/TestAutomatonQueryUnicode.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestAutomatonQueryUnicode.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestAutomatonQueryUnicode.java	(working copy)
    @@ -21,6 +21,7 @@
     
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.index.Term;
    @@ -47,12 +48,9 @@
         directory = newDirectory();
         RandomIndexWriter writer = new RandomIndexWriter(random, directory);
         Document doc = new Document();
    -    Field titleField = newField("title", "some title", Field.Store.NO,
    -        Field.Index.ANALYZED);
    -    Field field = newField(FN, "", Field.Store.NO,
    -        Field.Index.ANALYZED);
    -    Field footerField = newField("footer", "a footer", Field.Store.NO,
    -        Field.Index.ANALYZED);
    +    Field titleField = newField("title", "some title", TextField.TYPE_UNSTORED);
    +    Field field = newField(FN, "", TextField.TYPE_UNSTORED);
    +    Field footerField = newField("footer", "a footer", TextField.TYPE_UNSTORED);
         doc.add(titleField);
         doc.add(field);
         doc.add(footerField);
    Index: lucene/src/test/org/apache/lucene/search/TestBooleanQuery.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestBooleanQuery.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestBooleanQuery.java	(working copy)
    @@ -24,6 +24,7 @@
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.MultiReader;
     import org.apache.lucene.index.RandomIndexWriter;
    @@ -68,7 +69,7 @@
         Directory dir = newDirectory();
         RandomIndexWriter w = new RandomIndexWriter(random, dir);
         Document doc = new Document();
    -    doc.add(newField("field", "a b c d", Field.Store.NO, Field.Index.ANALYZED));
    +    doc.add(newField("field", "a b c d", TextField.TYPE_UNSTORED));
         w.addDocument(doc);
     
         IndexReader r = w.getReader();
    @@ -129,7 +130,7 @@
         Directory dir1 = newDirectory();
         RandomIndexWriter iw1 = new RandomIndexWriter(random, dir1);
         Document doc1 = new Document();
    -    doc1.add(newField("field", "foo bar", Field.Index.ANALYZED));
    +    doc1.add(newField("field", "foo bar", TextField.TYPE_UNSTORED));
         iw1.addDocument(doc1);
         IndexReader reader1 = iw1.getReader();
         iw1.close();
    @@ -137,7 +138,7 @@
         Directory dir2 = newDirectory();
         RandomIndexWriter iw2 = new RandomIndexWriter(random, dir2);
         Document doc2 = new Document();
    -    doc2.add(newField("field", "foo baz", Field.Index.ANALYZED));
    +    doc2.add(newField("field", "foo baz", TextField.TYPE_UNSTORED));
         iw2.addDocument(doc2);
         IndexReader reader2 = iw2.getReader();
         iw2.close();
    Index: lucene/src/test/org/apache/lucene/search/TestPhraseQuery.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestPhraseQuery.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestPhraseQuery.java	(working copy)
    @@ -68,19 +68,19 @@
         RandomIndexWriter writer = new RandomIndexWriter(random, directory, analyzer);
         
         Document doc = new Document();
    -    doc.add(newField("field", "one two three four five", Field.Store.YES, Field.Index.ANALYZED));
    -    doc.add(newField("repeated", "this is a repeated field - first part", Field.Store.YES, Field.Index.ANALYZED));
    -    Fieldable repeatedField = newField("repeated", "second part of a repeated field", Field.Store.YES, Field.Index.ANALYZED);
    +    doc.add(newField("field", "one two three four five", TextField.TYPE_STORED));
    +    doc.add(newField("repeated", "this is a repeated field - first part", TextField.TYPE_STORED));
    +    IndexableField repeatedField = newField("repeated", "second part of a repeated field", TextField.TYPE_STORED);
         doc.add(repeatedField);
    -    doc.add(newField("palindrome", "one two three two one", Field.Store.YES, Field.Index.ANALYZED));
    +    doc.add(newField("palindrome", "one two three two one", TextField.TYPE_STORED));
         writer.addDocument(doc);
         
         doc = new Document();
    -    doc.add(newField("nonexist", "phrase exist notexist exist found", Field.Store.YES, Field.Index.ANALYZED));
    +    doc.add(newField("nonexist", "phrase exist notexist exist found", TextField.TYPE_STORED));
         writer.addDocument(doc);
         
         doc = new Document();
    -    doc.add(newField("nonexist", "phrase exist notexist exist found", Field.Store.YES, Field.Index.ANALYZED));
    +    doc.add(newField("nonexist", "phrase exist notexist exist found", TextField.TYPE_STORED));
         writer.addDocument(doc);
     
         reader = writer.getReader();
    @@ -223,7 +223,7 @@
         RandomIndexWriter writer = new RandomIndexWriter(random, directory, 
             newIndexWriterConfig( Version.LUCENE_40, stopAnalyzer));
         Document doc = new Document();
    -    doc.add(newField("field", "the stop words are here", Field.Store.YES, Field.Index.ANALYZED));
    +    doc.add(newField("field", "the stop words are here", TextField.TYPE_STORED));
         writer.addDocument(doc);
         IndexReader reader = writer.getReader();
         writer.close();
    @@ -258,12 +258,12 @@
         RandomIndexWriter writer = new RandomIndexWriter(random, directory);
         
         Document doc = new Document();
    -    doc.add(newField("source", "marketing info", Field.Store.YES, Field.Index.ANALYZED));
    +    doc.add(newField("source", "marketing info", TextField.TYPE_STORED));
         writer.addDocument(doc);
         
         doc = new Document();
    -    doc.add(newField("contents", "foobar", Field.Store.YES, Field.Index.ANALYZED));
    -    doc.add(newField("source", "marketing info", Field.Store.YES, Field.Index.ANALYZED)); 
    +    doc.add(newField("contents", "foobar", TextField.TYPE_STORED));
    +    doc.add(newField("source", "marketing info", TextField.TYPE_STORED)); 
         writer.addDocument(doc);
         
         IndexReader reader = writer.getReader();
    @@ -294,15 +294,15 @@
         writer = new RandomIndexWriter(random, directory, 
             newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random)).setOpenMode(OpenMode.CREATE));
         doc = new Document();
    -    doc.add(newField("contents", "map entry woo", Field.Store.YES, Field.Index.ANALYZED));
    +    doc.add(newField("contents", "map entry woo", TextField.TYPE_STORED));
         writer.addDocument(doc);
     
         doc = new Document();
    -    doc.add(newField("contents", "woo map entry", Field.Store.YES, Field.Index.ANALYZED));
    +    doc.add(newField("contents", "woo map entry", TextField.TYPE_STORED));
         writer.addDocument(doc);
     
         doc = new Document();
    -    doc.add(newField("contents", "map foobarword entry woo", Field.Store.YES, Field.Index.ANALYZED));
    +    doc.add(newField("contents", "map foobarword entry woo", TextField.TYPE_STORED));
         writer.addDocument(doc);
     
         reader = writer.getReader();
    @@ -345,15 +345,15 @@
         RandomIndexWriter writer = new RandomIndexWriter(random, directory, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMergePolicy(newLogMergePolicy()));
     
         Document doc = new Document();
    -    doc.add(newField("field", "foo firstname lastname foo", Field.Store.YES, Field.Index.ANALYZED));
    +    doc.add(newField("field", "foo firstname lastname foo", TextField.TYPE_STORED));
         writer.addDocument(doc);
         
         Document doc2 = new Document();
    -    doc2.add(newField("field", "foo firstname zzz lastname foo", Field.Store.YES, Field.Index.ANALYZED));
    +    doc2.add(newField("field", "foo firstname zzz lastname foo", TextField.TYPE_STORED));
         writer.addDocument(doc2);
         
         Document doc3 = new Document();
    -    doc3.add(newField("field", "foo firstname zzz yyy lastname foo", Field.Store.YES, Field.Index.ANALYZED));
    +    doc3.add(newField("field", "foo firstname zzz yyy lastname foo", TextField.TYPE_STORED));
         writer.addDocument(doc3);
         
         IndexReader reader = writer.getReader();
    @@ -608,7 +608,7 @@
         RandomIndexWriter w  = new RandomIndexWriter(random, dir, newIndexWriterConfig(TEST_VERSION_CURRENT, analyzer).setMergePolicy(newLogMergePolicy()));
         List> docs = new ArrayList>();
         Document d = new Document();
    -    Field f = newField("f", "", Field.Store.NO, Field.Index.ANALYZED);
    +    Field f = newField("f", "", TextField.TYPE_UNSTORED);
         d.add(f);
     
         Random r = random;
    Index: lucene/src/test/org/apache/lucene/search/TestPositionIncrement.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestPositionIncrement.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestPositionIncrement.java	(working copy)
    @@ -30,7 +30,7 @@
     import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
     import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
     import org.apache.lucene.document.Document;
    -import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.MultiFields;
     import org.apache.lucene.index.DocsAndPositionsEnum;
     import org.apache.lucene.index.IndexReader;
    @@ -88,7 +88,7 @@
         Directory store = newDirectory();
         RandomIndexWriter writer = new RandomIndexWriter(random, store, analyzer);
         Document d = new Document();
    -    d.add(newField("field", "bogus", Field.Store.YES, Field.Index.ANALYZED));
    +    d.add(newField("field", "bogus", TextField.TYPE_STORED));
         writer.addDocument(d);
         IndexReader reader = writer.getReader();
         writer.close();
    @@ -206,7 +206,7 @@
         Directory dir = newDirectory();
         RandomIndexWriter writer = new RandomIndexWriter(random, dir, new MockPayloadAnalyzer());
         Document doc = new Document();
    -    doc.add(new Field("content", new StringReader(
    +    doc.add(new TextField("content", new StringReader(
             "a a b c d e a f g h i j a b k k")));
         writer.addDocument(doc);
     
    Index: lucene/src/test/org/apache/lucene/search/TestTermRangeQuery.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestTermRangeQuery.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestTermRangeQuery.java	(working copy)
    @@ -27,6 +27,8 @@
     import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.StringField;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexWriter;
     import org.apache.lucene.index.MultiFields;
     import org.apache.lucene.index.Terms;
    @@ -265,8 +267,8 @@
       private void insertDoc(IndexWriter writer, String content) throws IOException {
         Document doc = new Document();
     
    -    doc.add(newField("id", "id" + docCount, Field.Store.YES, Field.Index.NOT_ANALYZED));
    -    doc.add(newField("content", content, Field.Store.NO, Field.Index.ANALYZED));
    +    doc.add(newField("id", "id" + docCount, StringField.TYPE_STORED));
    +    doc.add(newField("content", content, TextField.TYPE_UNSTORED));
     
         writer.addDocument(doc);
         docCount++;
    Index: lucene/src/test/org/apache/lucene/search/TestSearchWithThreads.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestSearchWithThreads.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestSearchWithThreads.java	(working copy)
    @@ -22,6 +22,7 @@
     
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.index.Term;
    @@ -44,7 +45,7 @@
         // TODO: replace w/ the @nightly test data; make this
         // into an optional @nightly stress test
         final Document doc = new Document();
    -    final Field body = newField("body", "", Field.Index.ANALYZED);
    +    final Field body = newField("body", "", TextField.TYPE_UNSTORED);
         doc.add(body);
         final StringBuilder sb = new StringBuilder();
         for(int docCount=0;docCount 1) {
               tester.values[i] = 10 + random.nextInt( 20 ); // get some field overlap
    -          doc.add(newField(tester.field, String.valueOf(tester.values[i]), 
    -              Field.Store.NO, Field.Index.NOT_ANALYZED ));
    +          FieldType customType = new FieldType(TextField.TYPE_UNSTORED);
    +          customType.setTokenized(false);
    +          doc.add(newField(tester.field, String.valueOf(tester.values[i]), customType));
             }
           }
           writer.addDocument(doc);
    Index: lucene/src/test/org/apache/lucene/search/TestDateSort.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestDateSort.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestDateSort.java	(working copy)
    @@ -26,6 +26,8 @@
     import org.apache.lucene.document.DateTools;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.StringField;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.search.Query;
    @@ -107,13 +109,12 @@
         Document document = new Document();
     
         // Add the text field.
    -    Field textField = newField(TEXT_FIELD, text, Field.Store.YES, Field.Index.ANALYZED);
    +    Field textField = newField(TEXT_FIELD, text, TextField.TYPE_STORED);
         document.add(textField);
     
         // Add the date/time field.
         String dateTimeString = DateTools.timeToString(time, DateTools.Resolution.SECOND);
    -    Field dateTimeField = newField(DATE_TIME_FIELD, dateTimeString, Field.Store.YES,
    -        Field.Index.NOT_ANALYZED);
    +    Field dateTimeField = newField(DATE_TIME_FIELD, dateTimeString, StringField.TYPE_STORED);
         document.add(dateTimeField);
     
         return document;
    Index: lucene/src/test/org/apache/lucene/search/TestMultiTermConstantScore.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestMultiTermConstantScore.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestMultiTermConstantScore.java	(working copy)
    @@ -20,7 +20,9 @@
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.analysis.MockTokenizer;
     import org.apache.lucene.document.Document;
    -import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.FieldType;
    +import org.apache.lucene.document.StringField;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.IndexReader.AtomicReaderContext;
     import org.apache.lucene.index.IndexWriterConfig;
    @@ -64,16 +66,14 @@
             newIndexWriterConfig(TEST_VERSION_CURRENT, 
                 new MockAnalyzer(random, MockTokenizer.WHITESPACE, false)).setMergePolicy(newLogMergePolicy()));
     
    +    FieldType customType = new FieldType(TextField.TYPE_STORED);
    +    customType.setTokenized(false);
         for (int i = 0; i < data.length; i++) {
           Document doc = new Document();
    -      doc.add(newField("id", String.valueOf(i), Field.Store.YES,
    -          Field.Index.NOT_ANALYZED));// Field.Keyword("id",String.valueOf(i)));
    -      doc
    -          .add(newField("all", "all", Field.Store.YES,
    -              Field.Index.NOT_ANALYZED));// Field.Keyword("all","all"));
    +      doc.add(newField("id", String.valueOf(i), customType));// Field.Keyword("id",String.valueOf(i)));
    +      doc.add(newField("all", "all", customType));// Field.Keyword("all","all"));
           if (null != data[i]) {
    -        doc.add(newField("data", data[i], Field.Store.YES,
    -            Field.Index.ANALYZED));// Field.Text("data",data[i]));
    +        doc.add(newField("data", data[i], TextField.TYPE_STORED));// Field.Text("data",data[i]));
           }
           writer.addDocument(doc);
         }
    Index: lucene/src/test/org/apache/lucene/search/TestWildcardRandom.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestWildcardRandom.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestWildcardRandom.java	(working copy)
    @@ -25,6 +25,7 @@
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.StringField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.index.Term;
    @@ -51,7 +52,7 @@
             .setMaxBufferedDocs(_TestUtil.nextInt(random, 50, 1000)));
         
         Document doc = new Document();
    -    Field field = newField("field", "", Field.Store.NO, Field.Index.ANALYZED_NO_NORMS);
    +    Field field = newField("field", "", StringField.TYPE_UNSTORED);
         doc.add(field);
         
         NumberFormat df = new DecimalFormat("000", new DecimalFormatSymbols(Locale.ENGLISH));
    Index: lucene/src/test/org/apache/lucene/search/payloads/TestPayloadNearQuery.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/payloads/TestPayloadNearQuery.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/payloads/TestPayloadNearQuery.java	(working copy)
    @@ -24,7 +24,8 @@
     import org.apache.lucene.analysis.TokenStream;
     import org.apache.lucene.analysis.tokenattributes.PayloadAttribute;
     import org.apache.lucene.document.Document;
    -import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.FieldType;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.FieldInvertState;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.Payload;
    @@ -112,9 +113,11 @@
         //writer.infoStream = System.out;
         for (int i = 0; i < 1000; i++) {
           Document doc = new Document();
    -      doc.add(newField("field", English.intToEnglish(i), Field.Store.YES, Field.Index.ANALYZED));
    +      FieldType customType = new FieldType(TextField.TYPE_UNSTORED);
    +      customType.setStored(true);
    +      doc.add(newField("field", English.intToEnglish(i), customType));
           String txt = English.intToEnglish(i) +' '+English.intToEnglish(i+1);
    -      doc.add(newField("field2",  txt, Field.Store.YES, Field.Index.ANALYZED));
    +      doc.add(newField("field2",  txt, customType));
           writer.addDocument(doc);
         }
         reader = writer.getReader();
    Index: lucene/src/test/org/apache/lucene/search/payloads/TestPayloadTermQuery.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/payloads/TestPayloadTermQuery.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/payloads/TestPayloadTermQuery.java	(working copy)
    @@ -48,6 +48,8 @@
     import org.apache.lucene.document.Field;
     import org.junit.AfterClass;
     import org.junit.BeforeClass;
    +import org.apache.lucene.document.FieldType;
    +import org.apache.lucene.document.TextField;
     
     import java.io.Reader;
     import java.io.IOException;
    @@ -117,13 +119,15 @@
             newIndexWriterConfig(TEST_VERSION_CURRENT, new PayloadAnalyzer())
                                                          .setSimilarityProvider(similarityProvider).setMergePolicy(newLogMergePolicy()));
         //writer.infoStream = System.out;
    +    FieldType customType = new FieldType(TextField.TYPE_UNSTORED);
    +    customType.setStored(true);
         for (int i = 0; i < 1000; i++) {
           Document doc = new Document();
    -      Field noPayloadField = newField(PayloadHelper.NO_PAYLOAD_FIELD, English.intToEnglish(i), Field.Store.YES, Field.Index.ANALYZED);
    +      Field noPayloadField = newField(PayloadHelper.NO_PAYLOAD_FIELD, English.intToEnglish(i), customType);
           //noPayloadField.setBoost(0);
           doc.add(noPayloadField);
    -      doc.add(newField("field", English.intToEnglish(i), Field.Store.YES, Field.Index.ANALYZED));
    -      doc.add(newField("multiField", English.intToEnglish(i) + "  " + English.intToEnglish(i), Field.Store.YES, Field.Index.ANALYZED));
    +      doc.add(newField("field", English.intToEnglish(i), customType));
    +      doc.add(newField("multiField", English.intToEnglish(i) + "  " + English.intToEnglish(i), customType));
           writer.addDocument(doc);
         }
         reader = writer.getReader();
    Index: lucene/src/test/org/apache/lucene/search/payloads/PayloadHelper.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/payloads/PayloadHelper.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/payloads/PayloadHelper.java	(working copy)
    @@ -24,6 +24,7 @@
     import org.apache.lucene.index.IndexWriter;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.util.English;
     import org.apache.lucene.util.LuceneTestCase;
     import org.apache.lucene.index.IndexReader;
    @@ -122,9 +123,9 @@
         // writer.infoStream = System.out;
         for (int i = 0; i < numDocs; i++) {
           Document doc = new Document();
    -      doc.add(new Field(FIELD, English.intToEnglish(i), Field.Store.YES, Field.Index.ANALYZED));
    -      doc.add(new Field(MULTI_FIELD, English.intToEnglish(i) + "  " + English.intToEnglish(i), Field.Store.YES, Field.Index.ANALYZED));
    -      doc.add(new Field(NO_PAYLOAD_FIELD, English.intToEnglish(i), Field.Store.YES, Field.Index.ANALYZED));
    +      doc.add(new Field(FIELD, TextField.TYPE_STORED, English.intToEnglish(i)));
    +      doc.add(new Field(MULTI_FIELD, TextField.TYPE_STORED, English.intToEnglish(i) + "  " + English.intToEnglish(i)));
    +      doc.add(new Field(NO_PAYLOAD_FIELD, TextField.TYPE_STORED, English.intToEnglish(i)));
           writer.addDocument(doc);
         }
         reader = IndexReader.open(writer, true);
    Index: lucene/src/test/org/apache/lucene/search/TestMultiTermQueryRewrites.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestMultiTermQueryRewrites.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestMultiTermQueryRewrites.java	(working copy)
    @@ -20,6 +20,7 @@
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.StringField;
     import org.apache.lucene.search.IndexSearcher;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.MultiReader;
    @@ -53,7 +54,7 @@
     
         for (int i = 0; i < 10; i++) {
           Document doc = new Document();
    -      doc.add(newField("data", Integer.toString(i), Field.Store.NO, Field.Index.NOT_ANALYZED));
    +      doc.add(newField("data", Integer.toString(i), StringField.TYPE_UNSTORED));
           writer.addDocument(doc);
           ((i % 2 == 0) ? swriter1 : swriter2).addDocument(doc);
         }
    Index: lucene/src/test/org/apache/lucene/search/TestBooleanScorer.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestBooleanScorer.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestBooleanScorer.java	(working copy)
    @@ -22,6 +22,8 @@
     
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.FieldType;
    +import org.apache.lucene.document.StringField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.index.Term;
    @@ -40,9 +42,11 @@
         String[] values = new String[] { "1", "2", "3", "4" };
     
         RandomIndexWriter writer = new RandomIndexWriter(random, directory);
    +    FieldType customType = new FieldType(StringField.TYPE_UNSTORED);
    +    customType.setStored(true);
         for (int i = 0; i < values.length; i++) {
           Document doc = new Document();
    -      doc.add(newField(FIELD, values[i], Field.Store.YES, Field.Index.NOT_ANALYZED));
    +      doc.add(newField(FIELD, values[i], customType));
           writer.addDocument(doc);
         }
         IndexReader ir = writer.getReader();
    Index: lucene/src/test/org/apache/lucene/search/TestDocIdSet.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestDocIdSet.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestDocIdSet.java	(working copy)
    @@ -25,8 +25,8 @@
     import junit.framework.Assert;
     
     import org.apache.lucene.document.Document;
    -import org.apache.lucene.document.Field.Index;
    -import org.apache.lucene.document.Field.Store;
    +import org.apache.lucene.document.StringField;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.IndexReader.AtomicReaderContext;
     import org.apache.lucene.index.RandomIndexWriter;
    @@ -103,7 +103,7 @@
         Directory dir = newDirectory();
         RandomIndexWriter writer = new RandomIndexWriter(random, dir);
         Document doc = new Document();
    -    doc.add(newField("c", "val", Store.NO, Index.NOT_ANALYZED_NO_NORMS));
    +    doc.add(newField("c", "val", StringField.TYPE_UNSTORED));
         writer.addDocument(doc);
         IndexReader reader = writer.getReader();
         writer.close();
    Index: lucene/src/test/org/apache/lucene/search/spans/TestNearSpansOrdered.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/spans/TestNearSpansOrdered.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/spans/TestNearSpansOrdered.java	(working copy)
    @@ -19,7 +19,7 @@
     
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
    -import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.IndexReader.AtomicReaderContext;
     import org.apache.lucene.index.IndexReader.ReaderContext;
    @@ -57,7 +57,7 @@
         RandomIndexWriter writer= new RandomIndexWriter(random, directory, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMergePolicy(newLogMergePolicy()));
         for (int i = 0; i < docFields.length; i++) {
           Document doc = new Document();
    -      doc.add(newField(FIELD, docFields[i], Field.Store.NO, Field.Index.ANALYZED));
    +      doc.add(newField(FIELD, docFields[i], TextField.TYPE_UNSTORED));
           writer.addDocument(doc);
         }
         reader = writer.getReader();
    Index: lucene/src/test/org/apache/lucene/search/spans/TestSpanFirstQuery.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/spans/TestSpanFirstQuery.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/spans/TestSpanFirstQuery.java	(working copy)
    @@ -21,7 +21,7 @@
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.analysis.MockTokenizer;
     import org.apache.lucene.document.Document;
    -import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.index.Term;
    @@ -41,10 +41,10 @@
         
         RandomIndexWriter writer = new RandomIndexWriter(random, dir, analyzer);
         Document doc = new Document();
    -    doc.add(newField("field", "the quick brown fox", Field.Index.ANALYZED));
    +    doc.add(newField("field", "the quick brown fox", TextField.TYPE_UNSTORED));
         writer.addDocument(doc);
         Document doc2 = new Document();
    -    doc2.add(newField("field", "quick brown fox", Field.Index.ANALYZED));
    +    doc2.add(newField("field", "quick brown fox", TextField.TYPE_UNSTORED));
         writer.addDocument(doc2);
         
         IndexReader reader = writer.getReader();
    Index: lucene/src/test/org/apache/lucene/search/spans/TestBasics.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/spans/TestBasics.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/spans/TestBasics.java	(working copy)
    @@ -32,7 +32,8 @@
     import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
     import org.apache.lucene.analysis.tokenattributes.PayloadAttribute;
     import org.apache.lucene.document.Document;
    -import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.FieldType;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.Payload;
     import org.apache.lucene.index.RandomIndexWriter;
    @@ -120,7 +121,9 @@
         //writer.infoStream = System.out;
         for (int i = 0; i < 2000; i++) {
           Document doc = new Document();
    -      doc.add(newField("field", English.intToEnglish(i), Field.Store.YES, Field.Index.ANALYZED));
    +      FieldType customType = new FieldType(TextField.TYPE_UNSTORED);
    +      customType.setStored(true);
    +      doc.add(newField("field", English.intToEnglish(i), customType));
           writer.addDocument(doc);
         }
         reader = writer.getReader();
    Index: lucene/src/test/org/apache/lucene/search/spans/TestSpans.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/spans/TestSpans.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/spans/TestSpans.java	(working copy)
    @@ -38,7 +38,9 @@
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.index.Term;
     import org.apache.lucene.document.Document;
    -import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.FieldType;
    +import org.apache.lucene.document.StringField;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.util.LuceneTestCase;
     import org.apache.lucene.util.ReaderUtil;
     
    @@ -56,9 +58,11 @@
         super.setUp();
         directory = newDirectory();
         RandomIndexWriter writer= new RandomIndexWriter(random, directory, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMergePolicy(newLogMergePolicy()));
    +    FieldType customType = new FieldType(TextField.TYPE_UNSTORED);
    +    customType.setStored(true);
         for (int i = 0; i < docFields.length; i++) {
           Document doc = new Document();
    -      doc.add(newField(field, docFields[i], Field.Store.YES, Field.Index.ANALYZED));
    +      doc.add(newField(field, docFields[i], customType));
           writer.addDocument(doc);
         }
         reader = writer.getReader();
    @@ -452,8 +456,12 @@
       // LUCENE-1404
       private void addDoc(IndexWriter writer, String id, String text) throws IOException {
         final Document doc = new Document();
    -    doc.add( newField("id", id, Field.Store.YES, Field.Index.NOT_ANALYZED) );
    -    doc.add( newField("text", text, Field.Store.YES, Field.Index.ANALYZED) );
    +    FieldType customType = new FieldType(TextField.TYPE_UNSTORED);
    +    customType.setStored(true);
    +    FieldType customType2 = new FieldType(StringField.TYPE_UNSTORED);
    +    customType2.setStored(true);
    +    doc.add( newField("id", id, customType2) );
    +    doc.add( newField("text", text, customType) );
         writer.addDocument(doc);
       }
     
    Index: lucene/src/test/org/apache/lucene/search/spans/TestFieldMaskingSpanQuery.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/spans/TestFieldMaskingSpanQuery.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/spans/TestFieldMaskingSpanQuery.java	(working copy)
    @@ -23,6 +23,7 @@
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.index.Term;
    @@ -46,7 +47,7 @@
       }
       
       protected static Field field(String name, String value) {
    -    return newField(name, value, Field.Store.NO, Field.Index.ANALYZED);
    +    return newField(name, value, TextField.TYPE_UNSTORED);
       }
     
       protected static IndexSearcher searcher;
    Index: lucene/src/test/org/apache/lucene/search/spans/TestSpansAdvanced.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/spans/TestSpansAdvanced.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/spans/TestSpansAdvanced.java	(working copy)
    @@ -25,7 +25,9 @@
     import org.apache.lucene.analysis.MockTokenFilter;
     import org.apache.lucene.analysis.MockTokenizer;
     import org.apache.lucene.document.Document;
    -import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.FieldType;
    +import org.apache.lucene.document.StringField;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.index.Term;
    @@ -90,10 +92,12 @@
           final String text) throws IOException {
         
         final Document document = new Document();
    -    document.add(newField(FIELD_ID, id, Field.Store.YES,
    -        Field.Index.NOT_ANALYZED));
    -    document.add(newField(FIELD_TEXT, text, Field.Store.YES,
    -        Field.Index.ANALYZED));
    +    FieldType customType = new FieldType(TextField.TYPE_UNSTORED);
    +    customType.setStored(true);
    +    FieldType customType2 = new FieldType(StringField.TYPE_UNSTORED);
    +    customType2.setStored(true);
    +    document.add(newField(FIELD_ID, id, customType2));
    +    document.add(newField(FIELD_TEXT, text, customType));
         writer.addDocument(document);
       }
       
    Index: lucene/src/test/org/apache/lucene/search/spans/TestSpanMultiTermQueryWrapper.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/spans/TestSpanMultiTermQueryWrapper.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/spans/TestSpanMultiTermQueryWrapper.java	(working copy)
    @@ -19,6 +19,7 @@
     
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.index.Term;
    @@ -42,7 +43,7 @@
         directory = newDirectory();
         RandomIndexWriter iw = new RandomIndexWriter(random, directory);
         Document doc = new Document();
    -    Field field = newField("field", "", Field.Store.NO, Field.Index.ANALYZED);
    +    Field field = newField("field", "", TextField.TYPE_UNSTORED);
         doc.add(field);
         
         field.setValue("quick brown fox");
    Index: lucene/src/test/org/apache/lucene/search/spans/TestPayloadSpans.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/spans/TestPayloadSpans.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/spans/TestPayloadSpans.java	(working copy)
    @@ -31,7 +31,8 @@
     import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
     import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
     import org.apache.lucene.document.Document;
    -import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.FieldType;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.CorruptIndexException;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.index.IndexReader;
    @@ -113,8 +114,9 @@
                                                          newIndexWriterConfig(TEST_VERSION_CURRENT, new PayloadAnalyzer()).setSimilarityProvider(similarity));
     
         Document doc = new Document();
    -    doc.add(newField(PayloadHelper.FIELD, "one two three one four three",
    -        Field.Store.YES, Field.Index.ANALYZED));
    +    FieldType customType = new FieldType(TextField.TYPE_UNSTORED);
    +    customType.setStored(true);
    +    doc.add(newField(PayloadHelper.FIELD, "one two three one four three", customType));
         writer.addDocument(doc);
         IndexReader reader = writer.getReader();
         writer.close();
    @@ -261,7 +263,7 @@
                                                          newIndexWriterConfig(TEST_VERSION_CURRENT, new TestPayloadAnalyzer()));
     
         Document doc = new Document();
    -    doc.add(new Field("content", new StringReader("a b c d e f g h i j a k")));
    +    doc.add(new TextField("content", new StringReader("a b c d e f g h i j a k")));
         writer.addDocument(doc);
     
         IndexReader reader = writer.getReader();
    @@ -300,7 +302,7 @@
                                                          newIndexWriterConfig(TEST_VERSION_CURRENT, new TestPayloadAnalyzer()));
     
         Document doc = new Document();
    -    doc.add(new Field("content", new StringReader("a b a d k f a h i k a k")));
    +    doc.add(new TextField("content", new StringReader("a b a d k f a h i k a k")));
         writer.addDocument(doc);
         IndexReader reader = writer.getReader();
         IndexSearcher is = newSearcher(reader);
    @@ -337,7 +339,7 @@
                                                          newIndexWriterConfig(TEST_VERSION_CURRENT, new TestPayloadAnalyzer()));
     
         Document doc = new Document();
    -    doc.add(new Field("content", new StringReader("j k a l f k k p a t a k l k t a")));
    +    doc.add(new TextField("content", new StringReader("j k a l f k k p a t a k l k t a")));
         writer.addDocument(doc);
         IndexReader reader = writer.getReader();
         IndexSearcher is = newSearcher(reader);
    @@ -379,7 +381,9 @@
                                                          newIndexWriterConfig(TEST_VERSION_CURRENT, new PayloadAnalyzer()).setSimilarityProvider(similarity));
     
         Document doc = new Document();
    -    doc.add(newField(PayloadHelper.FIELD,"xx rr yy mm  pp", Field.Store.YES, Field.Index.ANALYZED));
    +    FieldType customType = new FieldType(TextField.TYPE_UNSTORED);
    +    customType.setStored(true);
    +    doc.add(newField(PayloadHelper.FIELD,"xx rr yy mm  pp", customType));
         writer.addDocument(doc);
       
         IndexReader reader = writer.getReader();
    @@ -440,10 +444,12 @@
                                                          newIndexWriterConfig(TEST_VERSION_CURRENT, new PayloadAnalyzer()).setSimilarityProvider(similarity));
     
         Document doc = null;
    +    FieldType customType = new FieldType(TextField.TYPE_UNSTORED);
    +    customType.setStored(true);
         for(int i = 0; i < docs.length; i++) {
           doc = new Document();
           String docText = docs[i];
    -      doc.add(newField(PayloadHelper.FIELD,docText, Field.Store.YES, Field.Index.ANALYZED));
    +      doc.add(newField(PayloadHelper.FIELD,docText, customType));
           writer.addDocument(doc);
         }
     
    Index: lucene/src/test/org/apache/lucene/search/TestSubScorerFreqs.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestSubScorerFreqs.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestSubScorerFreqs.java	(working copy)
    @@ -46,12 +46,11 @@
         int num = atLeast(31);
         for (int i = 0; i < num; i++) {
           Document doc = new Document();
    -      doc.add(newField("f", "a b c d b c d c d d", Field.Store.NO,
    -          Field.Index.ANALYZED));
    +      doc.add(newField("f", "a b c d b c d c d d", TextField.TYPE_UNSTORED));
           w.addDocument(doc);
     
           doc = new Document();
    -      doc.add(newField("f", "a b c d", Field.Store.NO, Field.Index.ANALYZED));
    +      doc.add(newField("f", "a b c d", TextField.TYPE_UNSTORED));
           w.addDocument(doc);
         }
     
    Index: lucene/src/test/org/apache/lucene/search/TestDocValuesScoring.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestDocValuesScoring.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestDocValuesScoring.java	(working copy)
    @@ -22,6 +22,7 @@
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
     import org.apache.lucene.document.IndexDocValuesField;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.FieldInvertState;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
    @@ -50,11 +51,11 @@
         Directory dir = newDirectory();
         RandomIndexWriter iw = new RandomIndexWriter(random, dir);
         Document doc = new Document();
    -    Field field = newField("foo", "", Field.Store.NO, Field.Index.ANALYZED);
    +    Field field = newField("foo", "", TextField.TYPE_UNSTORED);
         doc.add(field);
         IndexDocValuesField dvField = new IndexDocValuesField("foo_boost");
         doc.add(dvField);
    -    Field field2 = newField("bar", "", Field.Store.NO, Field.Index.ANALYZED);
    +    Field field2 = newField("bar", "", TextField.TYPE_UNSTORED);
         doc.add(field2);
         
         field.setValue("quick brown fox");
    Index: lucene/src/test/org/apache/lucene/search/TestQueryWrapperFilter.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestQueryWrapperFilter.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestQueryWrapperFilter.java	(working copy)
    @@ -18,8 +18,7 @@
      */
     
     import org.apache.lucene.document.Document;
    -import org.apache.lucene.document.Field.Index;
    -import org.apache.lucene.document.Field.Store;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.index.Term;
    @@ -33,7 +32,7 @@
         Directory dir = newDirectory();
         RandomIndexWriter writer = new RandomIndexWriter(random, dir);
         Document doc = new Document();
    -    doc.add(newField("field", "value", Store.NO, Index.ANALYZED));
    +    doc.add(newField("field", "value", TextField.TYPE_UNSTORED));
         writer.addDocument(doc);
         IndexReader reader = writer.getReader();
         writer.close();
    Index: lucene/src/test/org/apache/lucene/search/TestTermVectors.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestTermVectors.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestTermVectors.java	(working copy)
    @@ -23,6 +23,8 @@
     import org.apache.lucene.analysis.MockTokenizer;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.FieldType;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.*;
     import org.apache.lucene.index.IndexWriterConfig.OpenMode;
     import org.apache.lucene.store.Directory;
    @@ -47,26 +49,25 @@
         //writer.infoStream = System.out;
         for (int i = 0; i < 1000; i++) {
           Document doc = new Document();
    -      Field.TermVector termVector;
    +      FieldType ft = new FieldType(TextField.TYPE_STORED);
           int mod3 = i % 3;
           int mod2 = i % 2;
    -      if (mod2 == 0 && mod3 == 0){
    -        termVector = Field.TermVector.WITH_POSITIONS_OFFSETS;
    +      if (mod2 == 0 && mod3 == 0) {
    +        ft.setStoreTermVectors(true);
    +        ft.setStoreTermVectorOffsets(true);
    +        ft.setStoreTermVectorPositions(true);
    +      } else if (mod2 == 0) {
    +        ft.setStoreTermVectors(true);
    +        ft.setStoreTermVectorPositions(true);
    +      } else if (mod3 == 0) {
    +        ft.setStoreTermVectors(true);
    +        ft.setStoreTermVectorOffsets(true);
    +      } else {
    +        ft.setStoreTermVectors(true);
           }
    -      else if (mod2 == 0){
    -        termVector = Field.TermVector.WITH_POSITIONS;
    -      }
    -      else if (mod3 == 0){
    -        termVector = Field.TermVector.WITH_OFFSETS;
    -      }
    -      else {
    -        termVector = Field.TermVector.YES;
    -      }
    -      doc.add(new Field("field", English.intToEnglish(i),
    -          Field.Store.YES, Field.Index.ANALYZED, termVector));
    +      doc.add(new Field("field", ft, English.intToEnglish(i)));
           //test no term vectors too
    -      doc.add(new Field("noTV", English.intToEnglish(i),
    -          Field.Store.YES, Field.Index.ANALYZED));
    +      doc.add(new Field("noTV", TextField.TYPE_STORED, English.intToEnglish(i)));
           writer.addDocument(doc);
         }
         reader = writer.getReader();
    @@ -91,11 +92,10 @@
         ScoreDoc[] hits = searcher.search(query, null, 1000).scoreDocs;
         assertEquals(100, hits.length);
           
    -    for (int i = 0; i < hits.length; i++)
    -    {
    +    for (int i = 0; i < hits.length; i++) {
           TermFreqVector [] vector = searcher.reader.getTermFreqVectors(hits[i].doc);
           assertTrue(vector != null);
    -      assertTrue(vector.length == 1);
    +      assertEquals("doc=" + hits[i].doc + " tv=" + vector, 1, vector.length);
         }
         TermFreqVector vector;
         vector = searcher.reader.getTermFreqVector(hits[0].doc, "noTV");
    @@ -109,11 +109,15 @@
       public void testTermVectorsFieldOrder() throws IOException {
         Directory dir = newDirectory();
         RandomIndexWriter writer = new RandomIndexWriter(random, dir, new MockAnalyzer(random, MockTokenizer.SIMPLE, true));
    -    Document doc = new Document();
    -    doc.add(new Field("c", "some content here", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS));
    -    doc.add(new Field("a", "some content here", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS));
    -    doc.add(new Field("b", "some content here", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS));
    -    doc.add(new Field("x", "some content here", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS));
    +    Document doc = new Document();;
    +    FieldType ft = new FieldType(TextField.TYPE_STORED);
    +    ft.setStoreTermVectors(true);
    +    ft.setStoreTermVectorOffsets(true);
    +    ft.setStoreTermVectorPositions(true);
    +    doc.add(newField("c", "some content here", ft));
    +    doc.add(newField("a", "some content here", ft));
    +    doc.add(newField("b", "some content here", ft));
    +    doc.add(newField("x", "some content here", ft));
         writer.addDocument(doc);
         IndexReader reader = writer.getReader();
         writer.close();
    @@ -341,10 +345,14 @@
       
       private void setupDoc(Document doc, String text)
       {
    -    doc.add(new Field("field2", text, Field.Store.YES,
    -        Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS));
    -    doc.add(new Field("field", text, Field.Store.YES,
    -        Field.Index.ANALYZED, Field.TermVector.YES));
    +    FieldType ft = new FieldType(TextField.TYPE_STORED);
    +    ft.setStoreTermVectors(true);
    +    ft.setStoreTermVectorOffsets(true);
    +    ft.setStoreTermVectorPositions(true);
    +    FieldType ft2 = new FieldType(TextField.TYPE_STORED);
    +    ft2.setStoreTermVectors(true);
    +    doc.add(newField("field2", text, ft));
    +    doc.add(newField("field", text, ft2));
         //System.out.println("Document: " + doc);
       }
     
    @@ -359,17 +367,19 @@
         }
         for (int i = 0; i < 100; i++) {
           Document doc = new Document();
    -      doc.add(new Field("field", English.intToEnglish(i),
    -                        Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.NO));
    +      doc.add(newField("field", English.intToEnglish(i), TextField.TYPE_STORED));
           writer.addDocument(doc);
         }
         if (VERBOSE) {
           System.out.println("TEST: now add vectors");
         }
    +    FieldType ft = new FieldType(TextField.TYPE_STORED);
    +    ft.setStoreTermVectors(true);
    +    ft.setStoreTermVectorOffsets(true);
    +    ft.setStoreTermVectorPositions(true);
         for(int i=0;i<10;i++) {
           Document doc = new Document();
    -      doc.add(new Field("field", English.intToEnglish(100+i),
    -                        Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS));
    +      doc.add(newField("field", English.intToEnglish(100+i), ft));
           writer.addDocument(doc);
         }
     
    @@ -400,16 +410,28 @@
             newIndexWriterConfig(TEST_VERSION_CURRENT, 
             new MockAnalyzer(random, MockTokenizer.SIMPLE, true)).setOpenMode(OpenMode.CREATE));
         Document doc = new Document();
    -    doc.add(new Field("field", "one",
    -                      Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.NO));
    -    doc.add(new Field("field", "one",
    -                      Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES));
    -    doc.add(new Field("field", "one",
    -                      Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS));
    -    doc.add(new Field("field", "one",
    -                      Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_OFFSETS));
    -    doc.add(new Field("field", "one",
    -                      Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS));
    +    
    +    FieldType ft2 = new FieldType(TextField.TYPE_STORED);
    +    ft2.setStoreTermVectors(true);
    +    
    +    FieldType ft3 = new FieldType(TextField.TYPE_STORED);
    +    ft3.setStoreTermVectors(true);
    +    ft3.setStoreTermVectorPositions(true);
    +    
    +    FieldType ft4 = new FieldType(TextField.TYPE_STORED);
    +    ft4.setStoreTermVectors(true);
    +    ft4.setStoreTermVectorOffsets(true);
    +    
    +    FieldType ft5 = new FieldType(TextField.TYPE_STORED);
    +    ft5.setStoreTermVectors(true);
    +    ft5.setStoreTermVectorOffsets(true);
    +    ft5.setStoreTermVectorPositions(true);
    +    
    +    doc.add(newField("field", "one", TextField.TYPE_STORED));
    +    doc.add(newField("field", "one", ft2));
    +    doc.add(newField("field", "one", ft3));
    +    doc.add(newField("field", "one", ft4));
    +    doc.add(newField("field", "one", ft5));
         writer.addDocument(doc);
         IndexReader reader = writer.getReader();
         writer.close();
    Index: lucene/src/test/org/apache/lucene/search/TestMultiValuedNumericRangeQuery.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestMultiValuedNumericRangeQuery.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestMultiValuedNumericRangeQuery.java	(working copy)
    @@ -23,8 +23,8 @@
     
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
    -import org.apache.lucene.document.Field;
     import org.apache.lucene.document.NumericField;
    +import org.apache.lucene.document.StringField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.store.Directory;
    @@ -51,8 +51,8 @@
           Document doc = new Document();
           for (int m=0, c=random.nextInt(10); m<=c; m++) {
             int value = random.nextInt(Integer.MAX_VALUE);
    -        doc.add(newField("asc", format.format(value), Field.Store.NO, Field.Index.NOT_ANALYZED));
    -        doc.add(new NumericField("trie", Field.Store.NO, true).setIntValue(value));
    +        doc.add(newField("asc", format.format(value), StringField.TYPE_UNSTORED));
    +        doc.add(new NumericField("trie").setIntValue(value));
           }
           writer.addDocument(doc);
         }
    Index: lucene/src/test/org/apache/lucene/search/TestTermScorer.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestTermScorer.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestTermScorer.java	(working copy)
    @@ -24,6 +24,7 @@
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader.AtomicReaderContext;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
    @@ -51,8 +52,7 @@
         for (int i = 0; i < values.length; i++) {
           Document doc = new Document();
           doc
    -          .add(newField(FIELD, values[i], Field.Store.YES,
    -              Field.Index.ANALYZED));
    +          .add(newField(FIELD, values[i], TextField.TYPE_STORED));
           writer.addDocument(doc);
         }
         indexReader = new SlowMultiReaderWrapper(writer.getReader());
    Index: lucene/src/test/org/apache/lucene/search/TestPhrasePrefixQuery.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestPhrasePrefixQuery.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestPhrasePrefixQuery.java	(working copy)
    @@ -19,7 +19,7 @@
     
     import org.apache.lucene.util.LuceneTestCase;
     import org.apache.lucene.document.Document;
    -import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.index.TermsEnum;
     import org.apache.lucene.index.IndexReader;
    @@ -47,16 +47,11 @@
         Document doc3 = new Document();
         Document doc4 = new Document();
         Document doc5 = new Document();
    -    doc1.add(newField("body", "blueberry pie", Field.Store.YES,
    -        Field.Index.ANALYZED));
    -    doc2.add(newField("body", "blueberry strudel", Field.Store.YES,
    -        Field.Index.ANALYZED));
    -    doc3.add(newField("body", "blueberry pizza", Field.Store.YES,
    -        Field.Index.ANALYZED));
    -    doc4.add(newField("body", "blueberry chewing gum", Field.Store.YES,
    -        Field.Index.ANALYZED));
    -    doc5.add(newField("body", "piccadilly circus", Field.Store.YES,
    -        Field.Index.ANALYZED));
    +    doc1.add(newField("body", "blueberry pie", TextField.TYPE_STORED));
    +    doc2.add(newField("body", "blueberry strudel", TextField.TYPE_STORED));
    +    doc3.add(newField("body", "blueberry pizza", TextField.TYPE_STORED));
    +    doc4.add(newField("body", "blueberry chewing gum", TextField.TYPE_STORED));
    +    doc5.add(newField("body", "piccadilly circus", TextField.TYPE_STORED));
         writer.addDocument(doc1);
         writer.addDocument(doc2);
         writer.addDocument(doc3);
    Index: lucene/src/test/org/apache/lucene/search/TestSetNorm.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestSetNorm.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestSetNorm.java	(working copy)
    @@ -39,7 +39,7 @@
         IndexWriter writer = new IndexWriter(store, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random)));
     
         // add the same document four times
    -    Fieldable f1 = newField("field", "word", Field.Store.YES, Field.Index.ANALYZED);
    +    Field f1 = newField("field", "word", TextField.TYPE_STORED);
         Document d1 = new Document();
         d1.add(f1);
         writer.addDocument(d1);
    Index: lucene/src/test/org/apache/lucene/search/TestWildcard.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestWildcard.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestWildcard.java	(working copy)
    @@ -21,9 +21,7 @@
     import org.apache.lucene.util.LuceneTestCase;
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
    -import org.apache.lucene.document.Field;
    -import org.apache.lucene.document.Field.Store;
    -import org.apache.lucene.document.Field.Index;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.MultiFields;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.index.Term;
    @@ -244,7 +242,7 @@
         RandomIndexWriter writer = new RandomIndexWriter(random, indexStore);
         for (int i = 0; i < contents.length; ++i) {
           Document doc = new Document();
    -      doc.add(newField(field, contents[i], Field.Store.YES, Field.Index.ANALYZED));
    +      doc.add(newField(field, contents[i], TextField.TYPE_STORED));
           writer.addDocument(doc);
         }
         writer.close();
    @@ -344,7 +342,7 @@
             .setMergePolicy(newLogMergePolicy()));
         for (int i = 0; i < docs.length; i++) {
           Document doc = new Document();
    -      doc.add(newField(field,docs[i],Store.NO,Index.ANALYZED));
    +      doc.add(newField(field,docs[i],TextField.TYPE_UNSTORED));
           iw.addDocument(doc);
         }
         iw.close();
    Index: lucene/src/test/org/apache/lucene/search/TestTopDocsMerge.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestTopDocsMerge.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestTopDocsMerge.java	(working copy)
    @@ -24,6 +24,8 @@
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
     import org.apache.lucene.document.NumericField;
    +import org.apache.lucene.document.StringField;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.index.Term;
    @@ -90,8 +92,8 @@
     
           for(int docIDX=0;docIDX fields = doc.getFields();
    -      for (final Fieldable f : fields ) {
    -        validateField(f);
    -      }
    -
    -    }
    -
    -  }
    -
    -
    -  void validateField(Fieldable f) {
    -    String val = f.stringValue();
    -    if (!val.startsWith("^") || !val.endsWith("$")) {
    -      throw new RuntimeException("Invalid field:" + f.toString() + " val=" +val);
    -    }
    -  }
    -
    -  String[] words = "now is the time for all good men to come to the aid of their country".split(" ");
    -
    -  void buildDir(Directory dir, int nDocs, int maxFields, int maxFieldLen) throws IOException {
    -    IndexWriter iw = new IndexWriter(dir, new IndexWriterConfig(
    -        TEST_VERSION_CURRENT, new MockAnalyzer(random)).setOpenMode(OpenMode.CREATE).setMaxBufferedDocs(10));
    -    for (int j=0; j terms = new ArrayList();
         int num = atLeast(200);
    Index: lucene/src/test/org/apache/lucene/search/TestMultiThreadTermVectors.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestMultiThreadTermVectors.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestMultiThreadTermVectors.java	(working copy)
    @@ -41,9 +41,13 @@
         IndexWriter writer = new IndexWriter(directory, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMergePolicy(newLogMergePolicy()));
         //writer.setUseCompoundFile(false);
         //writer.infoStream = System.out;
    +    FieldType customType = new FieldType(TextField.TYPE_STORED);
    +    customType.setStored(true);
    +    customType.setTokenized(false);
    +    customType.setStoreTermVectors(true);
         for (int i = 0; i < numDocs; i++) {
           Document doc = new Document();
    -      Fieldable fld = newField("field", English.intToEnglish(i), Field.Store.YES, Field.Index.NOT_ANALYZED, Field.TermVector.YES);
    +      Field fld = newField("field", English.intToEnglish(i), customType);
           doc.add(fld);
           writer.addDocument(doc);
         }
    Index: lucene/src/test/org/apache/lucene/search/TestRegexpQuery.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestRegexpQuery.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestRegexpQuery.java	(working copy)
    @@ -21,7 +21,7 @@
     import java.util.Arrays;
     
     import org.apache.lucene.document.Document;
    -import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.index.Term;
    @@ -50,7 +50,7 @@
         Document doc = new Document();
         doc.add(newField(FN,
             "the quick brown fox jumps over the lazy ??? dog 493432 49344",
    -        Field.Store.NO, Field.Index.ANALYZED));
    +        TextField.TYPE_UNSTORED));
         writer.addDocument(doc);
         reader = writer.getReader();
         writer.close();
    Index: lucene/src/test/org/apache/lucene/search/TestDateFilter.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestDateFilter.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestDateFilter.java	(working copy)
    @@ -22,6 +22,8 @@
     import org.apache.lucene.document.DateTools;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.FieldType;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.index.Term;
    @@ -47,11 +49,13 @@
         
         Document doc = new Document();
         // add time that is in the past
    +    FieldType customType = new FieldType(TextField.TYPE_STORED);
    +    customType.setTokenized(false);
    +    FieldType customType2 = new FieldType(TextField.TYPE_STORED);
         doc.add(newField("datefield", DateTools.timeToString(now - 1000,
    -        DateTools.Resolution.MILLISECOND), Field.Store.YES,
    -        Field.Index.NOT_ANALYZED));
    +        DateTools.Resolution.MILLISECOND), customType));
         doc.add(newField("body", "Today is a very sunny day in New York City",
    -        Field.Store.YES, Field.Index.ANALYZED));
    +        customType2));
         writer.addDocument(doc);
         
         IndexReader reader = writer.getReader();
    @@ -114,11 +118,13 @@
         
         Document doc = new Document();
         // add time that is in the future
    +    FieldType customType = new FieldType(TextField.TYPE_STORED);
    +    customType.setTokenized(false);
    +    FieldType customType2 = new FieldType(TextField.TYPE_STORED);
         doc.add(newField("datefield", DateTools.timeToString(now + 888888,
    -        DateTools.Resolution.MILLISECOND), Field.Store.YES,
    -        Field.Index.NOT_ANALYZED));
    +        DateTools.Resolution.MILLISECOND), customType));
         doc.add(newField("body", "Today is a very sunny day in New York City",
    -        Field.Store.YES, Field.Index.ANALYZED));
    +        customType2));
         writer.addDocument(doc);
         
         IndexReader reader = writer.getReader();
    Index: lucene/src/test/org/apache/lucene/search/TestCachingSpanFilter.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestCachingSpanFilter.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestCachingSpanFilter.java	(working copy)
    @@ -22,6 +22,9 @@
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.FieldType;
    +import org.apache.lucene.document.StringField;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.index.SerialMergeScheduler;
    @@ -54,7 +57,10 @@
     
         // add a doc, refresh the reader, and check that its there
         Document doc = new Document();
    -    doc.add(newField("id", "1", Field.Store.YES, Field.Index.NOT_ANALYZED));
    +    FieldType customType = new FieldType(TextField.TYPE_UNSTORED);
    +    customType.setStored(true);
    +    customType.setTokenized(false);
    +    doc.add(newField("id", "1", customType));
         writer.addDocument(doc);
     
         reader = refreshReader(reader);
    Index: lucene/src/test/org/apache/lucene/search/TestFilteredSearch.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestFilteredSearch.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestFilteredSearch.java	(working copy)
    @@ -22,7 +22,7 @@
     import org.apache.lucene.util.LuceneTestCase;
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
    -import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.StringField;
     import org.apache.lucene.index.CorruptIndexException;
     import org.apache.lucene.index.IndexReader.AtomicReaderContext;
     import org.apache.lucene.index.IndexWriter;
    @@ -64,7 +64,7 @@
         try {
           for (int i = 0; i < 60; i++) {//Simple docs
             Document doc = new Document();
    -        doc.add(newField(FIELD, Integer.toString(i), Field.Store.YES, Field.Index.NOT_ANALYZED));
    +        doc.add(newField(FIELD, Integer.toString(i), StringField.TYPE_STORED));
             writer.addDocument(doc);
           }
           if(optimize)
    Index: lucene/src/test/org/apache/lucene/search/TestMatchAllDocsQuery.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestMatchAllDocsQuery.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestMatchAllDocsQuery.java	(working copy)
    @@ -22,6 +22,7 @@
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexWriter;
     import org.apache.lucene.index.Term;
     import org.apache.lucene.index.IndexReader;
    @@ -89,7 +90,7 @@
       
       private void addDoc(String text, IndexWriter iw, float boost) throws IOException {
         Document doc = new Document();
    -    Field f = newField("key", text, Field.Store.YES, Field.Index.ANALYZED);
    +    Field f = newField("key", text, TextField.TYPE_STORED);
         f.setBoost(boost);
         doc.add(f);
         iw.addDocument(doc);
    Index: lucene/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java	(working copy)
    @@ -21,6 +21,9 @@
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.FieldType;
    +import org.apache.lucene.document.StringField;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.IndexReader.AtomicReaderContext;
     import org.apache.lucene.index.SlowMultiReaderWrapper;
    @@ -83,6 +86,11 @@
       public IndexReader r;
       public IndexSearcher s;
       
    +  private static final FieldType nonAnalyzedType = new FieldType(TextField.TYPE_STORED);
    +  static {
    +    nonAnalyzedType.setTokenized(false);
    +  }
    +  
       @Override
       public void setUp() throws Exception {
         super.setUp();
    @@ -97,57 +105,51 @@
         // d1 is an "ok" match for: albino elephant
         {
           Document d1 = new Document();
    -      d1.add(newField("id", "d1", Field.Store.YES, Field.Index.NOT_ANALYZED));// Field.Keyword("id",
    +      d1.add(newField("id", "d1", nonAnalyzedType));// Field.Keyword("id",
                                                                                    // "d1"));
           d1
    -          .add(newField("hed", "elephant", Field.Store.YES,
    -              Field.Index.ANALYZED));// Field.Text("hed", "elephant"));
    +          .add(newField("hed", "elephant", TextField.TYPE_STORED));// Field.Text("hed", "elephant"));
           d1
    -          .add(newField("dek", "elephant", Field.Store.YES,
    -              Field.Index.ANALYZED));// Field.Text("dek", "elephant"));
    +          .add(newField("dek", "elephant", TextField.TYPE_STORED));// Field.Text("dek", "elephant"));
           writer.addDocument(d1);
         }
         
         // d2 is a "good" match for: albino elephant
         {
           Document d2 = new Document();
    -      d2.add(newField("id", "d2", Field.Store.YES, Field.Index.NOT_ANALYZED));// Field.Keyword("id",
    +      d2.add(newField("id", "d2", nonAnalyzedType));// Field.Keyword("id",
                                                                                    // "d2"));
           d2
    -          .add(newField("hed", "elephant", Field.Store.YES,
    -              Field.Index.ANALYZED));// Field.Text("hed", "elephant"));
    -      d2.add(newField("dek", "albino", Field.Store.YES, Field.Index.ANALYZED));// Field.Text("dek",
    +          .add(newField("hed", "elephant", TextField.TYPE_STORED));// Field.Text("hed", "elephant"));
    +      d2.add(newField("dek", "albino", TextField.TYPE_STORED));// Field.Text("dek",
                                                                                     // "albino"));
           d2
    -          .add(newField("dek", "elephant", Field.Store.YES,
    -              Field.Index.ANALYZED));// Field.Text("dek", "elephant"));
    +          .add(newField("dek", "elephant", TextField.TYPE_STORED));// Field.Text("dek", "elephant"));
           writer.addDocument(d2);
         }
         
         // d3 is a "better" match for: albino elephant
         {
           Document d3 = new Document();
    -      d3.add(newField("id", "d3", Field.Store.YES, Field.Index.NOT_ANALYZED));// Field.Keyword("id",
    +      d3.add(newField("id", "d3", nonAnalyzedType));// Field.Keyword("id",
                                                                                    // "d3"));
    -      d3.add(newField("hed", "albino", Field.Store.YES, Field.Index.ANALYZED));// Field.Text("hed",
    +      d3.add(newField("hed", "albino", TextField.TYPE_STORED));// Field.Text("hed",
                                                                                     // "albino"));
           d3
    -          .add(newField("hed", "elephant", Field.Store.YES,
    -              Field.Index.ANALYZED));// Field.Text("hed", "elephant"));
    +          .add(newField("hed", "elephant", TextField.TYPE_STORED));// Field.Text("hed", "elephant"));
           writer.addDocument(d3);
         }
         
         // d4 is the "best" match for: albino elephant
         {
           Document d4 = new Document();
    -      d4.add(newField("id", "d4", Field.Store.YES, Field.Index.NOT_ANALYZED));// Field.Keyword("id",
    +      d4.add(newField("id", "d4", nonAnalyzedType));// Field.Keyword("id",
                                                                                    // "d4"));
    -      d4.add(newField("hed", "albino", Field.Store.YES, Field.Index.ANALYZED));// Field.Text("hed",
    +      d4.add(newField("hed", "albino", TextField.TYPE_STORED));// Field.Text("hed",
                                                                                     // "albino"));
           d4
    -          .add(newField("hed", "elephant", Field.Store.YES,
    -              Field.Index.ANALYZED));// Field.Text("hed", "elephant"));
    -      d4.add(newField("dek", "albino", Field.Store.YES, Field.Index.ANALYZED));// Field.Text("dek",
    +          .add(newField("hed", "elephant", nonAnalyzedType));// Field.Text("hed", "elephant"));
    +      d4.add(newField("dek", "albino", TextField.TYPE_STORED));// Field.Text("dek",
                                                                                     // "albino"));
           writer.addDocument(d4);
         }
    Index: lucene/src/test/org/apache/lucene/search/TestSimilarity.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestSimilarity.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestSimilarity.java	(working copy)
    @@ -31,6 +31,7 @@
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.TextField;
     
     /** Similarity unit test.
      *
    @@ -61,10 +62,10 @@
             .setSimilarityProvider(new SimpleSimilarityProvider()));
         
         Document d1 = new Document();
    -    d1.add(newField("field", "a c", Field.Store.YES, Field.Index.ANALYZED));
    +    d1.add(newField("field", "a c", TextField.TYPE_STORED));
     
         Document d2 = new Document();
    -    d2.add(newField("field", "a b c", Field.Store.YES, Field.Index.ANALYZED));
    +    d2.add(newField("field", "a b c", TextField.TYPE_STORED));
         
         writer.addDocument(d1);
         writer.addDocument(d2);
    Index: lucene/src/test/org/apache/lucene/search/TestFieldCacheRangeFilter.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestFieldCacheRangeFilter.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestFieldCacheRangeFilter.java	(working copy)
    @@ -26,6 +26,7 @@
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.StringField;
     import org.apache.lucene.store.Directory;
     import org.junit.Test;
     
    @@ -535,8 +536,8 @@
     
         for (int d = -20; d <= 20; d++) {
           Document doc = new Document();
    -      doc.add(newField("id",Integer.toString(d), Field.Store.NO, Field.Index.NOT_ANALYZED));
    -      doc.add(newField("body","body", Field.Store.NO, Field.Index.NOT_ANALYZED));
    +      doc.add(newField("id",Integer.toString(d), StringField.TYPE_UNSTORED));
    +      doc.add(newField("body","body", StringField.TYPE_UNSTORED));
           writer.addDocument(doc);
         }
         
    Index: lucene/src/test/org/apache/lucene/search/TestRegexpRandom.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestRegexpRandom.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestRegexpRandom.java	(working copy)
    @@ -25,6 +25,8 @@
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.FieldType;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.index.Term;
    @@ -51,7 +53,10 @@
             .setMaxBufferedDocs(_TestUtil.nextInt(random, 50, 1000)));
         
         Document doc = new Document();
    -    Field field = newField("field", "", Field.Store.NO, Field.Index.ANALYZED_NO_NORMS);
    +    FieldType customType = new FieldType(TextField.TYPE_UNSTORED);
    +    customType.setStored(true);
    +    customType.setOmitNorms(true);
    +    Field field = newField("field", "", customType);
         doc.add(field);
         
         NumberFormat df = new DecimalFormat("000", new DecimalFormatSymbols(Locale.ENGLISH));
    Index: lucene/src/test/org/apache/lucene/search/TestSpanQueryFilter.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestSpanQueryFilter.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestSpanQueryFilter.java	(working copy)
    @@ -20,7 +20,7 @@
     
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
    -import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader.AtomicReaderContext;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
    @@ -39,7 +39,7 @@
         for (int i = 0; i < 500; i++) {
           Document document = new Document();
           document.add(newField("field", English.intToEnglish(i) + " equals " + English.intToEnglish(i),
    -              Field.Store.NO, Field.Index.ANALYZED));
    +              TextField.TYPE_UNSTORED));
           writer.addDocument(document);
         }
         final int number = 10;
    Index: lucene/src/test/org/apache/lucene/search/TestPrefixRandom.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestPrefixRandom.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestPrefixRandom.java	(working copy)
    @@ -23,6 +23,7 @@
     import org.apache.lucene.analysis.MockTokenizer;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.StringField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.Term;
     import org.apache.lucene.index.Terms;
    @@ -53,7 +54,7 @@
             .setMaxBufferedDocs(_TestUtil.nextInt(random, 50, 1000)));
         
         Document doc = new Document();
    -    Field field = newField("field", "", Field.Store.NO, Field.Index.NOT_ANALYZED);
    +    Field field = newField("field", "", StringField.TYPE_UNSTORED);
         doc.add(field);
     
         // we generate aweful prefixes: good for testing.
    Index: lucene/src/test/org/apache/lucene/search/TestCustomSearcherSort.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestCustomSearcherSort.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestCustomSearcherSort.java	(working copy)
    @@ -25,7 +25,8 @@
     
     import org.apache.lucene.document.DateTools;
     import org.apache.lucene.document.Document;
    -import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.FieldType;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.index.Term;
    @@ -51,21 +52,23 @@
         index = newDirectory();
         RandomIndexWriter writer = new RandomIndexWriter(random, index);
         RandomGen random = new RandomGen(this.random);
    +    FieldType customType = new FieldType(TextField.TYPE_UNSTORED);
    +    customType.setStored(true);
    +    customType.setTokenized(false);
    +    FieldType customType2 = new FieldType(TextField.TYPE_UNSTORED);
    +    customType2.setStored(true);
         for (int i = 0; i < INDEX_SIZE; ++i) { // don't decrease; if to low the
                                                // problem doesn't show up
           Document doc = new Document();
           if ((i % 5) != 0) { // some documents must not have an entry in the first
                               // sort field
    -        doc.add(newField("publicationDate_", random.getLuceneDate(),
    -            Field.Store.YES, Field.Index.NOT_ANALYZED));
    +        doc.add(newField("publicationDate_", random.getLuceneDate(), customType));
           }
           if ((i % 7) == 0) { // some documents to match the query (see below)
    -        doc.add(newField("content", "test", Field.Store.YES,
    -            Field.Index.ANALYZED));
    +        doc.add(newField("content", "test", customType2));
           }
           // every document has a defined 'mandant' field
    -      doc.add(newField("mandant", Integer.toString(i % 3), Field.Store.YES,
    -          Field.Index.NOT_ANALYZED));
    +      doc.add(newField("mandant", Integer.toString(i % 3), customType));
           writer.addDocument(doc);
         }
         reader = writer.getReader();
    Index: lucene/src/test/org/apache/lucene/search/TestSimilarityProvider.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestSimilarityProvider.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestSimilarityProvider.java	(working copy)
    @@ -20,6 +20,7 @@
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.FieldInvertState;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.IndexWriterConfig;
    @@ -44,9 +45,9 @@
             new MockAnalyzer(random)).setSimilarityProvider(sim);
         RandomIndexWriter iw = new RandomIndexWriter(random, directory, iwc);
         Document doc = new Document();
    -    Field field = newField("foo", "", Field.Store.NO, Field.Index.ANALYZED);
    +    Field field = newField("foo", "", TextField.TYPE_UNSTORED);
         doc.add(field);
    -    Field field2 = newField("bar", "", Field.Store.NO, Field.Index.ANALYZED);
    +    Field field2 = newField("bar", "", TextField.TYPE_UNSTORED);
         doc.add(field2);
         
         field.setValue("quick brown fox");
    Index: lucene/src/test/org/apache/lucene/search/TestPrefixInBooleanQuery.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestPrefixInBooleanQuery.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestPrefixInBooleanQuery.java	(working copy)
    @@ -20,6 +20,7 @@
     import org.apache.lucene.util.LuceneTestCase;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.StringField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.index.Term;
    @@ -50,8 +51,7 @@
         RandomIndexWriter writer = new RandomIndexWriter(random, directory);
     
         Document doc = new Document();
    -    Field field = newField(FIELD, "meaninglessnames", Field.Store.NO,
    -        Field.Index.NOT_ANALYZED_NO_NORMS);
    +    Field field = newField(FIELD, "meaninglessnames", StringField.TYPE_UNSTORED);
         doc.add(field);
         
         for (int i = 0; i < 5137; ++i) {
    Index: lucene/src/test/org/apache/lucene/search/TestNumericRangeQuery32.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestNumericRangeQuery32.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestNumericRangeQuery32.java	(working copy)
    @@ -58,15 +58,15 @@
             newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random))
             .setMaxBufferedDocs(_TestUtil.nextInt(random, 100, 1000))
             .setMergePolicy(newLogMergePolicy()));
    -    
    +  
         NumericField
    -      field8 = new NumericField("field8", 8, Field.Store.YES, true),
    -      field4 = new NumericField("field4", 4, Field.Store.YES, true),
    -      field2 = new NumericField("field2", 2, Field.Store.YES, true),
    -      fieldNoTrie = new NumericField("field"+Integer.MAX_VALUE, Integer.MAX_VALUE, rarely() ? Field.Store.YES : Field.Store.NO, true),
    -      ascfield8 = new NumericField("ascfield8", 8, Field.Store.NO, true),
    -      ascfield4 = new NumericField("ascfield4", 4, Field.Store.NO, true),
    -      ascfield2 = new NumericField("ascfield2", 2, Field.Store.NO, true);
    +	    field8 = new NumericField("field8", 8, NumericField.TYPE_STORED),
    +	    field4 = new NumericField("field4", 4, NumericField.TYPE_STORED),
    +	    field2 = new NumericField("field2", 2, NumericField.TYPE_STORED),
    +	    fieldNoTrie = new NumericField("field"+Integer.MAX_VALUE, Integer.MAX_VALUE, rarely() ? NumericField.TYPE_STORED : NumericField.TYPE_UNSTORED),
    +	    ascfield8 = new NumericField("ascfield8", 8, NumericField.TYPE_UNSTORED),
    +	    ascfield4 = new NumericField("ascfield4", 4, NumericField.TYPE_UNSTORED),
    +	    ascfield2 = new NumericField("ascfield2", 2, NumericField.TYPE_UNSTORED);
         
         Document doc = new Document();
         // add fields, that have a distance to test general functionality
    Index: lucene/src/test/org/apache/lucene/search/TestElevationComparator.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestElevationComparator.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestElevationComparator.java	(working copy)
    @@ -20,6 +20,7 @@
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.*;
     import org.apache.lucene.index.IndexReader.AtomicReaderContext;
     import org.apache.lucene.search.FieldValueHitQueue.Entry;
    @@ -124,7 +125,7 @@
      private Document adoc(String[] vals) {
        Document doc = new Document();
        for (int i = 0; i < vals.length - 2; i += 2) {
    -     doc.add(newField(vals[i], vals[i + 1], Field.Store.YES, Field.Index.ANALYZED));
    +     doc.add(newField(vals[i], vals[i + 1], TextField.TYPE_STORED));
        }
        return doc;
      }
    Index: lucene/src/test/org/apache/lucene/search/TestNumericRangeQuery64.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestNumericRangeQuery64.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestNumericRangeQuery64.java	(working copy)
    @@ -57,15 +57,15 @@
             .setMergePolicy(newLogMergePolicy()));
         
         NumericField
    -      field8 = new NumericField("field8", 8, Field.Store.YES, true),
    -      field6 = new NumericField("field6", 6, Field.Store.YES, true),
    -      field4 = new NumericField("field4", 4, Field.Store.YES, true),
    -      field2 = new NumericField("field2", 2, Field.Store.YES, true),
    -      fieldNoTrie = new NumericField("field"+Integer.MAX_VALUE, Integer.MAX_VALUE, rarely() ? Field.Store.YES : Field.Store.NO, true),
    -      ascfield8 = new NumericField("ascfield8", 8, Field.Store.NO, true),
    -      ascfield6 = new NumericField("ascfield6", 6, Field.Store.NO, true),
    -      ascfield4 = new NumericField("ascfield4", 4, Field.Store.NO, true),
    -      ascfield2 = new NumericField("ascfield2", 2, Field.Store.NO, true);
    +      field8 = new NumericField("field8", 8, NumericField.TYPE_STORED),
    +      field6 = new NumericField("field6", 6, NumericField.TYPE_STORED),
    +      field4 = new NumericField("field4", 4, NumericField.TYPE_STORED),
    +      field2 = new NumericField("field2", 2, NumericField.TYPE_STORED),
    +      fieldNoTrie = new NumericField("field"+Integer.MAX_VALUE, Integer.MAX_VALUE, rarely() ? NumericField.TYPE_STORED : NumericField.TYPE_UNSTORED),
    +      ascfield8 = new NumericField("ascfield8", 8, NumericField.TYPE_UNSTORED),
    +      ascfield6 = new NumericField("ascfield6", 6, NumericField.TYPE_UNSTORED),
    +      ascfield4 = new NumericField("ascfield4", 4, NumericField.TYPE_UNSTORED),
    +      ascfield2 = new NumericField("ascfield2", 2, NumericField.TYPE_UNSTORED);
         
         Document doc = new Document();
         // add fields, that have a distance to test general functionality
    Index: lucene/src/test/org/apache/lucene/search/TestPrefixQuery.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestPrefixQuery.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestPrefixQuery.java	(working copy)
    @@ -25,7 +25,7 @@
     import org.apache.lucene.index.Term;
     import org.apache.lucene.index.Terms;
     import org.apache.lucene.document.Document;
    -import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.StringField;
     
     /**
      * Tests {@link PrefixQuery} class.
    @@ -41,7 +41,7 @@
         RandomIndexWriter writer = new RandomIndexWriter(random, directory);
         for (int i = 0; i < categories.length; i++) {
           Document doc = new Document();
    -      doc.add(newField("category", categories[i], Field.Store.YES, Field.Index.NOT_ANALYZED));
    +      doc.add(newField("category", categories[i], StringField.TYPE_STORED));
           writer.addDocument(doc);
         }
         IndexReader reader = writer.getReader();
    Index: lucene/src/test/org/apache/lucene/search/TestMultiPhraseQuery.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestMultiPhraseQuery.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestMultiPhraseQuery.java	(working copy)
    @@ -33,6 +33,8 @@
     import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.StringField;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexWriter;
     import org.apache.lucene.search.IndexSearcher;
     import org.apache.lucene.store.RAMDirectory;
    @@ -164,7 +166,7 @@
       
       private void add(String s, RandomIndexWriter writer) throws IOException {
         Document doc = new Document();
    -    doc.add(newField("body", s, Field.Store.YES, Field.Index.ANALYZED));
    +    doc.add(newField("body", s, TextField.TYPE_STORED));
         writer.addDocument(doc);
       }
       
    @@ -287,8 +289,8 @@
       private void add(String s, String type, RandomIndexWriter writer)
           throws IOException {
         Document doc = new Document();
    -    doc.add(newField("body", s, Field.Store.YES, Field.Index.ANALYZED));
    -    doc.add(newField("type", type, Field.Store.YES, Field.Index.NOT_ANALYZED));
    +    doc.add(newField("body", s, TextField.TYPE_STORED));
    +    doc.add(newField("type", type, StringField.TYPE_UNSTORED));
         writer.addDocument(doc);
       }
       
    @@ -389,7 +391,7 @@
     
         RandomIndexWriter writer = new RandomIndexWriter(random, dir, new CannedAnalyzer(tokens));
         Document doc = new Document();
    -    doc.add(new Field("field", "", Field.Store.NO, Field.Index.ANALYZED));
    +    doc.add(new TextField("field", ""));
         writer.addDocument(doc);
         writer.addDocument(doc);
         IndexReader r = writer.getReader();
    @@ -481,7 +483,7 @@
         IndexWriterConfig cfg = newIndexWriterConfig(TEST_VERSION_CURRENT, new CannedAnalyzer(INCR_0_DOC_TOKENS));
         IndexWriter writer = new IndexWriter(dir, cfg);
         Document doc = new Document();
    -    doc.add(new Field("field", "", Field.Store.NO, Field.Index.ANALYZED));
    +    doc.add(new TextField("field", ""));
         writer.addDocument(doc);
         IndexReader r = IndexReader.open(writer,false);
         writer.close();
    Index: lucene/src/test/org/apache/lucene/search/TestFilteredQuery.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestFilteredQuery.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestFilteredQuery.java	(working copy)
    @@ -22,6 +22,7 @@
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader.AtomicReaderContext;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
    @@ -54,23 +55,23 @@
         RandomIndexWriter writer = new RandomIndexWriter (random, directory, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMergePolicy(newLogMergePolicy()));
     
         Document doc = new Document();
    -    doc.add (newField("field", "one two three four five", Field.Store.YES, Field.Index.ANALYZED));
    -    doc.add (newField("sorter", "b", Field.Store.YES, Field.Index.ANALYZED));
    +    doc.add (newField("field", "one two three four five", TextField.TYPE_STORED));
    +    doc.add (newField("sorter", "b", TextField.TYPE_STORED));
         writer.addDocument (doc);
     
         doc = new Document();
    -    doc.add (newField("field", "one two three four", Field.Store.YES, Field.Index.ANALYZED));
    -    doc.add (newField("sorter", "d", Field.Store.YES, Field.Index.ANALYZED));
    +    doc.add (newField("field", "one two three four", TextField.TYPE_STORED));
    +    doc.add (newField("sorter", "d", TextField.TYPE_STORED));
         writer.addDocument (doc);
     
         doc = new Document();
    -    doc.add (newField("field", "one two three y", Field.Store.YES, Field.Index.ANALYZED));
    -    doc.add (newField("sorter", "a", Field.Store.YES, Field.Index.ANALYZED));
    +    doc.add (newField("field", "one two three y", TextField.TYPE_STORED));
    +    doc.add (newField("sorter", "a", TextField.TYPE_STORED));
         writer.addDocument (doc);
     
         doc = new Document();
    -    doc.add (newField("field", "one two x", Field.Store.YES, Field.Index.ANALYZED));
    -    doc.add (newField("sorter", "c", Field.Store.YES, Field.Index.ANALYZED));
    +    doc.add (newField("field", "one two x", TextField.TYPE_STORED));
    +    doc.add (newField("sorter", "c", TextField.TYPE_STORED));
         writer.addDocument (doc);
     
         // tests here require single segment (eg try seed
    Index: lucene/src/test/org/apache/lucene/search/TestFieldCacheTermsFilter.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/search/TestFieldCacheTermsFilter.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/search/TestFieldCacheTermsFilter.java	(working copy)
    @@ -21,6 +21,7 @@
     
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.StringField;
     import org.apache.lucene.index.IndexReader;
     import org.apache.lucene.index.RandomIndexWriter;
     import org.apache.lucene.store.Directory;
    @@ -41,7 +42,7 @@
         for (int i = 0; i < 100; i++) {
           Document doc = new Document();
           int term = i * 10; //terms are units of 10;
    -      doc.add(newField(fieldName, "" + term, Field.Store.YES, Field.Index.NOT_ANALYZED));
    +      doc.add(newField(fieldName, "" + term, StringField.TYPE_STORED));
           w.addDocument(doc);
         }
         IndexReader reader = w.getReader();
    Index: lucene/src/test/org/apache/lucene/index/TestIndexableField.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/index/TestIndexableField.java	(revision 0)
    +++ lucene/src/test/org/apache/lucene/index/TestIndexableField.java	(revision 1160484)
    @@ -0,0 +1,342 @@
    +package org.apache.lucene.index;
    +
    +/**
    + * 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.
    + */
    +
    +import java.io.Reader;
    +import java.io.StringReader;
    +import java.util.Iterator;
    +
    +import org.apache.lucene.analysis.TokenStream;
    +import org.apache.lucene.document.Document;
    +import org.apache.lucene.document.NumericField.DataType;
    +import org.apache.lucene.document.NumericField;
    +import org.apache.lucene.document.StringField;
    +import org.apache.lucene.index.values.PerDocFieldValues;
    +import org.apache.lucene.index.values.ValueType;
    +import org.apache.lucene.search.BooleanClause;
    +import org.apache.lucene.search.BooleanQuery;
    +import org.apache.lucene.search.IndexSearcher;
    +import org.apache.lucene.search.NumericRangeQuery;
    +import org.apache.lucene.search.TermQuery;
    +import org.apache.lucene.search.TopDocs;
    +import org.apache.lucene.store.Directory;
    +import org.apache.lucene.util.BytesRef;
    +import org.apache.lucene.util.LuceneTestCase;
    +import org.apache.lucene.util._TestUtil;
    +
    +public class TestIndexableField extends LuceneTestCase {
    +
    +  private class MyField implements IndexableField {
    +
    +    private final int counter;
    +
    +    public MyField(int counter) {
    +      this.counter = counter;
    +    }
    +
    +    @Override
    +    public String name() {
    +      return "f" + counter;
    +    }
    +
    +    @Override
    +    public float boost() {
    +      return 1.0f + random.nextFloat();
    +    }
    +  
    +    @Override
    +    public boolean stored() {
    +      return (counter & 1) == 0 || (counter % 10) == 3;
    +    }
    +
    +    @Override
    +    public BytesRef binaryValue() {
    +      if ((counter%10) == 3) {
    +        final byte[] bytes = new byte[10];
    +        for(int idx=0;idx() {
    +        @Override
    +        public Iterator iterator() {
    +          return new Iterator() {
    +            int fieldUpto;
    +
    +            @Override
    +            public boolean hasNext() {
    +              return fieldUpto < fieldCount;
    +            }
    +
    +            @Override
    +            public IndexableField next() {
    +              assert fieldUpto < fieldCount;
    +              if (fieldUpto == 0) {
    +                fieldUpto = 1;
    +                return newField("id", ""+finalDocCount, StringField.TYPE_STORED);
    +              } else {
    +                return new MyField(finalBaseCount + (fieldUpto++-1));
    +              }
    +            }
    +
    +            @Override
    +            public void remove() {
    +              throw new UnsupportedOperationException();
    +            }
    +          };
    +        }
    +        });
    +    }
    +
    +    final IndexReader r = w.getReader();
    +    w.close();
    +
    +    final IndexSearcher s = new IndexSearcher(r);
    +    int counter = 0;
    +    for(int id=0;id valueVarList, boolean withDeletions, int bytesSize)
           throws CorruptIndexException, IOException {
         final boolean isNumeric = NUMERICS.contains(value);
         FixedBitSet deleted = new FixedBitSet(numValues);
         Document doc = new Document();
    -    Index idx = IDX_VALUES[random.nextInt(IDX_VALUES.length)];
    -    AbstractField field = random.nextBoolean() ? new IndexDocValuesField(value.name())
    -        : newField(value.name(), _TestUtil.randomRealisticUnicodeString(random,
    -            10), idx == Index.NO ? Store.YES : Store.NO, idx);
    -    doc.add(field);
    -    IndexDocValuesField valField = new IndexDocValuesField("prototype");
    +    FieldType ft = new FieldType();
    +    ft.setIndexed(random.nextBoolean());
    +    if (ft.indexed()) {
    +      ft.setTokenized(random.nextBoolean());
    +      ft.setOmitNorms(random.nextBoolean());
    +    }
    +    else {
    +      ft.setStored(true);
    +    }
    +    
    +    IndexDocValuesField valField = new IndexDocValuesField(value.name());
    +    doc.add(valField);
         final BytesRef bytesRef = new BytesRef();
     
         final String idBase = value.name() + "_";
    @@ -543,9 +545,7 @@
             }
           }
           doc.removeFields("id");
    -      doc.add(new Field("id", idBase + i, Store.YES,
    -          Index.NOT_ANALYZED_NO_NORMS));
    -      valField.set(field);
    +      doc.add(new Field("id", StringField.TYPE_STORED, idBase + i));
           w.addDocument(doc);
     
           if (i % 7 == 0) {
    @@ -567,8 +567,9 @@
         w.commit();
     
         // TODO test unoptimized with deletions
    -    if (withDeletions || random.nextBoolean())
    +    if (withDeletions || random.nextBoolean()) {
           w.optimize(true);
    +    }
         return deleted;
       }
     }
    Index: lucene/src/test/org/apache/lucene/index/TestStressNRT.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/index/TestStressNRT.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/index/TestStressNRT.java	(working copy)
    @@ -28,7 +28,8 @@
     
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
    -import org.apache.lucene.document.Field;
    +import org.apache.lucene.document.FieldType;
    +import org.apache.lucene.document.StringField;
     import org.apache.lucene.search.IndexSearcher;
     import org.apache.lucene.search.Query;
     import org.apache.lucene.search.ScoreDoc;
    @@ -81,6 +82,9 @@
         final int nReadThreads = _TestUtil.nextInt(random, 1, TEST_NIGHTLY ? 10 : 5);
         initModel(ndocs);
     
    +    final FieldType storedOnlyType = new FieldType();
    +    storedOnlyType.setStored(true);
    +
         if (VERBOSE) {
           System.out.println("\n");
           System.out.println("TEST: commitPercent=" + commitPercent);
    @@ -228,8 +232,8 @@
                         // add tombstone first
                         if (tombstones) {
                           Document d = new Document();
    -                      d.add(new Field("id","-"+Integer.toString(id), Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
    -                      d.add(new Field(field, Long.toString(nextVal), Field.Store.YES, Field.Index.NO));
    +                      d.add(newField("id", "-"+Integer.toString(id), StringField.TYPE_STORED));
    +                      d.add(newField(field, Long.toString(nextVal), storedOnlyType));
                           writer.updateDocument(new Term("id", "-"+Integer.toString(id)), d);
                         }
     
    @@ -244,8 +248,8 @@
                         // add tombstone first
                         if (tombstones) {
                           Document d = new Document();
    -                      d.add(new Field("id","-"+Integer.toString(id), Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
    -                      d.add(new Field(field, Long.toString(nextVal), Field.Store.YES, Field.Index.NO));
    +                      d.add(newField("id", "-"+Integer.toString(id), StringField.TYPE_STORED));
    +                      d.add(newField(field, Long.toString(nextVal), storedOnlyType));
                           writer.updateDocument(new Term("id", "-"+Integer.toString(id)), d);
                         }
     
    @@ -257,8 +261,8 @@
                       } else {
                         // assertU(adoc("id",Integer.toString(id), field, Long.toString(nextVal)));
                         Document d = new Document();
    -                    d.add(newField("id",Integer.toString(id), Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
    -                    d.add(newField(field, Long.toString(nextVal), Field.Store.YES, Field.Index.NO));
    +                    d.add(newField("id", Integer.toString(id), StringField.TYPE_STORED));
    +                    d.add(newField(field, Long.toString(nextVal), storedOnlyType));
                         if (VERBOSE) {
                           System.out.println("TEST: " + Thread.currentThread().getName() + ": u id:" + id + " val=" + nextVal);
                         }
    Index: lucene/src/test/org/apache/lucene/index/TestIndexReader.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/index/TestIndexReader.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/index/TestIndexReader.java	(working copy)
    @@ -31,27 +31,22 @@
     import java.util.SortedSet;
     import org.junit.Assume;
     import org.apache.lucene.analysis.MockAnalyzer;
    +import org.apache.lucene.document.BinaryField;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    -import org.apache.lucene.document.FieldSelector;
    -import org.apache.lucene.document.Fieldable;
    -import org.apache.lucene.document.SetBasedFieldSelector;
    +import org.apache.lucene.document.FieldType;
    +import org.apache.lucene.document.StringField;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexReader.FieldOption;
     import org.apache.lucene.index.codecs.CodecProvider;
     import org.apache.lucene.index.IndexWriterConfig.OpenMode;
     import org.apache.lucene.search.DefaultSimilarity;
     import org.apache.lucene.search.DocIdSetIterator;
     import org.apache.lucene.search.FieldCache;
    -import org.apache.lucene.search.Similarity;
    -import org.apache.lucene.search.IndexSearcher;
    -import org.apache.lucene.search.ScoreDoc;
    -import org.apache.lucene.search.TermQuery;
     import org.apache.lucene.store.AlreadyClosedException;
     import org.apache.lucene.store.Directory;
     import org.apache.lucene.store.LockObtainFailedException;
    -import org.apache.lucene.store.MockDirectoryWrapper;
     import org.apache.lucene.store.NoSuchDirectoryException;
    -import org.apache.lucene.store.RAMDirectory;
     import org.apache.lucene.store.LockReleaseFailedException;
     import org.apache.lucene.util.LuceneTestCase;
     import org.apache.lucene.util._TestUtil;
    @@ -154,10 +149,20 @@
             );
     
             Document doc = new Document();
    -        doc.add(new Field("keyword","test1", Field.Store.YES, Field.Index.NOT_ANALYZED));
    -        doc.add(new Field("text","test1", Field.Store.YES, Field.Index.ANALYZED));
    -        doc.add(new Field("unindexed","test1", Field.Store.YES, Field.Index.NO));
    -        doc.add(new Field("unstored","test1", Field.Store.NO, Field.Index.ANALYZED));
    +        FieldType customType = new FieldType(TextField.TYPE_UNSTORED);
    +        customType.setStored(true);
    +        customType.setTokenized(false);
    +
    +        FieldType customType2 = new FieldType(TextField.TYPE_UNSTORED);
    +        customType2.setStored(true);
    +
    +        FieldType customType3 = new FieldType();
    +        customType3.setStored(true);
    +        
    +        doc.add(new Field("keyword",customType,"test1"));
    +        doc.add(new Field("text",customType2,"test1"));
    +        doc.add(new Field("unindexed",customType3,"test1"));
    +        doc.add(new TextField("unstored","test1"));
             writer.addDocument(doc);
     
             writer.close();
    @@ -180,29 +185,49 @@
             int mergeFactor = ((LogMergePolicy) writer.getConfig().getMergePolicy()).getMergeFactor();
             for (int i = 0; i < 5*mergeFactor; i++) {
               doc = new Document();
    -          doc.add(new Field("keyword","test1", Field.Store.YES, Field.Index.NOT_ANALYZED));
    -          doc.add(new Field("text","test1", Field.Store.YES, Field.Index.ANALYZED));
    -          doc.add(new Field("unindexed","test1", Field.Store.YES, Field.Index.NO));
    -          doc.add(new Field("unstored","test1", Field.Store.NO, Field.Index.ANALYZED));
    +          doc.add(new Field("keyword",customType,"test1"));
    +          doc.add(new Field("text",customType2, "test1"));
    +          doc.add(new Field("unindexed",customType3,"test1"));
    +          doc.add(new TextField("unstored","test1"));
               writer.addDocument(doc);
             }
             // new fields are in some different segments (we hope)
             for (int i = 0; i < 5*mergeFactor; i++) {
               doc = new Document();
    -          doc.add(new Field("keyword2","test1", Field.Store.YES, Field.Index.NOT_ANALYZED));
    -          doc.add(new Field("text2","test1", Field.Store.YES, Field.Index.ANALYZED));
    -          doc.add(new Field("unindexed2","test1", Field.Store.YES, Field.Index.NO));
    -          doc.add(new Field("unstored2","test1", Field.Store.NO, Field.Index.ANALYZED));
    +          doc.add(new Field("keyword2",customType,"test1"));
    +          doc.add(new Field("text2",customType2, "test1"));
    +          doc.add(new Field("unindexed2",customType3,"test1"));
    +          doc.add(new TextField("unstored2","test1"));
               writer.addDocument(doc);
             }
             // new termvector fields
    +
    +        FieldType customType4 = new FieldType(TextField.TYPE_UNSTORED);
    +        customType4.setStored(true);
    +        FieldType customType5 = new FieldType(TextField.TYPE_UNSTORED);
    +        customType5.setStored(true);
    +        customType5.setStoreTermVectors(true);
    +        FieldType customType6 = new FieldType(TextField.TYPE_UNSTORED);
    +        customType6.setStored(true);
    +        customType6.setStoreTermVectors(true);
    +        customType6.setStoreTermVectorOffsets(true);
    +        FieldType customType7 = new FieldType(TextField.TYPE_UNSTORED);
    +        customType7.setStored(true);
    +        customType7.setStoreTermVectors(true);
    +        customType7.setStoreTermVectorPositions(true);
    +        FieldType customType8 = new FieldType(TextField.TYPE_UNSTORED);
    +        customType8.setStored(true);
    +        customType8.setStoreTermVectors(true);
    +        customType8.setStoreTermVectorOffsets(true);
    +        customType8.setStoreTermVectorPositions(true);
    +        
             for (int i = 0; i < 5*mergeFactor; i++) {
               doc = new Document();
    -          doc.add(new Field("tvnot","tvnot", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.NO));
    -          doc.add(new Field("termvector","termvector", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES));
    -          doc.add(new Field("tvoffset","tvoffset", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_OFFSETS));
    -          doc.add(new Field("tvposition","tvposition", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS));
    -          doc.add(newField("tvpositionoffset","tvpositionoffset", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS));
    +          doc.add(new Field("tvnot",customType4,"tvnot"));
    +          doc.add(new Field("termvector",customType5,"termvector"));
    +          doc.add(new Field("tvoffset",customType6,"tvoffset"));
    +          doc.add(new Field("tvposition",customType7,"tvposition"));
    +          doc.add(new Field("tvpositionoffset",customType8, "tvpositionoffset"));
               writer.addDocument(doc);
             }
             
    @@ -277,14 +302,32 @@
         // want to get some more segments here
         // new termvector fields
         int mergeFactor = ((LogMergePolicy) writer.getConfig().getMergePolicy()).getMergeFactor();
    +    FieldType customType4 = new FieldType(TextField.TYPE_UNSTORED);
    +    customType4.setStored(true);
    +    FieldType customType5 = new FieldType(TextField.TYPE_UNSTORED);
    +    customType5.setStored(true);
    +    customType5.setStoreTermVectors(true);
    +    FieldType customType6 = new FieldType(TextField.TYPE_UNSTORED);
    +    customType6.setStored(true);
    +    customType6.setStoreTermVectors(true);
    +    customType6.setStoreTermVectorOffsets(true);
    +    FieldType customType7 = new FieldType(TextField.TYPE_UNSTORED);
    +    customType7.setStored(true);
    +    customType7.setStoreTermVectors(true);
    +    customType7.setStoreTermVectorPositions(true);
    +    FieldType customType8 = new FieldType(TextField.TYPE_UNSTORED);
    +    customType8.setStored(true);
    +    customType8.setStoreTermVectors(true);
    +    customType8.setStoreTermVectorOffsets(true);
    +    customType8.setStoreTermVectorPositions(true);
         for (int i = 0; i < 5 * mergeFactor; i++) {
           Document doc = new Document();
    -        doc.add(new Field("tvnot","one two two three three three", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.NO));
    -        doc.add(new Field("termvector","one two two three three three", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES));
    -        doc.add(new Field("tvoffset","one two two three three three", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_OFFSETS));
    -        doc.add(new Field("tvposition","one two two three three three", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS));
    -        doc.add(new Field("tvpositionoffset","one two two three three three", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS));
    -
    +        doc.add(new Field("tvnot",customType4,"one two two three three three"));
    +        doc.add(new Field("termvector",customType5,"one two two three three three"));
    +        doc.add(new Field("tvoffset",customType6,"one two two three three three"));
    +        doc.add(new Field("tvposition",customType7,"one two two three three three"));
    +        doc.add(new Field("tvpositionoffset",customType8, "one two two three three three"));
    +        
             writer.addDocument(doc);
         }
         writer.close();
    @@ -338,37 +381,22 @@
             writer.close();
             writer = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setOpenMode(OpenMode.APPEND).setMergePolicy(newLogMergePolicy()));
             Document doc = new Document();
    -        doc.add(new Field("bin1", bin));
    -        doc.add(new Field("junk", "junk text", Field.Store.NO, Field.Index.ANALYZED));
    +        doc.add(new BinaryField("bin1", bin));
    +        doc.add(new TextField("junk", "junk text"));
             writer.addDocument(doc);
             writer.close();
             IndexReader reader = IndexReader.open(dir, false);
    -        doc = reader.document(reader.maxDoc() - 1);
    -        Field[] fields = doc.getFields("bin1");
    +        Document doc2 = reader.document(reader.maxDoc() - 1);
    +        IndexableField[] fields = doc2.getFields("bin1");
             assertNotNull(fields);
             assertEquals(1, fields.length);
    -        Field b1 = fields[0];
    -        assertTrue(b1.isBinary());
    -        byte[] data1 = b1.getBinaryValue();
    -        assertEquals(bin.length, b1.getBinaryLength());
    +        IndexableField b1 = fields[0];
    +        assertTrue(b1.binaryValue() != null);
    +        BytesRef bytesRef = b1.binaryValue();
    +        assertEquals(bin.length, bytesRef.length);
             for (int i = 0; i < bin.length; i++) {
    -          assertEquals(bin[i], data1[i + b1.getBinaryOffset()]);
    +          assertEquals(bin[i], bytesRef.bytes[i + bytesRef.offset]);
             }
    -        Set lazyFields = new HashSet();
    -        lazyFields.add("bin1");
    -        FieldSelector sel = new SetBasedFieldSelector(new HashSet(), lazyFields);
    -        doc = reader.document(reader.maxDoc() - 1, sel);
    -        Fieldable[] fieldables = doc.getFieldables("bin1");
    -        assertNotNull(fieldables);
    -        assertEquals(1, fieldables.length);
    -        Fieldable fb1 = fieldables[0];
    -        assertTrue(fb1.isBinary());
    -        assertEquals(bin.length, fb1.getBinaryLength());
    -        data1 = fb1.getBinaryValue();
    -        assertEquals(bin.length, fb1.getBinaryLength());
    -        for (int i = 0; i < bin.length; i++) {
    -          assertEquals(bin[i], data1[i + fb1.getBinaryOffset()]);
    -        }
             reader.close();
             // force optimize
     
    @@ -377,16 +405,16 @@
             writer.optimize();
             writer.close();
             reader = IndexReader.open(dir, false);
    -        doc = reader.document(reader.maxDoc() - 1);
    -        fields = doc.getFields("bin1");
    +        doc2 = reader.document(reader.maxDoc() - 1);
    +        fields = doc2.getFields("bin1");
             assertNotNull(fields);
             assertEquals(1, fields.length);
             b1 = fields[0];
    -        assertTrue(b1.isBinary());
    -        data1 = b1.getBinaryValue();
    -        assertEquals(bin.length, b1.getBinaryLength());
    +        assertTrue(b1.binaryValue() != null);
    +        bytesRef = b1.binaryValue();
    +        assertEquals(bin.length, bytesRef.length);
             for (int i = 0; i < bin.length; i++) {
    -          assertEquals(bin[i], data1[i + b1.getBinaryOffset()]);
    +          assertEquals(bin[i], bytesRef.bytes[i + bytesRef.offset]);
             }
             reader.close();
             dir.close();
    @@ -778,38 +806,76 @@
         static void addDocumentWithFields(IndexWriter writer) throws IOException
         {
             Document doc = new Document();
    -        doc.add(newField("keyword","test1", Field.Store.YES, Field.Index.NOT_ANALYZED));
    -        doc.add(newField("text","test1", Field.Store.YES, Field.Index.ANALYZED));
    -        doc.add(newField("unindexed","test1", Field.Store.YES, Field.Index.NO));
    -        doc.add(newField("unstored","test1", Field.Store.NO, Field.Index.ANALYZED));
    +        
    +        FieldType customType = new FieldType(TextField.TYPE_UNSTORED);
    +        customType.setStored(true);
    +        customType.setTokenized(false);
    +
    +        FieldType customType2 = new FieldType(TextField.TYPE_UNSTORED);
    +        customType2.setStored(true);
    +
    +        FieldType customType3 = new FieldType();
    +        customType3.setStored(true);
    +        doc.add(newField("keyword", "test1", customType));
    +        doc.add(newField("text", "test1", customType2));
    +        doc.add(newField("unindexed", "test1", customType3));
    +        doc.add(new TextField("unstored","test1"));
             writer.addDocument(doc);
         }
     
         static void addDocumentWithDifferentFields(IndexWriter writer) throws IOException
         {
    -        Document doc = new Document();
    -        doc.add(newField("keyword2","test1", Field.Store.YES, Field.Index.NOT_ANALYZED));
    -        doc.add(newField("text2","test1", Field.Store.YES, Field.Index.ANALYZED));
    -        doc.add(newField("unindexed2","test1", Field.Store.YES, Field.Index.NO));
    -        doc.add(newField("unstored2","test1", Field.Store.NO, Field.Index.ANALYZED));
    -        writer.addDocument(doc);
    +      Document doc = new Document();
    +      
    +      FieldType customType = new FieldType(TextField.TYPE_UNSTORED);
    +      customType.setStored(true);
    +      customType.setTokenized(false);
    +
    +      FieldType customType2 = new FieldType(TextField.TYPE_UNSTORED);
    +      customType2.setStored(true);
    +
    +      FieldType customType3 = new FieldType();
    +      customType3.setStored(true);
    +      doc.add(newField("keyword2", "test1", customType));
    +      doc.add(newField("text2", "test1", customType2));
    +      doc.add(newField("unindexed2", "test1", customType3));
    +      doc.add(new TextField("unstored2","test1"));
    +      writer.addDocument(doc);
         }
     
         static void addDocumentWithTermVectorFields(IndexWriter writer) throws IOException
         {
             Document doc = new Document();
    -        doc.add(newField("tvnot","tvnot", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.NO));
    -        doc.add(newField("termvector","termvector", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES));
    -        doc.add(newField("tvoffset","tvoffset", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_OFFSETS));
    -        doc.add(newField("tvposition","tvposition", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS));
    -        doc.add(newField("tvpositionoffset","tvpositionoffset", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS));
    +        FieldType customType4 = new FieldType(TextField.TYPE_UNSTORED);
    +        customType4.setStored(true);
    +        FieldType customType5 = new FieldType(TextField.TYPE_UNSTORED);
    +        customType5.setStored(true);
    +        customType5.setStoreTermVectors(true);
    +        FieldType customType6 = new FieldType(TextField.TYPE_UNSTORED);
    +        customType6.setStored(true);
    +        customType6.setStoreTermVectors(true);
    +        customType6.setStoreTermVectorOffsets(true);
    +        FieldType customType7 = new FieldType(TextField.TYPE_UNSTORED);
    +        customType7.setStored(true);
    +        customType7.setStoreTermVectors(true);
    +        customType7.setStoreTermVectorPositions(true);
    +        FieldType customType8 = new FieldType(TextField.TYPE_UNSTORED);
    +        customType8.setStored(true);
    +        customType8.setStoreTermVectors(true);
    +        customType8.setStoreTermVectorOffsets(true);
    +        customType8.setStoreTermVectorPositions(true);
    +        doc.add(newField("tvnot","tvnot",customType4));
    +        doc.add(newField("termvector","termvector",customType5));
    +        doc.add(newField("tvoffset","tvoffset", customType6));
    +        doc.add(newField("tvposition","tvposition", customType7));
    +        doc.add(newField("tvpositionoffset","tvpositionoffset", customType8));
             
             writer.addDocument(doc);
         }
         
         static void addDoc(IndexWriter writer, String value) throws IOException {
             Document doc = new Document();
    -        doc.add(newField("content", value, Field.Store.NO, Field.Index.ANALYZED));
    +        doc.add(newField("content", value, TextField.TYPE_UNSTORED));
             writer.addDocument(doc);
         }
     
    @@ -862,11 +928,11 @@
             if (liveDocs1 == null || liveDocs1.get(i)) {
               Document doc1 = index1.document(i);
               Document doc2 = index2.document(i);
    -          List fieldable1 = doc1.getFields();
    -          List fieldable2 = doc2.getFields();
    -          assertEquals("Different numbers of fields for doc " + i + ".", fieldable1.size(), fieldable2.size());
    -          Iterator itField1 = fieldable1.iterator();
    -          Iterator itField2 = fieldable2.iterator();
    +          List field1 = doc1.getFields();
    +          List field2 = doc2.getFields();
    +          assertEquals("Different numbers of fields for doc " + i + ".", field1.size(), field2.size());
    +          Iterator itField1 = field1.iterator();
    +          Iterator itField2 = field2.iterator();
               while (itField1.hasNext()) {
                 Field curField1 = (Field) itField1.next();
                 Field curField2 = (Field) itField2.next();
    @@ -1047,7 +1113,12 @@
     
       static Document createDocument(String id) {
         Document doc = new Document();
    -    doc.add(newField("id", id, Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
    +    FieldType customType = new FieldType(TextField.TYPE_UNSTORED);
    +    customType.setStored(true);
    +    customType.setTokenized(false);
    +    customType.setOmitNorms(true);
    +    
    +    doc.add(newField("id", id, customType));
         return doc;
       }
     
    @@ -1097,7 +1168,7 @@
         Directory dir = newDirectory();
         IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)));
         Document doc = new Document();
    -    doc.add(newField("number", "17", Field.Store.NO, Field.Index.NOT_ANALYZED));
    +    doc.add(newField("number", "17", StringField.TYPE_UNSTORED));
         writer.addDocument(doc);
         writer.close();
     
    @@ -1132,7 +1203,7 @@
                 setMergePolicy(newLogMergePolicy(10))
         );
         Document doc = new Document();
    -    doc.add(newField("number", "17", Field.Store.NO, Field.Index.NOT_ANALYZED));
    +    doc.add(newField("number", "17", StringField.TYPE_UNSTORED));
         writer.addDocument(doc);
         writer.commit();
     
    @@ -1164,8 +1235,8 @@
         Directory dir = newDirectory();
         IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setCodecProvider(_TestUtil.alwaysCodec("Standard")));
         Document doc = new Document();
    -    doc.add(newField("field", "a b c d e f g h i j k l m n o p q r s t u v w x y z", Field.Store.NO, Field.Index.ANALYZED));
    -    doc.add(newField("number", "0 1 2 3 4 5 6 7 8 9", Field.Store.NO, Field.Index.ANALYZED));
    +    doc.add(newField("field", "a b c d e f g h i j k l m n o p q r s t u v w x y z", TextField.TYPE_UNSTORED));
    +    doc.add(newField("number", "0 1 2 3 4 5 6 7 8 9", TextField.TYPE_UNSTORED));
         writer.addDocument(doc);
         writer.addDocument(doc);
         writer.commit();
    @@ -1197,8 +1268,8 @@
         Directory dir = newDirectory();
         IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setCodecProvider(_TestUtil.alwaysCodec("Standard")));
         Document doc = new Document();
    -    doc.add(newField("field", "a b c d e f g h i j k l m n o p q r s t u v w x y z", Field.Store.NO, Field.Index.ANALYZED));
    -    doc.add(newField("number", "0 1 2 3 4 5 6 7 8 9", Field.Store.NO, Field.Index.ANALYZED));
    +    doc.add(newField("field", "a b c d e f g h i j k l m n o p q r s t u v w x y z", TextField.TYPE_UNSTORED));
    +    doc.add(newField("number", "0 1 2 3 4 5 6 7 8 9", TextField.TYPE_UNSTORED));
         writer.addDocument(doc);
         writer.addDocument(doc);
         writer.close();
    @@ -1302,7 +1373,7 @@
         Directory dir = newDirectory();
         IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)));
         Document d = new Document();
    -    d.add(newField("f", "a a b", Field.Index.ANALYZED));
    +    d.add(newField("f", "a a b", TextField.TYPE_UNSTORED));
         writer.addDocument(d);
         IndexReader r = writer.getReader();
         writer.close();
    Index: lucene/src/test/org/apache/lucene/index/TestStressIndexing2.java
    ===================================================================
    --- lucene/src/test/org/apache/lucene/index/TestStressIndexing2.java	(revision 1158028)
    +++ lucene/src/test/org/apache/lucene/index/TestStressIndexing2.java	(working copy)
    @@ -31,7 +31,8 @@
     import org.apache.lucene.analysis.MockAnalyzer;
     import org.apache.lucene.document.Document;
     import org.apache.lucene.document.Field;
    -import org.apache.lucene.document.Fieldable;
    +import org.apache.lucene.document.FieldType;
    +import org.apache.lucene.document.TextField;
     import org.apache.lucene.index.IndexWriterConfig.OpenMode;
     import org.apache.lucene.search.TermQuery;
     import org.apache.lucene.store.Directory;
    @@ -130,11 +131,16 @@
     
       static Term idTerm = new Term("id","");
       IndexingThread[] threads;
    -  static Comparator fieldNameComparator = new Comparator() {
    -        public int compare(Fieldable o1, Fieldable o2) {
    -          return o1.name().compareTo(o2.name());
    -        }
    +  static Comparator fieldNameComparator = new Comparator() {
    +    public int compare(IndexableField o1, IndexableField o2) {
    +      return o1.name().compareTo(o2.name());
    +    }
       };
    +  static Comparator fieldNameComparator2 = new Comparator() {
    +    public int compare(IndexableField o1, IndexableField o2) {
    +      return o1.name().compareTo(o2.name());
    +    }
    +  };
     
       // This test avoids using any extra synchronization in the multiple
       // indexing threads to test that IndexWriter does correctly synchronize
    @@ -249,13 +255,12 @@
         Iterator iter = docs.values().iterator();
         while (iter.hasNext()) {
           Document d = iter.next();
    -      ArrayList fields = new ArrayList();
    +      ArrayList fields = new ArrayList();
           fields.addAll(d.getFields());
           // put fields in same order each time
    -      Collections.sort(fields, fieldNameComparator);
    +      Collections.sort(fields, fieldNameComparator2);
           
           Document d1 = new Document();
    -      d1.setBoost(d.getBoost());
           for (int i=0; i ff1 = d1.getFields();
    -    List ff2 = d2.getFields();
    +    List ff1 = d1.getFields();
    +    List ff2 = d2.getFields();
     
         Collections.sort(ff1, fieldNameComparator);
         Collections.sort(ff2, fieldNameComparator);
    @@ -517,10 +522,10 @@
         assertEquals(ff1 + " : " + ff2, ff1.size(), ff2.size());
     
         for (int i=0; i fields = new ArrayList();      
           String idString = getIdString();
    -      Field idField =  newField("id", idString, Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS);
    +      Field idField =  newField("id", idString, customType1);
           fields.add(idField);
     
           int nFields = nextInt(maxFields);
           for (int i=0; i it = doc.getFields().iterator();
    +    Document doc2 = r.document(0);
    +    Iterator it = doc2.getFields().iterator();
         assertTrue(it.hasNext());
         Field f = (Field) it.next();
         assertEquals(f.name(), "zzz");
    @@ -1322,7 +1362,7 @@
           s.append(' ').append(i);
         }
         Document d = new Document();
    -    Field f = newField("field", s.toString(), Field.Store.NO, Field.Index.ANALYZED);
    +    Field f = newField("field", s.toString(), TextField.TYPE_UNSTORED);
         d.add(f);
         w.addDocument(d);
     
    @@ -1354,7 +1394,7 @@
                   setMergePolicy(mergePolicy)
           );
           Document doc = new Document();
    -      doc.add(newField("field", "go", Field.Store.NO, Field.Index.ANALYZED));
    +      doc.add(newField("field", "go", TextField.TYPE_UNSTORED));
           w.addDocument(doc);
           IndexReader r;
           if (iter == 0) {
    @@ -1422,7 +1462,14 @@
     
         // First commit
         Document doc = new Document();
    -    doc.add(newField("c", "val", Store.YES, Index.ANALYZED, TermVector.WITH_POSITIONS_OFFSETS));
    +
    +    FieldType customType = new FieldType(TextField.TYPE_UNSTORED);
    +    customType.setStored(true);
    +    customType.setStoreTermVectors(true);
    +    customType.setStoreTermVectorPositions(true);
    +    customType.setStoreTermVectorOffsets(true);
    +    
    +    doc.add(newField("c", "val", customType));
         writer.addDocument(doc);
         writer.commit();
         assertEquals(1, IndexReader.listCommits(dir).size());
    @@ -1432,7 +1479,7 @@
     
         // Second commit - now KeepOnlyLastCommit cannot delete the prev commit.
         doc = new Document();
    -    doc.add(newField("c", "val", Store.YES, Index.ANALYZED, TermVector.WITH_POSITIONS_OFFSETS));
    +    doc.add(newField("c", "val", customType));
         writer.addDocument(doc);
         writer.commit();
         assertEquals(2, IndexReader.listCommits(dir).size());
    @@ -1479,14 +1526,19 @@
         }
     
         Document doc = new Document();
    +    FieldType customType = new FieldType(TextField.TYPE_UNSTORED);
    +    customType.setStored(true);
    +    customType.setStoreTermVectors(true);
    +    customType.setStoreTermVectorPositions(true);
    +    customType.setStoreTermVectorOffsets(true);
         // create as many files as possible
    -    doc.add(newField("c", "val", Store.YES, Index.ANALYZED, TermVector.WITH_POSITIONS_OFFSETS));
    +    doc.add(newField("c", "val", customType));
         writer.addDocument(doc);
         // Adding just one document does not call flush yet.
         assertEquals("only the stored and term vector files should exist in the directory", 5 + extraFileCount, dir.listAll().length);
     
         doc = new Document();
    -    doc.add(newField("c", "val", Store.YES, Index.ANALYZED, TermVector.WITH_POSITIONS_OFFSETS));
    +    doc.add(newField("c", "val", customType));
         writer.addDocument(doc);
     
         // The second document should cause a flush.
    @@ -1509,7 +1561,12 @@
             TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMaxBufferedDocs(2));
     
         Document doc = new Document();
    -    doc.add(newField("c", "val", Store.YES, Index.ANALYZED, TermVector.WITH_POSITIONS_OFFSETS));
    +    FieldType customType = new FieldType(TextField.TYPE_UNSTORED);
    +    customType.setStored(true);
    +    customType.setStoreTermVectors(true);
    +    customType.setStoreTermVectorPositions(true);
    +    customType.setStoreTermVectorOffsets(true);
    +    doc.add(newField("c", "val", customType));
         w.addDocument(doc);
         w.addDocument(doc);
         IndexWriter w2 = new IndexWriter(dir, newIndexWriterConfig(
    @@ -1536,7 +1593,10 @@
     
         final List fieldIDs = new ArrayList();
     
    -    Field idField = newField("id", "", Field.Store.YES, Field.Index.NOT_ANALYZED);
    +    FieldType customType = new FieldType(TextField.TYPE_UNSTORED);
    +    customType.setStored(true);
    +    customType.setTokenized(false);
    +    Field idField = newField("id", "", customType);
     
         for(int i=0;i loadFieldNames = new HashSet();
    -    loadFieldNames.add(DocHelper.TEXT_FIELD_1_KEY);
    -    loadFieldNames.add(DocHelper.TEXT_FIELD_UTF1_KEY);
    -    Set lazyFieldNames = new HashSet();
    -    //new String[]{DocHelper.LARGE_LAZY_FIELD_KEY, DocHelper.LAZY_FIELD_KEY, DocHelper.LAZY_FIELD_BINARY_KEY};
    -    lazyFieldNames.add(DocHelper.LARGE_LAZY_FIELD_KEY);
    -    lazyFieldNames.add(DocHelper.LAZY_FIELD_KEY);
    -    lazyFieldNames.add(DocHelper.LAZY_FIELD_BINARY_KEY);
    -    lazyFieldNames.add(DocHelper.TEXT_FIELD_UTF2_KEY);
    -    SetBasedFieldSelector fieldSelector = new SetBasedFieldSelector(loadFieldNames, lazyFieldNames);
    -    Document doc = reader.doc(0, fieldSelector);
    -    assertTrue("doc is null and it shouldn't be", doc != null);
    -    Fieldable field = doc.getFieldable(DocHelper.LAZY_FIELD_KEY);
    -    assertTrue("field is null and it shouldn't be", field != null);
    -    assertTrue("field is not lazy and it should be", field.isLazy());
    -    String value = field.stringValue();
    -    assertTrue("value is null and it shouldn't be", value != null);
    -    assertTrue(value + " is not equal to " + DocHelper.LAZY_FIELD_TEXT, value.equals(DocHelper.LAZY_FIELD_TEXT) == true);
    -    assertTrue("calling stringValue() twice should give same reference", field.stringValue() == field.stringValue());
    -
    -    field = doc.getFieldable(DocHelper.TEXT_FIELD_1_KEY);
    -    assertTrue("field is null and it shouldn't be", field != null);
    -    assertTrue("Field is lazy and it should not be", field.isLazy() == false);
    -    field = doc.getFieldable(DocHelper.TEXT_FIELD_UTF1_KEY);
    -    assertTrue("field is null and it shouldn't be", field != null);
    -    assertTrue("Field is lazy and it should not be", field.isLazy() == false);
    -    assertTrue(field.stringValue() + " is not equal to " + DocHelper.FIELD_UTF1_TEXT, field.stringValue().equals(DocHelper.FIELD_UTF1_TEXT) == true);
    -
    -    field = doc.getFieldable(DocHelper.TEXT_FIELD_UTF2_KEY);
    -    assertTrue("field is null and it shouldn't be", field != null);
    -    assertTrue("Field is lazy and it should not be", field.isLazy() == true);
    -    assertTrue(field.stringValue() + " is not equal to " + DocHelper.FIELD_UTF2_TEXT, field.stringValue().equals(DocHelper.FIELD_UTF2_TEXT) == true);
    -
    -    field = doc.getFieldable(DocHelper.LAZY_FIELD_BINARY_KEY);
    -    assertTrue("field is null and it shouldn't be", field != null);
    -    assertTrue("stringValue isn't null for lazy binary field", field.stringValue() == null);
    -
    -    byte [] bytes = field.getBinaryValue();
    -    assertTrue("bytes is null and it shouldn't be", bytes != null);
    -    assertTrue("", DocHelper.LAZY_FIELD_BINARY_BYTES.length == bytes.length);
    -    assertTrue("calling binaryValue() twice should give same reference", field.getBinaryValue() == field.getBinaryValue());
    -    for (int i = 0; i < bytes.length; i++) {
    -      assertTrue("byte[" + i + "] is mismatched", bytes[i] == DocHelper.LAZY_FIELD_BINARY_BYTES[i]);
    -
    -    }
    +    DocumentStoredFieldVisitor visitor = new DocumentStoredFieldVisitor(DocHelper.TEXT_FIELD_3_KEY);
    +    reader.document(0, visitor);
    +    final List fields = visitor.getDocument().getFields();
    +    assertEquals(1, fields.size());
    +    assertEquals(DocHelper.TEXT_FIELD_3_KEY, fields.get(0).name());
         reader.close();
       }
     
    -  public void testLatentFields() throws Exception {
    -    assertTrue(dir != null);
    -    assertTrue(fieldInfos != null);
    -    FieldsReader reader = new FieldsReader(dir, TEST_SEGMENT_NAME, fieldInfos);
    -    assertTrue(reader.size() == 1);
    -    Set loadFieldNames = new HashSet();
    -    loadFieldNames.add(DocHelper.TEXT_FIELD_1_KEY);
    -    loadFieldNames.add(DocHelper.TEXT_FIELD_UTF1_KEY);
    -    Set lazyFieldNames = new HashSet();
    -    //new String[]{DocHelper.LARGE_LAZY_FIELD_KEY, DocHelper.LAZY_FIELD_KEY, DocHelper.LAZY_FIELD_BINARY_KEY};
    -    lazyFieldNames.add(DocHelper.LARGE_LAZY_FIELD_KEY);
    -    lazyFieldNames.add(DocHelper.LAZY_FIELD_KEY);
    -    lazyFieldNames.add(DocHelper.LAZY_FIELD_BINARY_KEY);
    -    lazyFieldNames.add(DocHelper.TEXT_FIELD_UTF2_KEY);
     
    -    // Use LATENT instead of LAZY
    -    SetBasedFieldSelector fieldSelector = new SetBasedFieldSelector(loadFieldNames, lazyFieldNames) {
    -        @Override
    -        public FieldSelectorResult accept(String fieldName) {
    -          final FieldSelectorResult result = super.accept(fieldName);
    -          if (result == FieldSelectorResult.LAZY_LOAD) {
    -            return FieldSelectorResult.LATENT;
    -          } else {
    -            return result;
    -          }
    -        }
    -      };
    -
    -    Document doc = reader.doc(0, fieldSelector);
    -    assertTrue("doc is null and it shouldn't be", doc != null);
    -    Fieldable field = doc.getFieldable(DocHelper.LAZY_FIELD_KEY);
    -    assertTrue("field is null and it shouldn't be", field != null);
    -    assertTrue("field is not lazy and it should be", field.isLazy());
    -    String value = field.stringValue();
    -    assertTrue("value is null and it shouldn't be", value != null);
    -    assertTrue(value + " is not equal to " + DocHelper.LAZY_FIELD_TEXT, value.equals(DocHelper.LAZY_FIELD_TEXT) == true);
    -    assertTrue("calling stringValue() twice should give different references", field.stringValue() != field.stringValue());
    -
    -    field = doc.getFieldable(DocHelper.TEXT_FIELD_1_KEY);
    -    assertTrue("field is null and it shouldn't be", field != null);
    -    assertTrue("Field is lazy and it should not be", field.isLazy() == false);
    -    assertTrue("calling stringValue() twice should give same reference", field.stringValue() == field.stringValue());
    -
    -    field = doc.getFieldable(DocHelper.TEXT_FIELD_UTF1_KEY);
    -    assertTrue("field is null and it shouldn't be", field != null);
    -    assertTrue("Field is lazy and it should not be", field.isLazy() == false);
    -    assertTrue(field.stringValue() + " is not equal to " + DocHelper.FIELD_UTF1_TEXT, field.stringValue().equals(DocHelper.FIELD_UTF1_TEXT) == true);
    -    assertTrue("calling stringValue() twice should give same reference", field.stringValue() == field.stringValue());
    -
    -    field = doc.getFieldable(DocHelper.TEXT_FIELD_UTF2_KEY);
    -    assertTrue("field is null and it shouldn't be", field != null);
    -    assertTrue("Field is lazy and it should not be", field.isLazy() == true);
    -    assertTrue(field.stringValue() + " is not equal to " + DocHelper.FIELD_UTF2_TEXT, field.stringValue().equals(DocHelper.FIELD_UTF2_TEXT) == true);
    -    assertTrue("calling stringValue() twice should give different references", field.stringValue() != field.stringValue());
    -
    -    field = doc.getFieldable(DocHelper.LAZY_FIELD_BINARY_KEY);
    -    assertTrue("field is null and it shouldn't be", field != null);
    -    assertTrue("stringValue isn't null for lazy binary field", field.stringValue() == null);
    -    assertTrue("calling binaryValue() twice should give different references", field.getBinaryValue() != field.getBinaryValue());
    -
    -    byte [] bytes = field.getBinaryValue();
    -    assertTrue("bytes is null and it shouldn't be", bytes != null);
    -    assertTrue("", DocHelper.LAZY_FIELD_BINARY_BYTES.length == bytes.length);
    -    for (int i = 0; i < bytes.length; i++) {
    -      assertTrue("byte[" + i + "] is mismatched", bytes[i] == DocHelper.LAZY_FIELD_BINARY_BYTES[i]);
    -
    -    }
    -    reader.close();
    -  }
    -
    -
    -
    -
    -  public void testLazyFieldsAfterClose() throws Exception {
    -    assertTrue(dir != null);
    -    assertTrue(fieldInfos != null);
    -    FieldsReader reader = new FieldsReader(dir, TEST_SEGMENT_NAME, fieldInfos);
    -    assertTrue(reader.size() == 1);
    -    Set loadFieldNames = new HashSet();
    -    loadFieldNames.add(DocHelper.TEXT_FIELD_1_KEY);
    -    loadFieldNames.add(DocHelper.TEXT_FIELD_UTF1_KEY);
    -    Set lazyFieldNames = new HashSet();
    -    lazyFieldNames.add(DocHelper.LARGE_LAZY_FIELD_KEY);
    -    lazyFieldNames.add(DocHelper.LAZY_FIELD_KEY);
    -    lazyFieldNames.add(DocHelper.LAZY_FIELD_BINARY_KEY);
    -    lazyFieldNames.add(DocHelper.TEXT_FIELD_UTF2_KEY);
    -    SetBasedFieldSelector fieldSelector = new SetBasedFieldSelector(loadFieldNames, lazyFieldNames);
    -    Document doc = reader.doc(0, fieldSelector);
    -    assertTrue("doc is null and it shouldn't be", doc != null);
    -    Fieldable field = doc.getFieldable(DocHelper.LAZY_FIELD_KEY);
    -    assertTrue("field is null and it shouldn't be", field != null);
    -    assertTrue("field is not lazy and it should be", field.isLazy());
    -    reader.close();
    -    try {
    -      field.stringValue();
    -      fail("did not hit AlreadyClosedException as expected");
    -    } catch (AlreadyClosedException e) {
    -      // expected
    -    }
    -  }
    -
    -  public void testLoadFirst() throws Exception {
    -    assertTrue(dir != null);
    -    assertTrue(fieldInfos != null);
    -    FieldsReader reader = new FieldsReader(dir, TEST_SEGMENT_NAME, fieldInfos);
    -    assertTrue(reader.size() == 1);
    -    LoadFirstFieldSelector fieldSelector = new LoadFirstFieldSelector();
    -    Document doc = reader.doc(0, fieldSelector);
    -    assertTrue("doc is null and it shouldn't be", doc != null);
    -    int count = 0;
    -    List l = doc.getFields();
    -    for (final Fieldable fieldable : l ) {
    -      Field field = (Field) fieldable;
    -
    -      assertTrue("field is null and it shouldn't be", field != null);
    -      String sv = field.stringValue();
    -      assertTrue("sv is null and it shouldn't be", sv != null);
    -      count++;
    -    }
    -    assertTrue(count + " does not equal: " + 1, count == 1);
    -    reader.close();
    -  }
    -
    -  /**
    -   * Not really a test per se, but we should have some way of assessing whether this is worthwhile.
    -   * 

    - * Must test using a File based directory - * - * @throws Exception - */ - public void testLazyPerformance() throws Exception { - String userName = System.getProperty("user.name"); - File file = _TestUtil.getTempDir("lazyDir" + userName); - Directory tmpDir = newFSDirectory(file); - assertTrue(tmpDir != null); - - IndexWriterConfig conf = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setOpenMode(OpenMode.CREATE).setMergePolicy(newLogMergePolicy()); - ((LogMergePolicy) conf.getMergePolicy()).setUseCompoundFile(false); - IndexWriter writer = new IndexWriter(tmpDir, conf); - writer.addDocument(testDoc); - writer.close(); - - assertTrue(fieldInfos != null); - FieldsReader reader; - long lazyTime = 0; - long regularTime = 0; - int length = 10; - Set lazyFieldNames = new HashSet(); - lazyFieldNames.add(DocHelper.LARGE_LAZY_FIELD_KEY); - SetBasedFieldSelector fieldSelector = new SetBasedFieldSelector(Collections. emptySet(), lazyFieldNames); - - for (int i = 0; i < length; i++) { - reader = new FieldsReader(tmpDir, TEST_SEGMENT_NAME, fieldInfos); - assertTrue(reader.size() == 1); - - Document doc; - doc = reader.doc(0, null);//Load all of them - assertTrue("doc is null and it shouldn't be", doc != null); - Fieldable field = doc.getFieldable(DocHelper.LARGE_LAZY_FIELD_KEY); - assertTrue("field is null and it shouldn't be", field != null); - assertTrue("field is lazy", field.isLazy() == false); - String value; - long start; - long finish; - start = System.currentTimeMillis(); - //On my machine this was always 0ms. - value = field.stringValue(); - finish = System.currentTimeMillis(); - assertTrue("value is null and it shouldn't be", value != null); - regularTime += (finish - start); - reader.close(); - reader = null; - doc = null; - //Hmmm, are we still in cache??? - System.gc(); - reader = new FieldsReader(tmpDir, TEST_SEGMENT_NAME, fieldInfos); - doc = reader.doc(0, fieldSelector); - field = doc.getFieldable(DocHelper.LARGE_LAZY_FIELD_KEY); - assertTrue("field is not lazy", field.isLazy() == true); - start = System.currentTimeMillis(); - //On my machine this took around 50 - 70ms - value = field.stringValue(); - finish = System.currentTimeMillis(); - assertTrue("value is null and it shouldn't be", value != null); - lazyTime += (finish - start); - reader.close(); - - } - tmpDir.close(); - if (VERBOSE) { - System.out.println("Average Non-lazy time (should be very close to zero): " + regularTime / length + " ms for " + length + " reads"); - System.out.println("Average Lazy Time (should be greater than zero): " + lazyTime / length + " ms for " + length + " reads"); - } - } - - public void testLoadSize() throws IOException { - FieldsReader reader = new FieldsReader(dir, TEST_SEGMENT_NAME, fieldInfos); - Document doc; - - doc = reader.doc(0, new FieldSelector(){ - public FieldSelectorResult accept(String fieldName) { - if (fieldName.equals(DocHelper.TEXT_FIELD_1_KEY) || - fieldName.equals(DocHelper.LAZY_FIELD_BINARY_KEY)) - return FieldSelectorResult.SIZE; - else if (fieldName.equals(DocHelper.TEXT_FIELD_3_KEY)) - return FieldSelectorResult.LOAD; - else - return FieldSelectorResult.NO_LOAD; - } - }); - Fieldable f1 = doc.getFieldable(DocHelper.TEXT_FIELD_1_KEY); - Fieldable f3 = doc.getFieldable(DocHelper.TEXT_FIELD_3_KEY); - Fieldable fb = doc.getFieldable(DocHelper.LAZY_FIELD_BINARY_KEY); - assertTrue(f1.isBinary()); - assertTrue(!f3.isBinary()); - assertTrue(fb.isBinary()); - assertSizeEquals(2*DocHelper.FIELD_1_TEXT.length(), f1.getBinaryValue()); - assertEquals(DocHelper.FIELD_3_TEXT, f3.stringValue()); - assertSizeEquals(DocHelper.LAZY_FIELD_BINARY_BYTES.length, fb.getBinaryValue()); - - reader.close(); - } - - private void assertSizeEquals(int size, byte[] sizebytes) { - assertEquals((byte) (size>>>24), sizebytes[0]); - assertEquals((byte) (size>>>16), sizebytes[1]); - assertEquals((byte) (size>>> 8), sizebytes[2]); - assertEquals((byte) size , sizebytes[3]); - } - public static class FaultyFSDirectory extends Directory { Directory fsDir; @@ -528,7 +239,7 @@ final NumericField.DataType[] typeAnswers = new NumericField.DataType[numDocs]; for(int id=0;id files = writer.getIndexFileNames(); @@ -115,6 +112,8 @@ public void testIndexReaderCommit() throws IOException { int num = atLeast(3); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); for (int i = 0; i < num; i++) { Directory dir = newDirectory(); { @@ -122,17 +121,14 @@ new MockAnalyzer(random)); IndexWriter writer = new IndexWriter(dir, config); Document d = new Document(); - d.add(new Field("f1", "d1 first field", Store.YES, Index.ANALYZED, - TermVector.NO)); - d.add(new Field("f2", "d1 second field", Store.YES, Index.ANALYZED, - TermVector.NO)); + d.add(new Field("f1", customType, "d1 first field")); + d.add(new Field("f2", customType, "d1 second field")); writer.addDocument(d); writer.commit(); assertFNXFiles(dir, "1.fnx"); d = new Document(); - d.add(new Field("f1", "d2 first field", Store.YES, Index.ANALYZED, - TermVector.NO)); - d.add(new Field("f3", new byte[] { 1, 2, 3 })); + d.add(new Field("f1", customType, "d2 first field")); + d.add(new BinaryField("f3", new byte[] { 1, 2, 3 })); writer.addDocument(d); writer.commit(); assertFNXFiles(dir, "2.fnx"); @@ -159,6 +155,8 @@ public void testGlobalFieldNumberFilesAcrossCommits() throws IOException { int num = atLeast(3); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); for (int i = 0; i < num; i++) { Directory dir = newDirectory(); { @@ -166,17 +164,14 @@ TEST_VERSION_CURRENT, new MockAnalyzer(random)).setIndexDeletionPolicy( new KeepAllDeletionPolicy())); Document d = new Document(); - d.add(new Field("f1", "d1 first field", Store.YES, Index.ANALYZED, - TermVector.NO)); - d.add(new Field("f2", "d1 second field", Store.YES, Index.ANALYZED, - TermVector.NO)); + d.add(new Field("f1", customType, "d1 first field")); + d.add(new Field("f2", customType, "d1 second field")); writer.addDocument(d); writer.commit(); assertFNXFiles(dir, "1.fnx"); d = new Document(); - d.add(new Field("f1", "d2 first field", Store.YES, Index.ANALYZED, - TermVector.NO)); - d.add(new Field("f3", new byte[] { 1, 2, 3 })); + d.add(new Field("f1", customType, "d2 first field")); + d.add(new BinaryField("f3", new byte[] { 1, 2, 3 })); writer.addDocument(d); writer.commit(); writer.commit(); @@ -190,11 +185,9 @@ IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random))); Document d = new Document(); - d.add(new Field("f1", "d3 first field", Store.YES, Index.ANALYZED, - TermVector.NO)); - d.add(new Field("f2", "d3 second field", Store.YES, Index.ANALYZED, - TermVector.NO)); - d.add(new Field("f3", new byte[] { 1, 2, 3, 4, 5 })); + d.add(new Field("f1", customType, "d3 first field")); + d.add(new Field("f2", customType, "d3 second field")); + d.add(new BinaryField("f3", new byte[] { 1, 2, 3, 4, 5 })); writer.addDocument(d); writer.close(); assertFNXFiles(dir, "2.fnx"); @@ -211,23 +204,22 @@ public void testGlobalFieldNumberOnOldCommit() throws IOException { int num = atLeast(3); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); for (int i = 0; i < num; i++) { Directory dir = newDirectory(); IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random)).setIndexDeletionPolicy( new KeepAllDeletionPolicy())); Document d = new Document(); - d.add(new Field("f1", "d1 first field", Store.YES, Index.ANALYZED, - TermVector.NO)); - d.add(new Field("f2", "d1 second field", Store.YES, Index.ANALYZED, - TermVector.NO)); + d.add(new Field("f1", customType, "d1 first field")); + d.add(new Field("f2", customType, "d1 second field")); writer.addDocument(d); writer.commit(); assertFNXFiles(dir, "1.fnx"); d = new Document(); - d.add(new Field("f1", "d2 first field", Store.YES, Index.ANALYZED, - TermVector.NO)); - d.add(new Field("f3", new byte[] { 1, 2, 3 })); + d.add(new Field("f1", customType, "d2 first field")); + d.add(new BinaryField("f3", new byte[] { 1, 2, 3 })); writer.addDocument(d); assertFNXFiles(dir, "1.fnx"); writer.close(); @@ -240,9 +232,8 @@ new KeepAllDeletionPolicy()).setIndexCommit(listCommits.get(0))); d = new Document(); - d.add(new Field("f1", "d2 first field", Store.YES, Index.ANALYZED, - TermVector.NO)); - d.add(new Field("f3", new byte[] { 1, 2, 3 })); + d.add(new Field("f1", customType, "d2 first field")); + d.add(new BinaryField("f3", new byte[] { 1, 2, 3 })); writer.addDocument(d); writer.commit(); // now we have 3 files since f3 is not present in the first commit @@ -271,9 +262,13 @@ Document doc = new Document(); final int numFields = 1 + random.nextInt(fieldNames.length); for (int j = 0; j < numFields; j++) { + FieldType customType = new FieldType(); + customType.setIndexed(true); + customType.setTokenized(random.nextBoolean()); + customType.setOmitNorms(random.nextBoolean()); doc.add(newField(fieldNames[random.nextInt(fieldNames.length)], _TestUtil.randomRealisticUnicodeString(random), - Index.toIndex(true, random.nextBoolean(), random.nextBoolean()))); + customType)); } writer.addDocument(doc); @@ -322,9 +317,13 @@ TEST_VERSION_CURRENT, new MockAnalyzer(random))); Document doc = new Document(); for (String string : fieldNames) { + FieldType customType = new FieldType(); + customType.setIndexed(true); + customType.setTokenized(random.nextBoolean()); + customType.setOmitNorms(random.nextBoolean()); doc.add(newField(string, _TestUtil.randomRealisticUnicodeString(random), - Index.toIndex(true, random.nextBoolean(), random.nextBoolean()))); + customType)); } writer.addDocument(doc); @@ -419,8 +418,12 @@ String name = copySortedMap.get(nextField); assertNotNull(name); + FieldType customType = new FieldType(); + customType.setIndexed(true); + customType.setTokenized(random.nextBoolean()); + customType.setOmitNorms(random.nextBoolean()); doc.add(newField(name, _TestUtil.randomRealisticUnicodeString(random), - Index.toIndex(true, random.nextBoolean(), random.nextBoolean()))); + customType)); writer.addDocument(doc); if (random.nextInt(10) == 0) { writer.commit(); @@ -480,8 +483,9 @@ } Document d = new Document(); - d.add(new Field("f1", "d1 first field", Store.YES, Index.ANALYZED, - TermVector.NO)); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + d.add(new Field("f1", customType, "d1 first field")); writer.addDocument(d); writer.prepareCommit(); // the fnx file should still be under control of the SIS Index: lucene/src/test/org/apache/lucene/index/TestSegmentTermDocs.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestSegmentTermDocs.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestSegmentTermDocs.java (working copy) @@ -22,7 +22,7 @@ import org.apache.lucene.store.IOContext; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; +import org.apache.lucene.document.TextField; import org.apache.lucene.util.BytesRef; import java.io.IOException; @@ -261,7 +261,7 @@ private void addDoc(IndexWriter writer, String value) throws IOException { Document doc = new Document(); - doc.add(newField("content", value, Field.Store.NO, Field.Index.ANALYZED)); + doc.add(newField("content", value, TextField.TYPE_UNSTORED)); writer.addDocument(doc); } } Index: lucene/src/test/org/apache/lucene/index/TestCheckIndex.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestCheckIndex.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestCheckIndex.java (working copy) @@ -28,6 +28,8 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.util.Constants; public class TestCheckIndex extends LuceneTestCase { @@ -36,7 +38,12 @@ Directory dir = newDirectory(); IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMaxBufferedDocs(2)); Document doc = new Document(); - doc.add(newField("field", "aaa", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + customType.setStoreTermVectors(true); + customType.setStoreTermVectorPositions(true); + customType.setStoreTermVectorOffsets(true); + doc.add(newField("field", "aaa", customType)); for(int i=0;i<19;i++) { writer.addDocument(doc); } Index: lucene/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java (working copy) @@ -34,6 +34,9 @@ import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.StringField; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriterConfig.OpenMode; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.IndexSearcher; @@ -54,7 +57,37 @@ private static class DocCopyIterator implements Iterable { private final Document doc; private final int count; + + /* private field types */ + /* private field types */ + private static final FieldType custom1 = new FieldType(TextField.TYPE_UNSTORED); + private static final FieldType custom2 = new FieldType(); + private static final FieldType custom3 = new FieldType(); + private static final FieldType custom4 = new FieldType(StringField.TYPE_UNSTORED); + private static final FieldType custom5 = new FieldType(TextField.TYPE_UNSTORED); + + static { + + custom1.setStoreTermVectors(true); + custom1.setStoreTermVectorPositions(true); + custom1.setStoreTermVectorOffsets(true); + + custom2.setStored(true); + custom2.setIndexed(true); + + custom3.setStored(true); + + custom4.setStoreTermVectors(true); + custom4.setStoreTermVectorPositions(true); + custom4.setStoreTermVectorOffsets(true); + + custom5.setStored(true); + custom5.setStoreTermVectors(true); + custom5.setStoreTermVectorPositions(true); + custom5.setStoreTermVectorOffsets(true); + } + public DocCopyIterator(Document doc, int count) { this.count = count; this.doc = doc; @@ -101,17 +134,17 @@ final Document doc = new Document(); - doc.add(newField("content1", "aaa bbb ccc ddd", Field.Store.YES, Field.Index.ANALYZED)); - doc.add(newField("content6", "aaa bbb ccc ddd", Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); - doc.add(newField("content2", "aaa bbb ccc ddd", Field.Store.YES, Field.Index.NOT_ANALYZED)); - doc.add(newField("content3", "aaa bbb ccc ddd", Field.Store.YES, Field.Index.NO)); + doc.add(newField("content1", "aaa bbb ccc ddd", TextField.TYPE_STORED)); + doc.add(newField("content6", "aaa bbb ccc ddd", DocCopyIterator.custom1)); + doc.add(newField("content2", "aaa bbb ccc ddd", DocCopyIterator.custom2)); + doc.add(newField("content3", "aaa bbb ccc ddd", DocCopyIterator.custom3)); - doc.add(newField("content4", "aaa bbb ccc ddd", Field.Store.NO, Field.Index.ANALYZED)); - doc.add(newField("content5", "aaa bbb ccc ddd", Field.Store.NO, Field.Index.NOT_ANALYZED)); + doc.add(newField("content4", "aaa bbb ccc ddd", TextField.TYPE_UNSTORED)); + doc.add(newField("content5", "aaa bbb ccc ddd", StringField.TYPE_UNSTORED)); - doc.add(newField("content7", "aaa bbb ccc ddd", Field.Store.NO, Field.Index.NOT_ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); + doc.add(newField("content7", "aaa bbb ccc ddd", DocCopyIterator.custom4)); - final Field idField = newField("id", "", Field.Store.YES, Field.Index.NOT_ANALYZED); + final Field idField = newField("id", "", DocCopyIterator.custom2); doc.add(idField); final long stopTime = System.currentTimeMillis() + 500; @@ -337,8 +370,7 @@ MockIndexWriter2 w = new MockIndexWriter2(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random))); w.setInfoStream(VERBOSE ? System.out : null); Document doc = new Document(); - doc.add(newField("field", "a field", Field.Store.YES, - Field.Index.ANALYZED)); + doc.add(newField("field", "a field", TextField.TYPE_STORED)); w.addDocument(doc); w.doFail = true; try { @@ -357,8 +389,7 @@ MockIndexWriter w = new MockIndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMaxBufferedDocs(2)); w.setInfoStream(VERBOSE ? System.out : null); Document doc = new Document(); - doc.add(newField("field", "a field", Field.Store.YES, - Field.Index.ANALYZED)); + doc.add(newField("field", "a field", TextField.TYPE_STORED)); w.addDocument(doc); Analyzer analyzer = new Analyzer() { @@ -371,8 +402,7 @@ }; Document crashDoc = new Document(); - crashDoc.add(newField("crash", "do it on token 4", Field.Store.YES, - Field.Index.ANALYZED)); + crashDoc.add(newField("crash", "do it on token 4", TextField.TYPE_STORED)); try { w.addDocument(crashDoc, analyzer); fail("did not hit expected exception"); @@ -413,8 +443,7 @@ MockIndexWriter3 w = new MockIndexWriter3(dir, conf); w.doFail = true; Document doc = new Document(); - doc.add(newField("field", "a field", Field.Store.YES, - Field.Index.ANALYZED)); + doc.add(newField("field", "a field", TextField.TYPE_STORED)); for(int i=0;i<10;i++) try { w.addDocument(doc); @@ -457,8 +486,7 @@ Document doc = new Document(); String contents = "aa bb cc dd ee ff gg hh ii jj kk"; - doc.add(newField("content", contents, Field.Store.NO, - Field.Index.ANALYZED)); + doc.add(newField("content", contents, TextField.TYPE_UNSTORED)); try { writer.addDocument(doc); fail("did not hit expected exception"); @@ -467,14 +495,12 @@ // Make sure we can add another normal document doc = new Document(); - doc.add(newField("content", "aa bb cc dd", Field.Store.NO, - Field.Index.ANALYZED)); + doc.add(newField("content", "aa bb cc dd", TextField.TYPE_UNSTORED)); writer.addDocument(doc); // Make sure we can add another normal document doc = new Document(); - doc.add(newField("content", "aa bb cc dd", Field.Store.NO, - Field.Index.ANALYZED)); + doc.add(newField("content", "aa bb cc dd", TextField.TYPE_UNSTORED)); writer.addDocument(doc); writer.close(); @@ -545,8 +571,7 @@ IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMaxBufferedDocs(2)); Document doc = new Document(); String contents = "aa bb cc dd ee ff gg hh ii jj kk"; - doc.add(newField("content", contents, Field.Store.NO, - Field.Index.ANALYZED)); + doc.add(newField("content", contents, TextField.TYPE_UNSTORED)); boolean hitError = false; for(int i=0;i<200;i++) { try { @@ -589,14 +614,11 @@ lmp.setMergeFactor(Math.max(lmp.getMergeFactor(), 5)); Document doc = new Document(); - doc.add(newField("contents", "here are some contents", Field.Store.YES, - Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); + doc.add(newField("contents", "here are some contents", DocCopyIterator.custom5)); writer.addDocument(doc); writer.addDocument(doc); - doc.add(newField("crash", "this should crash after 4 terms", Field.Store.YES, - Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); - doc.add(newField("other", "this will not get indexed", Field.Store.YES, - Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); + doc.add(newField("crash", "this should crash after 4 terms", DocCopyIterator.custom5)); + doc.add(newField("other", "this will not get indexed", DocCopyIterator.custom5)); try { writer.addDocument(doc); fail("did not hit expected exception"); @@ -609,8 +631,7 @@ if (0 == i) { doc = new Document(); - doc.add(newField("contents", "here are some contents", Field.Store.YES, - Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); + doc.add(newField("contents", "here are some contents", DocCopyIterator.custom5)); writer.addDocument(doc); writer.addDocument(doc); } @@ -642,8 +663,7 @@ writer = new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, analyzer).setMaxBufferedDocs(10)); doc = new Document(); - doc.add(newField("contents", "here are some contents", Field.Store.YES, - Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); + doc.add(newField("contents", "here are some contents", DocCopyIterator.custom5)); for(int j=0;j<17;j++) writer.addDocument(doc); writer.optimize(); @@ -699,14 +719,11 @@ try { for(int iter=0;iter docIDs = new ArrayList(); final SubDocs subDocs = new SubDocs(packID, docIDs); final List docsList = new ArrayList(); Index: lucene/src/test/org/apache/lucene/index/TestOmitPositions.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestOmitPositions.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestOmitPositions.java (working copy) @@ -21,6 +21,8 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.FieldInfo.IndexOptions; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.store.Directory; @@ -37,8 +39,9 @@ Directory dir = newDirectory(); RandomIndexWriter w = new RandomIndexWriter(random, dir); Document doc = new Document(); - Field f = newField("foo", "this is a test test", Field.Index.ANALYZED); - f.setIndexOptions(IndexOptions.DOCS_AND_FREQS); + FieldType ft = new FieldType(TextField.TYPE_UNSTORED); + ft.setIndexOptions(IndexOptions.DOCS_AND_FREQS); + Field f = newField("foo", "this is a test test", ft); doc.add(f); for (int i = 0; i < 100; i++) { w.addDocument(doc); @@ -67,42 +70,42 @@ Document d = new Document(); // f1,f2,f3: docs only - Field f1 = newField("f1", "This field has docs only", Field.Store.NO, Field.Index.ANALYZED); - f1.setIndexOptions(IndexOptions.DOCS_ONLY); + FieldType ft = new FieldType(TextField.TYPE_UNSTORED); + ft.setIndexOptions(IndexOptions.DOCS_ONLY); + + Field f1 = newField("f1", "This field has docs only", ft); d.add(f1); - Field f2 = newField("f2", "This field has docs only", Field.Store.NO, Field.Index.ANALYZED); - f2.setIndexOptions(IndexOptions.DOCS_ONLY); + Field f2 = newField("f2", "This field has docs only", ft); d.add(f2); - Field f3 = newField("f3", "This field has docs only", Field.Store.NO, Field.Index.ANALYZED); - f3.setIndexOptions(IndexOptions.DOCS_ONLY); + Field f3 = newField("f3", "This field has docs only", ft); d.add(f3); + + FieldType ft2 = new FieldType(TextField.TYPE_UNSTORED); + ft2.setIndexOptions(IndexOptions.DOCS_AND_FREQS); // f4,f5,f6 docs and freqs - Field f4 = newField("f4", "This field has docs and freqs", Field.Store.NO, Field.Index.ANALYZED); - f4.setIndexOptions(IndexOptions.DOCS_AND_FREQS); + Field f4 = newField("f4", "This field has docs and freqs", ft2); d.add(f4); - Field f5 = newField("f5", "This field has docs and freqs", Field.Store.NO, Field.Index.ANALYZED); - f5.setIndexOptions(IndexOptions.DOCS_AND_FREQS); + Field f5 = newField("f5", "This field has docs and freqs", ft2); d.add(f5); - Field f6 = newField("f6", "This field has docs and freqs", Field.Store.NO, Field.Index.ANALYZED); - f6.setIndexOptions(IndexOptions.DOCS_AND_FREQS); + Field f6 = newField("f6", "This field has docs and freqs", ft2); d.add(f6); + FieldType ft3 = new FieldType(TextField.TYPE_UNSTORED); + ft3.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS); + // f7,f8,f9 docs/freqs/positions - Field f7 = newField("f7", "This field has docs and freqs and positions", Field.Store.NO, Field.Index.ANALYZED); - f7.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS); + Field f7 = newField("f7", "This field has docs and freqs and positions", ft3); d.add(f7); - Field f8 = newField("f8", "This field has docs and freqs and positions", Field.Store.NO, Field.Index.ANALYZED); - f8.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS); + Field f8 = newField("f8", "This field has docs and freqs and positions", ft3); d.add(f8); - Field f9 = newField("f9", "This field has docs and freqs and positions", Field.Store.NO, Field.Index.ANALYZED); - f9.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS); + Field f9 = newField("f9", "This field has docs and freqs and positions", ft3); d.add(f9); writer.addDocument(d); @@ -113,42 +116,33 @@ d = new Document(); // f1,f4,f7: docs only - f1 = newField("f1", "This field has docs only", Field.Store.NO, Field.Index.ANALYZED); - f1.setIndexOptions(IndexOptions.DOCS_ONLY); + f1 = newField("f1", "This field has docs only", ft); d.add(f1); - f4 = newField("f4", "This field has docs only", Field.Store.NO, Field.Index.ANALYZED); - f4.setIndexOptions(IndexOptions.DOCS_ONLY); + f4 = newField("f4", "This field has docs only", ft); d.add(f4); - f7 = newField("f7", "This field has docs only", Field.Store.NO, Field.Index.ANALYZED); - f7.setIndexOptions(IndexOptions.DOCS_ONLY); + f7 = newField("f7", "This field has docs only", ft); d.add(f7); // f2, f5, f8: docs and freqs - f2 = newField("f2", "This field has docs and freqs", Field.Store.NO, Field.Index.ANALYZED); - f2.setIndexOptions(IndexOptions.DOCS_AND_FREQS); + f2 = newField("f2", "This field has docs and freqs", ft2); d.add(f2); - f5 = newField("f5", "This field has docs and freqs", Field.Store.NO, Field.Index.ANALYZED); - f5.setIndexOptions(IndexOptions.DOCS_AND_FREQS); + f5 = newField("f5", "This field has docs and freqs", ft2); d.add(f5); - f8 = newField("f8", "This field has docs and freqs", Field.Store.NO, Field.Index.ANALYZED); - f8.setIndexOptions(IndexOptions.DOCS_AND_FREQS); + f8 = newField("f8", "This field has docs and freqs", ft2); d.add(f8); // f3, f6, f9: docs and freqs and positions - f3 = newField("f3", "This field has docs and freqs and positions", Field.Store.NO, Field.Index.ANALYZED); - f3.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS); + f3 = newField("f3", "This field has docs and freqs and positions", ft3); d.add(f3); - f6 = newField("f6", "This field has docs and freqs and positions", Field.Store.NO, Field.Index.ANALYZED); - f6.setIndexOptions(IndexOptions.DOCS_AND_FREQS); + f6 = newField("f6", "This field has docs and freqs and positions", ft3); d.add(f6); - f9 = newField("f9", "This field has docs and freqs and positions", Field.Store.NO, Field.Index.ANALYZED); - f9.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS); + f9 = newField("f9", "This field has docs and freqs and positions", ft3); d.add(f9); writer.addDocument(d); @@ -201,9 +195,10 @@ lmp.setMergeFactor(2); lmp.setUseCompoundFile(false); Document d = new Document(); - - Field f1 = newField("f1", "This field has term freqs", Field.Store.NO, Field.Index.ANALYZED); - f1.setIndexOptions(IndexOptions.DOCS_AND_FREQS); + + FieldType ft = new FieldType(TextField.TYPE_UNSTORED); + ft.setIndexOptions(IndexOptions.DOCS_AND_FREQS); + Field f1 = newField("f1", "This field has term freqs", ft); d.add(f1); for(int i=0;i<30;i++) @@ -215,7 +210,7 @@ // now add some documents with positions, and check there is no prox after optimization d = new Document(); - f1 = newField("f1", "This field has positions", Field.Store.NO, Field.Index.ANALYZED); + f1 = newField("f1", "This field has positions", TextField.TYPE_UNSTORED); d.add(f1); for(int i=0;i<30;i++) Index: lucene/src/test/org/apache/lucene/index/TestNoDeletionPolicy.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestNoDeletionPolicy.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestNoDeletionPolicy.java (working copy) @@ -23,8 +23,8 @@ import java.util.Arrays; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.store.Directory; import org.apache.lucene.util.LuceneTestCase; import org.junit.Test; @@ -72,9 +72,11 @@ IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random)) .setIndexDeletionPolicy(NoDeletionPolicy.INSTANCE)); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); for (int i = 0; i < 10; i++) { Document doc = new Document(); - doc.add(newField("c", "a" + i, Store.YES, Index.ANALYZED)); + doc.add(newField("c", "a" + i, customType)); writer.addDocument(doc); writer.commit(); assertEquals("wrong number of commits !", i + 1, IndexReader.listCommits(dir).size()); Index: lucene/src/test/org/apache/lucene/index/TestOmitNorms.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestOmitNorms.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestOmitNorms.java (working copy) @@ -25,6 +25,8 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.store.Directory; public class TestOmitNorms extends LuceneTestCase { @@ -37,12 +39,13 @@ Document d = new Document(); // this field will have norms - Field f1 = newField("f1", "This field has norms", Field.Store.NO, Field.Index.ANALYZED); + Field f1 = newField("f1", "This field has norms", TextField.TYPE_UNSTORED); d.add(f1); // this field will NOT have norms - Field f2 = newField("f2", "This field has NO norms in all docs", Field.Store.NO, Field.Index.ANALYZED); - f2.setOmitNorms(true); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setOmitNorms(true); + Field f2 = newField("f2", "This field has NO norms in all docs", customType); d.add(f2); writer.addDocument(d); @@ -52,11 +55,9 @@ d = new Document(); // Reverse - f1.setOmitNorms(true); - d.add(f1); + d.add(newField("f1", "This field has norms", customType)); - f2.setOmitNorms(false); - d.add(f2); + d.add(newField("f2", "This field has NO norms in all docs", TextField.TYPE_UNSTORED)); writer.addDocument(d); @@ -88,12 +89,13 @@ Document d = new Document(); // this field will have norms - Field f1 = newField("f1", "This field has norms", Field.Store.NO, Field.Index.ANALYZED); + Field f1 = newField("f1", "This field has norms", TextField.TYPE_UNSTORED); d.add(f1); // this field will NOT have norms - Field f2 = newField("f2", "This field has NO norms in all docs", Field.Store.NO, Field.Index.ANALYZED); - f2.setOmitNorms(true); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setOmitNorms(true); + Field f2 = newField("f2", "This field has NO norms in all docs", customType); d.add(f2); for (int i = 0; i < 30; i++) { @@ -105,11 +107,9 @@ d = new Document(); // Reverese - f1.setOmitNorms(true); - d.add(f1); + d.add(newField("f1", "This field has norms", customType)); - f2.setOmitNorms(false); - d.add(f2); + d.add(newField("f2", "This field has NO norms in all docs", TextField.TYPE_UNSTORED)); for (int i = 0; i < 30; i++) { writer.addDocument(d); @@ -144,18 +144,19 @@ Document d = new Document(); // this field will have norms - Field f1 = newField("f1", "This field has norms", Field.Store.NO, Field.Index.ANALYZED); + Field f1 = newField("f1", "This field has norms", TextField.TYPE_UNSTORED); d.add(f1); // this field will NOT have norms - Field f2 = newField("f2", "This field has NO norms in all docs", Field.Store.NO, Field.Index.ANALYZED); + + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setOmitNorms(true); + Field f2 = newField("f2", "This field has NO norms in all docs", customType); d.add(f2); for (int i = 0; i < 5; i++) { writer.addDocument(d); } - - f2.setOmitNorms(true); for (int i = 0; i < 20; i++) { writer.addDocument(d); @@ -194,9 +195,10 @@ lmp.setMergeFactor(2); lmp.setUseCompoundFile(false); Document d = new Document(); - - Field f1 = newField("f1", "This field has no norms", Field.Store.NO, Field.Index.ANALYZED); - f1.setOmitNorms(true); + + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setOmitNorms(true); + Field f1 = newField("f1", "This field has no norms", customType); d.add(f1); for (int i = 0; i < 30; i++) { @@ -224,16 +226,25 @@ */ public void testOmitNormsCombos() throws IOException { // indexed with norms - Field norms = new Field("foo", "a", Field.Store.YES, Field.Index.ANALYZED); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + Field norms = new Field("foo", customType, "a"); // indexed without norms - Field noNorms = new Field("foo", "a", Field.Store.YES, Field.Index.ANALYZED_NO_NORMS); + FieldType customType1 = new FieldType(TextField.TYPE_UNSTORED); + customType1.setStored(true); + customType1.setOmitNorms(true); + Field noNorms = new Field("foo", customType1, "a"); // not indexed, but stored - Field noIndex = new Field("foo", "a", Field.Store.YES, Field.Index.NO); + FieldType customType2 = new FieldType(); + customType2.setStored(true); + Field noIndex = new Field("foo", customType2, "a"); // not indexed but stored, omitNorms is set - Field noNormsNoIndex = new Field("foo", "a", Field.Store.YES, Field.Index.NO); - noNormsNoIndex.setOmitNorms(true); + FieldType customType3 = new FieldType(); + customType3.setStored(true); + customType3.setOmitNorms(true); + Field noNormsNoIndex = new Field("foo", customType3, "a"); // not indexed nor stored (doesnt exist at all, we index a different field instead) - Field emptyNorms = new Field("bar", "a", Field.Store.YES, Field.Index.ANALYZED); + Field emptyNorms = new Field("bar", customType, "a"); assertNotNull(getNorms("foo", norms, norms)); assertNull(getNorms("foo", norms, noNorms)); Index: lucene/src/test/org/apache/lucene/index/TestDirectoryReader.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestDirectoryReader.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestDirectoryReader.java (working copy) @@ -22,6 +22,8 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriterConfig.OpenMode; import org.apache.lucene.store.Directory; import org.apache.lucene.util.BytesRef; @@ -202,7 +204,9 @@ new MockAnalyzer(random)).setOpenMode( create ? OpenMode.CREATE : OpenMode.APPEND)); Document doc = new Document(); - doc.add(newField("body", s, Field.Store.YES, Field.Index.ANALYZED)); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(false); + doc.add(newField("body", s, customType)); iw.addDocument(doc); iw.close(); } Index: lucene/src/test/org/apache/lucene/index/TestIndexWriterReader.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestIndexWriterReader.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestIndexWriterReader.java (working copy) @@ -28,9 +28,9 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; -import org.apache.lucene.document.Field.TermVector; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.StringField; +import org.apache.lucene.document.TextField; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; @@ -146,7 +146,7 @@ Document newDoc = r1.document(10); newDoc.removeField("id"); - newDoc.add(newField("id", Integer.toString(8000), Store.YES, Index.NOT_ANALYZED)); + newDoc.add(newField("id", Integer.toString(8000), StringField.TYPE_STORED)); writer.updateDocument(new Term("id", id10), newDoc); assertFalse(r1.isCurrent()); @@ -170,7 +170,7 @@ writer = new IndexWriter(dir1, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random))); Document doc = new Document(); - doc.add(newField("field", "a b c", Field.Store.NO, Field.Index.ANALYZED)); + doc.add(newField("field", "a b c", TextField.TYPE_UNSTORED)); writer.addDocument(doc); assertTrue(r2.isCurrent()); assertTrue(r3.isCurrent()); @@ -192,14 +192,14 @@ IndexWriter writer = new IndexWriter(dir, iwc); Document doc = new Document(); - doc.add(newField("field", "a b c", Field.Store.NO, Field.Index.ANALYZED)); + doc.add(newField("field", "a b c", TextField.TYPE_UNSTORED)); writer.addDocument(doc); writer.close(); iwc = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)); writer = new IndexWriter(dir, iwc); doc = new Document(); - doc.add(newField("field", "a b c", Field.Store.NO, Field.Index.ANALYZED)); + doc.add(newField("field", "a b c", TextField.TYPE_UNSTORED)); IndexReader nrtReader = writer.getReader(); assertTrue(nrtReader.isCurrent()); writer.addDocument(doc); @@ -580,16 +580,27 @@ public static Document createDocument(int n, String indexName, int numFields) { StringBuilder sb = new StringBuilder(); Document doc = new Document(); - doc.add(new Field("id", Integer.toString(n), Store.YES, Index.NOT_ANALYZED, TermVector.WITH_POSITIONS_OFFSETS)); - doc.add(new Field("indexname", indexName, Store.YES, Index.NOT_ANALYZED, TermVector.WITH_POSITIONS_OFFSETS)); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + customType.setStoreTermVectors(true); + customType.setStoreTermVectorPositions(true); + customType.setStoreTermVectorOffsets(true); + + FieldType customType1 = new FieldType(StringField.TYPE_UNSTORED); + customType1.setStored(true); + customType1.setStoreTermVectors(true); + customType1.setStoreTermVectorPositions(true); + customType1.setStoreTermVectorOffsets(true); + + doc.add(new Field("id", customType1, Integer.toString(n))); + doc.add(new Field("indexname", customType1, indexName)); sb.append("a"); sb.append(n); - doc.add(new Field("field1", sb.toString(), Store.YES, Index.ANALYZED, TermVector.WITH_POSITIONS_OFFSETS)); + doc.add(new Field("field1", customType, sb.toString())); sb.append(" b"); sb.append(n); for (int i = 1; i < numFields; i++) { - doc.add(new Field("field" + (i + 1), sb.toString(), Store.YES, - Index.ANALYZED, TermVector.WITH_POSITIONS_OFFSETS)); + doc.add(new Field("field" + (i + 1), customType, sb.toString())); } return doc; } @@ -915,8 +926,8 @@ Directory dir = newDirectory(); final IndexWriter w = new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMergePolicy(newLogMergePolicy())); Document doc = new Document(); - doc.add(newField("field", "a b c", Field.Store.NO, Field.Index.ANALYZED)); - Field id = newField("id", "", Field.Store.NO, Field.Index.NOT_ANALYZED); + doc.add(newField("field", "a b c", TextField.TYPE_UNSTORED)); + Field id = newField("id", "", StringField.TYPE_UNSTORED); doc.add(id); id.setValue("0"); w.addDocument(doc); @@ -939,8 +950,8 @@ Directory dir = newDirectory(); final IndexWriter w = new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random))); Document doc = new Document(); - doc.add(newField("field", "a b c", Field.Store.NO, Field.Index.ANALYZED)); - Field id = newField("id", "", Field.Store.NO, Field.Index.NOT_ANALYZED); + doc.add(newField("field", "a b c", TextField.TYPE_UNSTORED)); + Field id = newField("id", "", StringField.TYPE_UNSTORED); doc.add(id); id.setValue("0"); w.addDocument(doc); @@ -997,7 +1008,9 @@ ); Document doc = new Document(); - doc.add(newField("foo", "bar", Field.Store.YES, Field.Index.NOT_ANALYZED)); + FieldType customType = new FieldType(StringField.TYPE_UNSTORED); + customType.setStored(false); + doc.add(newField("foo", "bar", customType)); for(int i=0;i<20;i++) { w.addDocument(doc); } @@ -1023,7 +1036,7 @@ Directory dir = newDirectory(); IndexWriter w = new IndexWriter(dir, conf); Document doc = new Document(); - doc.add(new Field("f", "val", Store.NO, Index.ANALYZED)); + doc.add(new TextField("f", "val")); w.addDocument(doc); IndexReader r = IndexReader.open(w, true).getSequentialSubReaders()[0]; try { Index: lucene/src/test/org/apache/lucene/index/TestRollingUpdates.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestRollingUpdates.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestRollingUpdates.java (working copy) @@ -19,7 +19,6 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.*; -import org.apache.lucene.document.Field.Index; import org.apache.lucene.index.codecs.CodecProvider; import org.apache.lucene.store.*; import org.apache.lucene.util.*; @@ -55,7 +54,7 @@ } else { id++; } - doc.getField("docid").setValue(myID); + ((Field) doc.getField("docid")).setValue(myID); w.updateDocument(new Term("docid", myID), doc); if (docIter >= SIZE && random.nextInt(50) == 17) { @@ -130,7 +129,7 @@ IndexReader open = null; for (int i = 0; i < num; i++) { Document doc = new Document();// docs.nextDoc(); - doc.add(newField("id", "test", Index.NOT_ANALYZED)); + doc.add(newField("id", "test", StringField.TYPE_UNSTORED)); writer.updateDocument(new Term("id", "test"), doc); if (random.nextInt(3) == 0) { if (open == null) { Index: lucene/src/test/org/apache/lucene/index/TestTransactionRollback.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestTransactionRollback.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestTransactionRollback.java (working copy) @@ -29,7 +29,8 @@ import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.store.Directory; import org.apache.lucene.util.Bits; @@ -128,9 +129,12 @@ //Build index, of records 1 to 100, committing after each batch of 10 IndexDeletionPolicy sdp=new KeepAllDeletionPolicy(); IndexWriter w=new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random)).setIndexDeletionPolicy(sdp)); + + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); for(int currentRecordId=1;currentRecordId<=100;currentRecordId++) { Document doc=new Document(); - doc.add(newField(FIELD_RECORD_ID,""+currentRecordId,Field.Store.YES,Field.Index.ANALYZED)); + doc.add(newField(FIELD_RECORD_ID,""+currentRecordId,customType)); w.addDocument(doc); if (currentRecordId%10 == 0) { Index: lucene/src/test/org/apache/lucene/index/TestBinaryTerms.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestBinaryTerms.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestBinaryTerms.java (working copy) @@ -21,6 +21,8 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.codecs.CodecProvider; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.TermQuery; @@ -47,8 +49,10 @@ bytes.bytes[1] = (byte) (255 - i); bytes.length = 2; Document doc = new Document(); - doc.add(new Field("id", "" + i, Field.Store.YES, Field.Index.NO)); - doc.add(new Field("bytes", tokenStream)); + FieldType customType = new FieldType(); + customType.setStored(true); + doc.add(new Field("id", customType, "" + i)); + doc.add(new TextField("bytes", tokenStream)); iw.addDocument(doc); } Index: lucene/src/test/org/apache/lucene/index/TestFilterIndexReader.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestFilterIndexReader.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestFilterIndexReader.java (working copy) @@ -23,7 +23,8 @@ import org.apache.lucene.store.Directory; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.Bits; @@ -128,16 +129,18 @@ Directory directory = newDirectory(); IndexWriter writer = new IndexWriter(directory, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random))); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); Document d1 = new Document(); - d1.add(newField("default","one two", Field.Store.YES, Field.Index.ANALYZED)); + d1.add(newField("default","one two", customType)); writer.addDocument(d1); Document d2 = new Document(); - d2.add(newField("default","one three", Field.Store.YES, Field.Index.ANALYZED)); + d2.add(newField("default","one three", customType)); writer.addDocument(d2); Document d3 = new Document(); - d3.add(newField("default","two four", Field.Store.YES, Field.Index.ANALYZED)); + d3.add(newField("default","two four", customType)); writer.addDocument(d3); writer.close(); Index: lucene/src/test/org/apache/lucene/index/TestSegmentMerger.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestSegmentMerger.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestSegmentMerger.java (working copy) @@ -23,9 +23,7 @@ import org.apache.lucene.store.IOContext; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriterConfig.OpenMode; import org.apache.lucene.util.BytesRef; @@ -142,7 +140,7 @@ // Create an index w/ .del file w.addDocument(new Document()); Document doc = new Document(); - doc.add(new Field("c", "test", Store.NO, Index.ANALYZED)); + doc.add(new TextField("c", "test")); w.addDocument(doc); w.commit(); w.deleteDocuments(new Term("c", "test")); @@ -160,7 +158,7 @@ // Create an index w/ .s* w = new IndexWriter(dir, new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setOpenMode(OpenMode.CREATE)); doc = new Document(); - doc.add(new Field("c", "test", Store.NO, Index.ANALYZED)); + doc.add(new TextField("c", "test")); w.addDocument(doc); w.close(); IndexReader r = IndexReader.open(dir, false); Index: lucene/src/test/org/apache/lucene/index/TestAddIndexes.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestAddIndexes.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestAddIndexes.java (working copy) @@ -25,9 +25,9 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; -import org.apache.lucene.document.Field.TermVector; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.StringField; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriterConfig.OpenMode; import org.apache.lucene.index.codecs.CodecProvider; import org.apache.lucene.index.codecs.mocksep.MockSepCodec; @@ -165,11 +165,12 @@ // Adds 10 docs, then replaces them with another 10 // docs, so 10 pending deletes: + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setTokenized(false); for (int i = 0; i < 20; i++) { Document doc = new Document(); - doc.add(newField("id", "" + (i % 10), Field.Store.NO, Field.Index.NOT_ANALYZED)); - doc.add(newField("content", "bbb " + i, Field.Store.NO, - Field.Index.ANALYZED)); + doc.add(newField("id", "" + (i % 10), customType)); + doc.add(newField("content", "bbb " + i, TextField.TYPE_UNSTORED)); writer.updateDocument(new Term("id", "" + (i%10)), doc); } // Deletes one of the 10 added docs, leaving 9: @@ -201,10 +202,12 @@ // Adds 10 docs, then replaces them with another 10 // docs, so 10 pending deletes: + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setTokenized(false); for (int i = 0; i < 20; i++) { Document doc = new Document(); - doc.add(newField("id", "" + (i % 10), Field.Store.NO, Field.Index.NOT_ANALYZED)); - doc.add(newField("content", "bbb " + i, Field.Store.NO, Field.Index.ANALYZED)); + doc.add(newField("id", "" + (i % 10), customType)); + doc.add(newField("content", "bbb " + i, TextField.TYPE_UNSTORED)); writer.updateDocument(new Term("id", "" + (i%10)), doc); } @@ -239,11 +242,12 @@ // Adds 10 docs, then replaces them with another 10 // docs, so 10 pending deletes: + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setTokenized(false); for (int i = 0; i < 20; i++) { Document doc = new Document(); - doc.add(newField("id", "" + (i % 10), Field.Store.NO, Field.Index.NOT_ANALYZED)); - doc.add(newField("content", "bbb " + i, Field.Store.NO, - Field.Index.ANALYZED)); + doc.add(newField("id", "" + (i % 10), customType)); + doc.add(newField("content", "bbb " + i, TextField.TYPE_UNSTORED)); writer.updateDocument(new Term("id", "" + (i%10)), doc); } @@ -503,8 +507,7 @@ private void addDocs(IndexWriter writer, int numDocs) throws IOException { for (int i = 0; i < numDocs; i++) { Document doc = new Document(); - doc.add(newField("content", "aaa", Field.Store.NO, - Field.Index.ANALYZED)); + doc.add(newField("content", "aaa", TextField.TYPE_UNSTORED)); writer.addDocument(doc); } } @@ -512,8 +515,7 @@ private void addDocs2(IndexWriter writer, int numDocs) throws IOException { for (int i = 0; i < numDocs; i++) { Document doc = new Document(); - doc.add(newField("content", "bbb", Field.Store.NO, - Field.Index.ANALYZED)); + doc.add(newField("content", "bbb", TextField.TYPE_UNSTORED)); writer.addDocument(doc); } } @@ -582,20 +584,22 @@ .setMaxBufferedDocs(5).setMergePolicy(lmp)); Document doc = new Document(); - doc.add(newField("content", "aaa bbb ccc ddd eee fff ggg hhh iii", Field.Store.YES, - Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + customType.setStoreTermVectors(true); + customType.setStoreTermVectorPositions(true); + customType.setStoreTermVectorOffsets(true); + doc.add(newField("content", "aaa bbb ccc ddd eee fff ggg hhh iii", customType)); for(int i=0;i<60;i++) writer.addDocument(doc); Document doc2 = new Document(); - doc2.add(newField("content", "aaa bbb ccc ddd eee fff ggg hhh iii", Field.Store.YES, - Field.Index.NO)); - doc2.add(newField("content", "aaa bbb ccc ddd eee fff ggg hhh iii", Field.Store.YES, - Field.Index.NO)); - doc2.add(newField("content", "aaa bbb ccc ddd eee fff ggg hhh iii", Field.Store.YES, - Field.Index.NO)); - doc2.add(newField("content", "aaa bbb ccc ddd eee fff ggg hhh iii", Field.Store.YES, - Field.Index.NO)); + FieldType customType2 = new FieldType(); + customType2.setStored(true); + doc2.add(newField("content", "aaa bbb ccc ddd eee fff ggg hhh iii", customType2)); + doc2.add(newField("content", "aaa bbb ccc ddd eee fff ggg hhh iii", customType2)); + doc2.add(newField("content", "aaa bbb ccc ddd eee fff ggg hhh iii", customType2)); + doc2.add(newField("content", "aaa bbb ccc ddd eee fff ggg hhh iii", customType2)); for(int i=0;i<10;i++) writer.addDocument(doc2); writer.close(); @@ -619,7 +623,7 @@ private void addDoc(IndexWriter writer) throws IOException { Document doc = new Document(); - doc.add(newField("content", "aaa", Field.Store.NO, Field.Index.ANALYZED)); + doc.add(newField("content", "aaa", TextField.TYPE_UNSTORED)); writer.addDocument(doc); } @@ -944,7 +948,7 @@ IndexWriterConfig conf = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)); IndexWriter writer = new IndexWriter(dirs[i], conf); Document doc = new Document(); - doc.add(new Field("id", "myid", Store.NO, Index.NOT_ANALYZED_NO_NORMS)); + doc.add(new StringField("id", "myid")); writer.addDocument(doc); writer.close(); } @@ -973,8 +977,10 @@ private void addDocs3(IndexWriter writer, int numDocs) throws IOException { for (int i = 0; i < numDocs; i++) { Document doc = new Document(); - doc.add(newField("content", "aaa", Field.Store.NO, Field.Index.ANALYZED)); - doc.add(newField("id", "" + i, Field.Store.YES, Field.Index.ANALYZED)); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + doc.add(newField("content", "aaa", TextField.TYPE_UNSTORED)); + doc.add(newField("id", "" + i, customType)); writer.addDocument(doc); } } @@ -1061,7 +1067,10 @@ dirs[i] = new RAMDirectory(); IndexWriter w = new IndexWriter(dirs[i], new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random))); Document d = new Document(); - d.add(new Field("c", "v", Store.YES, Index.ANALYZED, TermVector.YES)); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + customType.setStoreTermVectors(true); + d.add(new Field("c", customType, "v")); w.addDocument(d); w.close(); } @@ -1099,10 +1108,12 @@ new MockAnalyzer(random)).setMergePolicy(lmp2); IndexWriter w2 = new IndexWriter(src, conf2); Document doc = new Document(); - doc.add(new Field("c", "some text", Store.YES, Index.ANALYZED)); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + doc.add(new Field("c", customType, "some text")); w2.addDocument(doc); doc = new Document(); - doc.add(new Field("d", "delete", Store.NO, Index.NOT_ANALYZED_NO_NORMS)); + doc.add(new StringField("d", "delete")); w2.addDocument(doc); w2.commit(); w2.deleteDocuments(new Term("d", "delete")); @@ -1152,7 +1163,9 @@ conf.setCodecProvider(provider); IndexWriter w = new IndexWriter(toAdd, conf); Document doc = new Document(); - doc.add(newField("foo", "bar", Index.NOT_ANALYZED)); + FieldType customType = new FieldType(); + customType.setIndexed(true); + doc.add(newField("foo", "bar", customType)); w.addDocument(doc); w.close(); } Index: lucene/src/test/org/apache/lucene/index/TestTieredMergePolicy.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestTieredMergePolicy.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestTieredMergePolicy.java (working copy) @@ -19,7 +19,7 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; +import org.apache.lucene.document.TextField; import org.apache.lucene.store.Directory; import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.util._TestUtil; @@ -39,7 +39,7 @@ w.setInfoStream(VERBOSE ? System.out : null); for(int i=0;i<80;i++) { Document doc = new Document(); - doc.add(newField("content", "aaa " + (i%4), Field.Store.NO, Field.Index.ANALYZED)); + doc.add(newField("content", "aaa " + (i%4), TextField.TYPE_UNSTORED)); w.addDocument(doc); } assertEquals(80, w.maxDoc()); @@ -86,7 +86,7 @@ final int numDocs = _TestUtil.nextInt(random, 20, 100); for(int i=0;i fields = d.getFields(); + List fields = d.getFields(); if (d.getField("content3") == null) { final int numFields = 5; assertEquals(numFields, fields.size()); - Field f = d.getField("id"); + IndexableField f = d.getField("id"); assertEquals(""+i, f.stringValue()); f = d.getField("utf8"); @@ -594,12 +595,20 @@ private void addDoc(IndexWriter writer, int id) throws IOException { Document doc = new Document(); - doc.add(new Field("content", "aaa", Field.Store.NO, Field.Index.ANALYZED)); - doc.add(new Field("id", Integer.toString(id), Field.Store.YES, Field.Index.NOT_ANALYZED)); - doc.add(new Field("autf8", "Lu\uD834\uDD1Ece\uD834\uDD60ne \u0000 \u2620 ab\ud917\udc17cd", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); - doc.add(new Field("utf8", "Lu\uD834\uDD1Ece\uD834\uDD60ne \u0000 \u2620 ab\ud917\udc17cd", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); - doc.add(new Field("content2", "here is more content with aaa aaa aaa", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); - doc.add(new Field("fie\u2C77ld", "field with non-ascii name", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); + doc.add(new TextField("content", "aaa")); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + customType.setTokenized(false); + doc.add(new Field("id", customType, Integer.toString(id))); + FieldType customType2 = new FieldType(TextField.TYPE_UNSTORED); + customType2.setStored(true); + customType2.setStoreTermVectors(true); + customType2.setStoreTermVectorPositions(true); + customType2.setStoreTermVectorOffsets(true); + doc.add(new Field("autf8", customType2, "Lu\uD834\uDD1Ece\uD834\uDD60ne \u0000 \u2620 ab\ud917\udc17cd")); + doc.add(new Field("utf8", customType2, "Lu\uD834\uDD1Ece\uD834\uDD60ne \u0000 \u2620 ab\ud917\udc17cd")); + doc.add(new Field("content2", customType2, "here is more content with aaa aaa aaa")); + doc.add(new Field("fie\u2C77ld", customType2, "field with non-ascii name")); // add numeric fields, to test if flex preserves encoding doc.add(new NumericField("trieInt", 4).setIntValue(id)); doc.add(new NumericField("trieLong", 4).setLongValue(id)); @@ -608,11 +617,14 @@ private void addNoProxDoc(IndexWriter writer) throws IOException { Document doc = new Document(); - Field f = new Field("content3", "aaa", Field.Store.YES, Field.Index.ANALYZED); - f.setIndexOptions(IndexOptions.DOCS_ONLY); + FieldType customType = new FieldType(TextField.TYPE_STORED); + customType.setIndexOptions(IndexOptions.DOCS_ONLY); + Field f = new Field("content3", customType, "aaa"); doc.add(f); - f = new Field("content4", "aaa", Field.Store.YES, Field.Index.NO); - f.setIndexOptions(IndexOptions.DOCS_ONLY); + FieldType customType2 = new FieldType(); + customType2.setStored(true); + customType2.setIndexOptions(IndexOptions.DOCS_ONLY); + f = new Field("content4", customType2, "aaa"); doc.add(f); writer.addDocument(doc); } Index: lucene/src/test/org/apache/lucene/index/TestLazyProxSkipping.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestLazyProxSkipping.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestLazyProxSkipping.java (working copy) @@ -25,8 +25,9 @@ import org.apache.lucene.analysis.MockTokenizer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.document.Document; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.codecs.CodecProvider; -import org.apache.lucene.document.Field; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.PhraseQuery; import org.apache.lucene.search.ScoreDoc; @@ -85,6 +86,9 @@ setMaxBufferedDocs(10). setMergePolicy(newLogMergePolicy(false)) ); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + for (int i = 0; i < numDocs; i++) { Document doc = new Document(); String content; @@ -99,7 +103,7 @@ content = this.term3 + " " + this.term2; } - doc.add(newField(this.field, content, Field.Store.YES, Field.Index.ANALYZED)); + doc.add(newField(this.field, content, customType)); writer.addDocument(doc); } @@ -146,9 +150,11 @@ public void testSeek() throws IOException { Directory directory = newDirectory(); IndexWriter writer = new IndexWriter(directory, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random))); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); for (int i = 0; i < 10; i++) { Document doc = new Document(); - doc.add(newField(this.field, "a b", Field.Store.YES, Field.Index.ANALYZED)); + doc.add(newField(this.field, "a b", customType)); writer.addDocument(doc); } Index: lucene/src/test/org/apache/lucene/index/TestNorms.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestNorms.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestNorms.java (working copy) @@ -25,8 +25,7 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriterConfig.OpenMode; import org.apache.lucene.search.DefaultSimilarity; import org.apache.lucene.search.DefaultSimilarityProvider; @@ -220,7 +219,7 @@ Document d = new Document(); float boost = nextNorm("anyfield"); // in this test the same similarity is used for all fields so it does not matter what field is passed for (int i = 0; i < 10; i++) { - Field f = newField("f"+i,"v"+i,Store.NO,Index.NOT_ANALYZED); + Field f = newField("f"+i,"v"+i,TextField.TYPE_UNSTORED); f.setBoost(boost); d.add(f); } @@ -277,8 +276,8 @@ }); RandomIndexWriter writer = new RandomIndexWriter(random, dir, config); Document doc = new Document(); - Field foo = newField("foo", "", Field.Store.NO, Field.Index.ANALYZED); - Field bar = newField("bar", "", Field.Store.NO, Field.Index.ANALYZED); + Field foo = newField("foo", "", TextField.TYPE_UNSTORED); + Field bar = newField("bar", "", TextField.TYPE_UNSTORED); doc.add(foo); doc.add(bar); Index: lucene/src/test/org/apache/lucene/index/TestStressAdvance.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestStressAdvance.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestStressAdvance.java (working copy) @@ -36,9 +36,11 @@ RandomIndexWriter w = new RandomIndexWriter(random, dir); final Set aDocs = new HashSet(); final Document doc = new Document(); - final Field f = newField("field", "", Field.Index.NOT_ANALYZED_NO_NORMS); + FieldType customType = new FieldType(StringField.TYPE_UNSTORED); + customType.setStored(true); + final Field f = newField("field", "", StringField.TYPE_UNSTORED); doc.add(f); - final Field idField = newField("id", "", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS); + final Field idField = newField("id", "", customType); doc.add(idField); int num = atLeast(4097); for(int id=0;id allTerms = new HashSet(); Index: lucene/src/test/org/apache/lucene/index/TestIndexReaderClone.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestIndexReaderClone.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestIndexReaderClone.java (working copy) @@ -22,7 +22,8 @@ import org.apache.lucene.search.Similarity; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.store.Directory; import org.apache.lucene.store.LockObtainFailedException; import org.apache.lucene.util.LuceneTestCase; @@ -500,7 +501,9 @@ setMergePolicy(newLogMergePolicy(false)) ); Document doc = new Document(); - doc.add(newField("field", "yes it's stored", Field.Store.YES, Field.Index.ANALYZED)); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + doc.add(newField("field", "yes it's stored", customType)); w.addDocument(doc); w.close(); IndexReader r1 = IndexReader.open(dir, false); Index: lucene/src/test/org/apache/lucene/index/TestDocsAndPositions.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestDocsAndPositions.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestDocsAndPositions.java (working copy) @@ -22,7 +22,8 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.store.Directory; @@ -49,9 +50,11 @@ newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random))); for (int i = 0; i < 39; i++) { Document doc = new Document(); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setOmitNorms(true); doc.add(newField(fieldName, "1 2 3 4 5 6 7 8 9 10 " + "1 2 3 4 5 6 7 8 9 10 " + "1 2 3 4 5 6 7 8 9 10 " - + "1 2 3 4 5 6 7 8 9 10", Field.Store.NO, Field.Index.ANALYZED_NO_NORMS)); + + "1 2 3 4 5 6 7 8 9 10", customType)); writer.addDocument(doc); } IndexReader reader = writer.getReader(); @@ -117,6 +120,8 @@ int max = 1051; int term = random.nextInt(max); Integer[][] positionsInDoc = new Integer[numDocs][]; + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setOmitNorms(true); for (int i = 0; i < numDocs; i++) { Document doc = new Document(); ArrayList positions = new ArrayList(); @@ -133,8 +138,7 @@ builder.append(term); positions.add(num); } - doc.add(newField(fieldName, builder.toString(), Field.Store.NO, - Field.Index.ANALYZED_NO_NORMS)); + doc.add(newField(fieldName, builder.toString(), customType)); positionsInDoc[i] = positions.toArray(new Integer[0]); writer.addDocument(doc); } @@ -199,6 +203,8 @@ int max = 15678; int term = random.nextInt(max); int[] freqInDoc = new int[numDocs]; + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setOmitNorms(true); for (int i = 0; i < numDocs; i++) { Document doc = new Document(); StringBuilder builder = new StringBuilder(); @@ -209,8 +215,7 @@ freqInDoc[i]++; } } - doc.add(newField(fieldName, builder.toString(), Field.Store.NO, - Field.Index.ANALYZED_NO_NORMS)); + doc.add(newField(fieldName, builder.toString(), customType)); writer.addDocument(doc); } @@ -275,6 +280,8 @@ RandomIndexWriter writer = new RandomIndexWriter(random, dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random))); int howMany = 1000; + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setOmitNorms(true); for (int i = 0; i < 39; i++) { Document doc = new Document(); StringBuilder builder = new StringBuilder(); @@ -285,8 +292,7 @@ builder.append("odd "); } } - doc.add(newField(fieldName, builder.toString(), Field.Store.NO, - Field.Index.ANALYZED_NO_NORMS)); + doc.add(newField(fieldName, builder.toString(), customType)); writer.addDocument(doc); } Index: lucene/src/test/org/apache/lucene/index/TestIndexReaderOnDiskFull.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestIndexReaderOnDiskFull.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestIndexReaderOnDiskFull.java (working copy) @@ -21,7 +21,8 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.search.DefaultSimilarity; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.ScoreDoc; @@ -50,10 +51,13 @@ System.out.println("TEST: create initial index"); writer.setInfoStream(System.out); } + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + customType.setTokenized(false); for(int i=0;i<157;i++) { Document d = new Document(); - d.add(newField("id", Integer.toString(i), Field.Store.YES, Field.Index.NOT_ANALYZED)); - d.add(newField("content", "aaa " + i, Field.Store.NO, Field.Index.ANALYZED)); + d.add(newField("id", Integer.toString(i), customType)); + d.add(newField("content", "aaa " + i, TextField.TYPE_UNSTORED)); writer.addDocument(d); if (0==i%10) writer.commit(); Index: lucene/src/test/org/apache/lucene/index/TestRollback.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestRollback.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestRollback.java (working copy) @@ -19,8 +19,8 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.store.Directory; import org.apache.lucene.util.LuceneTestCase; @@ -30,9 +30,12 @@ public void testRollbackIntegrityWithBufferFlush() throws Exception { Directory dir = newDirectory(); RandomIndexWriter rw = new RandomIndexWriter(random, dir); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + customType.setOmitNorms(true); for (int i = 0; i < 5; i++) { Document doc = new Document(); - doc.add(newField("pk", Integer.toString(i), Store.YES, Index.ANALYZED_NO_NORMS)); + doc.add(newField("pk", Integer.toString(i), customType)); rw.addDocument(doc); } rw.close(); @@ -43,8 +46,8 @@ for (int i = 0; i < 3; i++) { Document doc = new Document(); String value = Integer.toString(i); - doc.add(newField("pk", value, Store.YES, Index.ANALYZED_NO_NORMS)); - doc.add(newField("text", "foo", Store.YES, Index.ANALYZED_NO_NORMS)); + doc.add(newField("pk", value, customType)); + doc.add(newField("text", "foo", customType)); w.updateDocument(new Term("pk", value), doc); } w.rollback(); Index: lucene/src/test/org/apache/lucene/index/TestTermVectorsReader.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestTermVectorsReader.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestTermVectorsReader.java (working copy) @@ -31,6 +31,8 @@ import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.store.Directory; import org.apache.lucene.store.IOContext; import org.apache.lucene.store.IOContext.Context; @@ -101,16 +103,24 @@ Document doc = new Document(); for(int i=0;i0) { int k = i-1; @@ -957,13 +967,21 @@ Document doc = new Document(); sb.append("a"); sb.append(n); - doc.add(new Field("field1", sb.toString(), Store.YES, Index.ANALYZED)); - doc.add(new Field("fielda", sb.toString(), Store.YES, Index.NOT_ANALYZED_NO_NORMS)); - doc.add(new Field("fieldb", sb.toString(), Store.YES, Index.NO)); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + FieldType customType2 = new FieldType(TextField.TYPE_UNSTORED); + customType2.setStored(true); + customType2.setTokenized(false); + customType2.setOmitNorms(true); + FieldType customType3 = new FieldType(); + customType3.setStored(true); + doc.add(new Field("field1", customType, sb.toString())); + doc.add(new Field("fielda", customType2, sb.toString())); + doc.add(new Field("fieldb", customType3, sb.toString())); sb.append(" b"); sb.append(n); for (int i = 1; i < numFields; i++) { - doc.add(new Field("field" + (i+1), sb.toString(), Store.YES, Index.ANALYZED)); + doc.add(new Field("field" + (i+1), customType, sb.toString())); } return doc; } @@ -1178,7 +1196,7 @@ ); for(int i=0;i<4;i++) { Document doc = new Document(); - doc.add(newField("id", ""+i, Field.Store.NO, Field.Index.NOT_ANALYZED)); + doc.add(newField("id", ""+i, StringField.TYPE_UNSTORED)); writer.addDocument(doc); Map data = new HashMap(); data.put("index", i+""); @@ -1239,7 +1257,7 @@ setMergePolicy(newLogMergePolicy(10)) ); Document doc = new Document(); - doc.add(newField("number", "17", Field.Store.NO, Field.Index.NOT_ANALYZED)); + doc.add(newField("number", "17", StringField.TYPE_UNSTORED)); writer.addDocument(doc); writer.commit(); Index: lucene/src/test/org/apache/lucene/index/TestStressIndexing.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestStressIndexing.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestStressIndexing.java (working copy) @@ -75,11 +75,13 @@ @Override public void doWork() throws Exception { // Add 10 docs: + FieldType customType = new FieldType(StringField.TYPE_UNSTORED); + customType.setStored(true); for(int j=0; j<10; j++) { Document d = new Document(); int n = random.nextInt(); - d.add(newField("id", Integer.toString(nextID++), Field.Store.YES, Field.Index.NOT_ANALYZED)); - d.add(newField("contents", English.intToEnglish(n), Field.Store.NO, Field.Index.ANALYZED)); + d.add(newField("id", Integer.toString(nextID++), customType)); + d.add(newField("contents", English.intToEnglish(n), TextField.TYPE_UNSTORED)); writer.addDocument(d); } Index: lucene/src/test/org/apache/lucene/index/TestTermdocPerf.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestTermdocPerf.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestTermdocPerf.java (working copy) @@ -25,7 +25,7 @@ import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; +import org.apache.lucene.document.StringField; import org.apache.lucene.index.IndexWriterConfig.OpenMode; import org.apache.lucene.store.Directory; import org.apache.lucene.util.LuceneTestCase; @@ -69,7 +69,8 @@ }; Document doc = new Document(); - doc.add(newField(field,val, Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS)); + + doc.add(newField(field,val, StringField.TYPE_UNSTORED)); IndexWriter writer = new IndexWriter( dir, newIndexWriterConfig(TEST_VERSION_CURRENT, analyzer). Index: lucene/src/test/org/apache/lucene/index/TestLazyBug.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestLazyBug.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestLazyBug.java (working copy) @@ -1,140 +0,0 @@ -package org.apache.lucene.index; - -/** - * 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. - */ - -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.apache.lucene.analysis.MockAnalyzer; -import org.apache.lucene.document.*; -import org.apache.lucene.store.Directory; -import org.apache.lucene.util.LuceneTestCase; -import org.junit.AfterClass; -import org.junit.BeforeClass; - - -/** - * Test demonstrating EOF bug on the last field of the last doc - * if other docs have allready been accessed. - */ -public class TestLazyBug extends LuceneTestCase { - - public static int NUM_DOCS = TEST_NIGHTLY ? 500 : 50; - public static int NUM_FIELDS = TEST_NIGHTLY ? 100 : 10; - - private static String[] data = new String[] { - "now", - "is the time", - "for all good men", - "to come to the aid", - "of their country!", - "this string contains big chars:{\u0111 \u0222 \u0333 \u1111 \u2222 \u3333}", - "this string is a bigger string, mary had a little lamb, little lamb, little lamb!" - }; - - private static Set dataset = asSet(data); - - private static String MAGIC_FIELD = "f"+(NUM_FIELDS/3); - - private static Directory directory; - - @BeforeClass - public static void beforeClass() throws Exception { - directory = makeIndex(); - } - - @AfterClass - public static void afterClass() throws Exception { - directory.close(); - directory = null; - } - - private static FieldSelector SELECTOR = new FieldSelector() { - public FieldSelectorResult accept(String f) { - if (f.equals(MAGIC_FIELD)) { - return FieldSelectorResult.LOAD; - } - return FieldSelectorResult.LAZY_LOAD; - } - }; - - private static Directory makeIndex() throws Exception { - Directory dir = newDirectory(); - try { - IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig( - TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMergePolicy(newLogMergePolicy())); - LogMergePolicy lmp = (LogMergePolicy) writer.getConfig().getMergePolicy(); - lmp.setUseCompoundFile(false); - for (int d = 1; d <= NUM_DOCS; d++) { - Document doc = new Document(); - for (int f = 1; f <= NUM_FIELDS; f++ ) { - doc.add(newField("f"+f, - data[f % data.length] - + '#' + data[random.nextInt(data.length)], - Field.Store.NO, - Field.Index.ANALYZED)); - } - writer.addDocument(doc); - } - writer.close(); - } catch (Exception e) { - throw new RuntimeException(e); - } - return dir; - } - - public void doTest(int[] docs) throws Exception { - IndexReader reader = IndexReader.open(directory, true); - for (int i = 0; i < docs.length; i++) { - Document d = reader.document(docs[i], SELECTOR); - d.get(MAGIC_FIELD); - - List fields = d.getFields(); - for (Iterator fi = fields.iterator(); fi.hasNext(); ) { - Fieldable f=null; - try { - f = fi.next(); - String fname = f.name(); - String fval = f.stringValue(); - assertNotNull(docs[i]+" FIELD: "+fname, fval); - String[] vals = fval.split("#"); - if (!dataset.contains(vals[0]) || !dataset.contains(vals[1])) { - fail("FIELD:"+fname+",VAL:"+fval); - } - } catch (Exception e) { - throw new Exception(docs[i]+" WTF: "+f.name(), e); - } - } - } - reader.close(); - } - - public void testLazyWorks() throws Exception { - doTest(new int[] { NUM_DOCS-1 }); - } - - public void testLazyAlsoWorks() throws Exception { - doTest(new int[] { NUM_DOCS-1, NUM_DOCS/2 }); - } - - public void testLazyBroken() throws Exception { - doTest(new int[] { NUM_DOCS/2, NUM_DOCS-1 }); - } - -} Index: lucene/src/test/org/apache/lucene/index/TestIndexWriterMerging.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestIndexWriterMerging.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestIndexWriterMerging.java (working copy) @@ -19,9 +19,9 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; -import org.apache.lucene.document.Field.TermVector; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.StringField; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriterConfig.OpenMode; import org.apache.lucene.util.LuceneTestCase; @@ -107,10 +107,12 @@ setMergePolicy(newLogMergePolicy(2)) ); + FieldType custom = new FieldType(StringField.TYPE_UNSTORED); + custom.setStored(true); for (int i = start; i < (start + numDocs); i++) { Document temp = new Document(); - temp.add(newField("count", (""+i), Field.Store.YES, Field.Index.NOT_ANALYZED)); + temp.add(newField("count", (""+i), custom)); writer.addDocument(temp); } @@ -129,12 +131,19 @@ Document document = new Document(); document = new Document(); - Field storedField = newField("stored", "stored", Field.Store.YES, - Field.Index.NO); + + FieldType customType = new FieldType(); + customType.setStored(true); + + FieldType customType1 = new FieldType(TextField.TYPE_UNSTORED); + customType1.setTokenized(false); + customType1.setStoreTermVectors(true); + customType1.setStoreTermVectorPositions(true); + customType1.setStoreTermVectorOffsets(true); + + Field storedField = newField("stored", "stored", customType); document.add(storedField); - Field termVectorField = newField("termVector", "termVector", - Field.Store.NO, Field.Index.NOT_ANALYZED, - Field.TermVector.WITH_POSITIONS_OFFSETS); + Field termVectorField = newField("termVector", "termVector", customType1); document.add(termVectorField); for(int i=0;i<10;i++) writer.addDocument(document); @@ -175,12 +184,19 @@ Document document = new Document(); document = new Document(); - Field storedField = newField("stored", "stored", Store.YES, - Index.NO); + + FieldType customType = new FieldType(); + customType.setStored(true); + + FieldType customType1 = new FieldType(TextField.TYPE_UNSTORED); + customType1.setTokenized(false); + customType1.setStoreTermVectors(true); + customType1.setStoreTermVectorPositions(true); + customType1.setStoreTermVectorOffsets(true); + + Field storedField = newField("stored", "stored", customType); document.add(storedField); - Field termVectorField = newField("termVector", "termVector", - Store.NO, Index.NOT_ANALYZED, - TermVector.WITH_POSITIONS_OFFSETS); + Field termVectorField = newField("termVector", "termVector", customType1); document.add(termVectorField); for(int i=0;i<98;i++) writer.addDocument(document); @@ -223,13 +239,19 @@ Document document = new Document(); + FieldType customType = new FieldType(); + customType.setStored(true); + + FieldType customType1 = new FieldType(TextField.TYPE_UNSTORED); + customType1.setTokenized(false); + customType1.setStoreTermVectors(true); + customType1.setStoreTermVectorPositions(true); + customType1.setStoreTermVectorOffsets(true); + document = new Document(); - Field storedField = newField("stored", "stored", Field.Store.YES, - Field.Index.NO); + Field storedField = newField("stored", "stored", customType); document.add(storedField); - Field termVectorField = newField("termVector", "termVector", - Field.Store.NO, Field.Index.NOT_ANALYZED, - Field.TermVector.WITH_POSITIONS_OFFSETS); + Field termVectorField = newField("termVector", "termVector", customType1); document.add(termVectorField); for(int i=0;i<98;i++) writer.addDocument(document); @@ -292,8 +314,11 @@ IndexWriter iw = new IndexWriter(dir, conf); iw.setInfoStream(VERBOSE ? System.out : null); Document document = new Document(); - document.add(newField("tvtest", "a b c", Field.Store.NO, Field.Index.ANALYZED, - Field.TermVector.YES)); + + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStoreTermVectors(true); + + document.add(newField("tvtest", "a b c", customType)); for(int i=0;i<177;i++) iw.addDocument(document); iw.close(); Index: lucene/src/test/org/apache/lucene/index/Test2BTerms.java =================================================================== --- lucene/src/test/org/apache/lucene/index/Test2BTerms.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/Test2BTerms.java (working copy) @@ -177,9 +177,12 @@ Document doc = new Document(); final MyTokenStream ts = new MyTokenStream(random, TERMS_PER_DOC); - Field field = new Field("field", ts); - field.setIndexOptions(IndexOptions.DOCS_ONLY); - field.setOmitNorms(true); + + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + customType.setIndexOptions(IndexOptions.DOCS_ONLY); + customType.setOmitNorms(true); + Field field = new Field("field", customType, ts); doc.add(field); //w.setInfoStream(System.out); final int numDocs = (int) (TERM_COUNT/TERMS_PER_DOC); Index: lucene/src/test/org/apache/lucene/index/TestSegmentInfo.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestSegmentInfo.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestSegmentInfo.java (working copy) @@ -3,8 +3,8 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.store.Directory; import org.apache.lucene.util.LuceneTestCase; @@ -33,7 +33,9 @@ IndexWriter writer = new IndexWriter(dir, conf); writer.setInfoStream(VERBOSE ? System.out : null); Document doc = new Document(); - doc.add(new Field("a", "value", Store.YES, Index.ANALYZED)); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + doc.add(new Field("a", customType, "value")); writer.addDocument(doc); writer.close(); Index: lucene/src/test/org/apache/lucene/index/TestParallelReader.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestParallelReader.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestParallelReader.java (working copy) @@ -18,14 +18,13 @@ */ import java.io.IOException; -import java.util.Arrays; import java.util.Collection; import java.util.Random; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; -import org.apache.lucene.document.MapFieldSelector; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.search.BooleanClause.Occur; import org.apache.lucene.search.*; import org.apache.lucene.store.Directory; @@ -89,30 +88,6 @@ dir2.close(); } - public void testDocument() throws IOException { - Directory dir1 = getDir1(random); - Directory dir2 = getDir2(random); - ParallelReader pr = new ParallelReader(); - pr.add(IndexReader.open(dir1, false)); - pr.add(IndexReader.open(dir2, false)); - - Document doc11 = pr.document(0, new MapFieldSelector("f1")); - Document doc24 = pr.document(1, new MapFieldSelector(Arrays.asList("f4"))); - Document doc223 = pr.document(1, new MapFieldSelector("f2", "f3")); - - assertEquals(1, doc11.getFields().size()); - assertEquals(1, doc24.getFields().size()); - assertEquals(2, doc223.getFields().size()); - - assertEquals("v1", doc11.get("f1")); - assertEquals("v2", doc24.get("f4")); - assertEquals("v2", doc223.get("f2")); - assertEquals("v2", doc223.get("f3")); - pr.close(); - dir1.close(); - dir2.close(); - } - public void testIncompatibleIndexes() throws IOException { // two documents: Directory dir1 = getDir1(random); @@ -121,7 +96,10 @@ Directory dir2 = newDirectory(); IndexWriter w2 = new IndexWriter(dir2, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random))); Document d3 = new Document(); - d3.add(newField("f3", "v1", Field.Store.YES, Field.Index.ANALYZED)); + + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + d3.add(newField("f3", "v1", customType)); w2.addDocument(d3); w2.close(); @@ -179,7 +157,9 @@ setMergePolicy(newLogMergePolicy(10)) ); Document d = new Document(); - d.add(newField("f1", "v1", Field.Store.YES, Field.Index.ANALYZED)); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + d.add(newField("f1", "v1", customType)); modifier.addDocument(d); modifier.close(); @@ -189,7 +169,7 @@ setMergePolicy(newLogMergePolicy(10)) ); d = new Document(); - d.add(newField("f2", "v2", Field.Store.YES, Field.Index.ANALYZED)); + d.add(newField("f2", "v2", customType)); modifier.addDocument(d); modifier.close(); @@ -246,16 +226,18 @@ dir = newDirectory(); IndexWriter w = new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random))); Document d1 = new Document(); - d1.add(newField("f1", "v1", Field.Store.YES, Field.Index.ANALYZED)); - d1.add(newField("f2", "v1", Field.Store.YES, Field.Index.ANALYZED)); - d1.add(newField("f3", "v1", Field.Store.YES, Field.Index.ANALYZED)); - d1.add(newField("f4", "v1", Field.Store.YES, Field.Index.ANALYZED)); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + d1.add(newField("f1", "v1", customType)); + d1.add(newField("f2", "v1", customType)); + d1.add(newField("f3", "v1", customType)); + d1.add(newField("f4", "v1", customType)); w.addDocument(d1); Document d2 = new Document(); - d2.add(newField("f1", "v2", Field.Store.YES, Field.Index.ANALYZED)); - d2.add(newField("f2", "v2", Field.Store.YES, Field.Index.ANALYZED)); - d2.add(newField("f3", "v2", Field.Store.YES, Field.Index.ANALYZED)); - d2.add(newField("f4", "v2", Field.Store.YES, Field.Index.ANALYZED)); + d2.add(newField("f1", "v2", customType)); + d2.add(newField("f2", "v2", customType)); + d2.add(newField("f3", "v2", customType)); + d2.add(newField("f4", "v2", customType)); w.addDocument(d2); w.close(); @@ -276,12 +258,14 @@ Directory dir1 = newDirectory(); IndexWriter w1 = new IndexWriter(dir1, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random))); Document d1 = new Document(); - d1.add(newField("f1", "v1", Field.Store.YES, Field.Index.ANALYZED)); - d1.add(newField("f2", "v1", Field.Store.YES, Field.Index.ANALYZED)); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); + d1.add(newField("f1", "v1", customType)); + d1.add(newField("f2", "v1", customType)); w1.addDocument(d1); Document d2 = new Document(); - d2.add(newField("f1", "v2", Field.Store.YES, Field.Index.ANALYZED)); - d2.add(newField("f2", "v2", Field.Store.YES, Field.Index.ANALYZED)); + d2.add(newField("f1", "v2", customType)); + d2.add(newField("f2", "v2", customType)); w1.addDocument(d2); w1.close(); return dir1; @@ -289,14 +273,16 @@ private Directory getDir2(Random random) throws IOException { Directory dir2 = newDirectory(); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); IndexWriter w2 = new IndexWriter(dir2, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random))); Document d3 = new Document(); - d3.add(newField("f3", "v1", Field.Store.YES, Field.Index.ANALYZED)); - d3.add(newField("f4", "v1", Field.Store.YES, Field.Index.ANALYZED)); + d3.add(newField("f3", "v1", customType)); + d3.add(newField("f4", "v1", customType)); w2.addDocument(d3); Document d4 = new Document(); - d4.add(newField("f3", "v2", Field.Store.YES, Field.Index.ANALYZED)); - d4.add(newField("f4", "v2", Field.Store.YES, Field.Index.ANALYZED)); + d4.add(newField("f3", "v2", customType)); + d4.add(newField("f4", "v2", customType)); w2.addDocument(d4); w2.close(); return dir2; Index: lucene/src/test/org/apache/lucene/index/codecs/pulsing/Test10KPulsings.java =================================================================== --- lucene/src/test/org/apache/lucene/index/codecs/pulsing/Test10KPulsings.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/codecs/pulsing/Test10KPulsings.java (working copy) @@ -26,6 +26,8 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.FieldInfo.IndexOptions; import org.apache.lucene.index.IndexReader; @@ -60,14 +62,15 @@ newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setCodecProvider(cp)); Document document = new Document(); - Field field = newField("field", "", Field.Store.YES, Field.Index.ANALYZED); + FieldType ft = new FieldType(TextField.TYPE_STORED); switch(_TestUtil.nextInt(random, 0, 2)) { - case 0: field.setIndexOptions(IndexOptions.DOCS_ONLY); break; - case 1: field.setIndexOptions(IndexOptions.DOCS_AND_FREQS); break; - default: field.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS); break; + case 0: ft.setIndexOptions(IndexOptions.DOCS_ONLY); break; + case 1: ft.setIndexOptions(IndexOptions.DOCS_AND_FREQS); break; + default: ft.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS); break; } + Field field = newField("field", "", ft); document.add(field); NumberFormat df = new DecimalFormat("00000", new DecimalFormatSymbols(Locale.ENGLISH)); @@ -111,14 +114,15 @@ newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setCodecProvider(cp)); Document document = new Document(); - Field field = newField("field", "", Field.Store.YES, Field.Index.ANALYZED); + FieldType ft = new FieldType(TextField.TYPE_STORED); switch(_TestUtil.nextInt(random, 0, 2)) { - case 0: field.setIndexOptions(IndexOptions.DOCS_ONLY); break; - case 1: field.setIndexOptions(IndexOptions.DOCS_AND_FREQS); break; - default: field.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS); break; + case 0: ft.setIndexOptions(IndexOptions.DOCS_ONLY); break; + case 1: ft.setIndexOptions(IndexOptions.DOCS_AND_FREQS); break; + default: ft.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS); break; } + Field field = newField("field", "", ft); document.add(field); NumberFormat df = new DecimalFormat("00000", new DecimalFormatSymbols(Locale.ENGLISH)); Index: lucene/src/test/org/apache/lucene/index/codecs/preflex/TestSurrogates.java =================================================================== --- lucene/src/test/org/apache/lucene/index/codecs/preflex/TestSurrogates.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/codecs/preflex/TestSurrogates.java (working copy) @@ -303,7 +303,9 @@ uniqueTerms.add(term); fieldTerms.add(new Term(field, term)); Document doc = new Document(); - doc.add(newField(field, term, Field.Store.NO, Field.Index.NOT_ANALYZED)); + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setTokenized(false); + doc.add(newField(field, term, customType)); w.addDocument(doc); } uniqueTermCount += uniqueTerms.size(); Index: lucene/src/test/org/apache/lucene/index/TestDeletionPolicy.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestDeletionPolicy.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestDeletionPolicy.java (working copy) @@ -26,6 +26,7 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriterConfig.OpenMode; import org.apache.lucene.search.DefaultSimilarity; import org.apache.lucene.search.IndexSearcher; @@ -853,7 +854,7 @@ private void addDoc(IndexWriter writer) throws IOException { Document doc = new Document(); - doc.add(newField("content", "aaa", Field.Store.NO, Field.Index.ANALYZED)); + doc.add(newField("content", "aaa", TextField.TYPE_UNSTORED)); writer.addDocument(doc); } } Index: lucene/src/test/org/apache/lucene/index/TestPerFieldCodecSupport.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestPerFieldCodecSupport.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestPerFieldCodecSupport.java (working copy) @@ -22,7 +22,8 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; -import org.apache.lucene.document.Field.Index; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.CheckIndex.Status; import org.apache.lucene.index.CheckIndex.Status.SegmentInfoStatus; import org.apache.lucene.index.IndexWriterConfig.OpenMode; @@ -63,7 +64,7 @@ private void addDocs(IndexWriter writer, int numDocs) throws IOException { for (int i = 0; i < numDocs; i++) { Document doc = new Document(); - doc.add(newField("content", "aaa", Field.Store.NO, Field.Index.ANALYZED)); + doc.add(newField("content", "aaa", TextField.TYPE_UNSTORED)); writer.addDocument(doc); } } @@ -71,16 +72,18 @@ private void addDocs2(IndexWriter writer, int numDocs) throws IOException { for (int i = 0; i < numDocs; i++) { Document doc = new Document(); - doc.add(newField("content", "bbb", Field.Store.NO, Field.Index.ANALYZED)); + doc.add(newField("content", "bbb", TextField.TYPE_UNSTORED)); writer.addDocument(doc); } } private void addDocs3(IndexWriter writer, int numDocs) throws IOException { + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setStored(true); for (int i = 0; i < numDocs; i++) { Document doc = new Document(); - doc.add(newField("content", "ccc", Field.Store.NO, Field.Index.ANALYZED)); - doc.add(newField("id", "" + i, Field.Store.YES, Field.Index.ANALYZED)); + doc.add(newField("content", "ccc", TextField.TYPE_UNSTORED)); + doc.add(newField("id", "" + i, customType)); writer.addDocument(doc); } } @@ -271,8 +274,6 @@ @Test public void testStressPerFieldCodec() throws IOException { Directory dir = newDirectory(random); - Index[] indexValue = new Index[] { Index.ANALYZED, Index.ANALYZED_NO_NORMS, - Index.NOT_ANALYZED, Index.NOT_ANALYZED_NO_NORMS }; final int docsPerRound = 97; int numRounds = atLeast(1); for (int i = 0; i < numRounds; i++) { @@ -297,9 +298,11 @@ for (int j = 0; j < docsPerRound; j++) { final Document doc = new Document(); for (int k = 0; k < num; k++) { + FieldType customType = new FieldType(TextField.TYPE_UNSTORED); + customType.setTokenized(random.nextBoolean()); + customType.setOmitNorms(random.nextBoolean()); Field field = newField("" + k, _TestUtil - .randomRealisticUnicodeString(random, 128), indexValue[random - .nextInt(indexValue.length)]); + .randomRealisticUnicodeString(random, 128), customType); doc.add(field); } writer.addDocument(doc); Index: lucene/src/test/org/apache/lucene/index/TestSegmentReader.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestSegmentReader.java (revision 1158028) +++ lucene/src/test/org/apache/lucene/index/TestSegmentReader.java (working copy) @@ -26,7 +26,6 @@ import org.apache.lucene.util.BytesRef; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Fieldable; import org.apache.lucene.store.Directory; import org.apache.lucene.store.IOContext; import org.apache.lucene.store.IOContext.Context; @@ -68,8 +67,8 @@ //There are 2 unstored fields on the document that are not preserved across writing assertTrue(DocHelper.numFields(result) == DocHelper.numFields(testDoc) - DocHelper.unstored.size()); - List fields = result.getFields(); - for (final Fieldable field : fields ) { + List fields = result.getFields(); + for (final IndexableField field : fields ) { assertTrue(field != null); assertTrue(DocHelper.nameValues.containsKey(field.name())); } @@ -176,9 +175,9 @@ public static void checkNorms(IndexReader reader) throws IOException { // test omit norms for (int i=0; i @@ -111,16 +110,16 @@ } /** - * Invoked before indexing a Fieldable instance if + * Invoked before indexing a IndexableField instance if * terms have already been added to that field. This allows custom * analyzers to place an automatic position increment gap between - * Fieldable instances using the same field name. The default value + * IndexbleField instances using the same field name. The default value * position increment gap is 0. With a 0 position increment gap and * the typical default token position increment of 1, all terms in a field, - * including across Fieldable instances, are in successive positions, allowing - * exact PhraseQuery matches, for instance, across Fieldable instance boundaries. + * including across IndexableField instances, are in successive positions, allowing + * exact PhraseQuery matches, for instance, across IndexableField instance boundaries. * - * @param fieldName Fieldable name being indexed. + * @param fieldName IndexableField name being indexed. * @return position increment gap, added to the next token emitted from {@link #tokenStream(String,Reader)} */ public int getPositionIncrementGap(String fieldName) { @@ -138,11 +137,12 @@ * @param field the field just indexed * @return offset gap, added to the next token emitted from {@link #tokenStream(String,Reader)} */ - public int getOffsetGap(Fieldable field) { - if (field.isTokenized()) + public int getOffsetGap(IndexableField field) { + if (field.tokenized()) { return 1; - else + } else { return 0; + } } /** Frees persistent resources used by this Analyzer */ Index: lucene/src/java/org/apache/lucene/analysis/package.html =================================================================== --- lucene/src/java/org/apache/lucene/analysis/package.html (revision 1158028) +++ lucene/src/java/org/apache/lucene/analysis/package.html (working copy) @@ -120,7 +120,7 @@ Applications usually do not invoke analysis – Lucene does it for them:

    • At indexing, as a consequence of - {@link org.apache.lucene.index.IndexWriter#addDocument(org.apache.lucene.document.Document) addDocument(doc)}, + {@link org.apache.lucene.index.IndexWriter#addDocument(Iterable) addDocument(doc)}, the Analyzer in effect for indexing is invoked for each indexed field of the added document.
    • At search, a QueryParser may invoke the Analyzer during parsing. Note that for some queries, analysis does not @@ -170,7 +170,7 @@

      Field Section Boundaries

      - When {@link org.apache.lucene.document.Document#add(org.apache.lucene.document.Fieldable) document.add(field)} + When {@link org.apache.lucene.document.Document#add(org.apache.lucene.index.IndexableField) document.add(field)} is called multiple times for the same field name, we could say that each such call creates a new section for that field in that document. In fact, a separate call to Index: lucene/src/java/org/apache/lucene/index/DocInverterPerField.java =================================================================== --- lucene/src/java/org/apache/lucene/index/DocInverterPerField.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/DocInverterPerField.java (working copy) @@ -19,7 +19,6 @@ import java.io.IOException; import java.io.Reader; -import org.apache.lucene.document.Fieldable; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.tokenattributes.OffsetAttribute; import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute; @@ -61,27 +60,32 @@ } @Override - public void processFields(final Fieldable[] fields, + public void processFields(final IndexableField[] fields, final int count) throws IOException { - fieldState.reset(docState.doc.getBoost()); + fieldState.reset(); final boolean doInvert = consumer.start(fields, count); for(int i=0;i 0) fieldState.position += docState.analyzer == null ? 0 : docState.analyzer.getPositionIncrementGap(fieldInfo.name); - if (!field.isTokenized()) { // un-tokenized field - String stringValue = field.stringValue(); + // TODO (LUCENE-2309): this analysis logic should be + // outside of indexer -- field should simply give us + // a TokenStream, even for multi-valued fields + + if (!field.tokenized()) { // un-tokenized field + final String stringValue = field.stringValue(); + assert stringValue != null; final int valueLength = stringValue.length(); parent.singleToken.reinit(stringValue, 0, valueLength); fieldState.attributeSource = parent.singleToken; @@ -103,17 +107,17 @@ final TokenStream stream; final TokenStream streamValue = field.tokenStreamValue(); - if (streamValue != null) + if (streamValue != null) { stream = streamValue; - else { + } else { // the field does not have a TokenStream, // so we have to obtain one from the analyzer final Reader reader; // find or make Reader final Reader readerValue = field.readerValue(); - if (readerValue != null) + if (readerValue != null) { reader = readerValue; - else { + } else { String stringValue = field.stringValue(); if (stringValue == null) { throw new IllegalArgumentException("field must have either TokenStream, String or Reader value"); @@ -189,7 +193,7 @@ } fieldState.offset += docState.analyzer == null ? 0 : docState.analyzer.getOffsetGap(field); - fieldState.boost *= field.getBoost(); + fieldState.boost *= field.boost(); } // LUCENE-2387: don't hang onto the field, so GC can Index: lucene/src/java/org/apache/lucene/index/FieldsReader.java =================================================================== --- lucene/src/java/org/apache/lucene/index/FieldsReader.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/FieldsReader.java (working copy) @@ -17,13 +17,8 @@ * limitations under the License. */ -import org.apache.lucene.analysis.TokenStream; -import org.apache.lucene.document.AbstractField; -import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; -import org.apache.lucene.document.FieldSelector; -import org.apache.lucene.document.FieldSelectorResult; -import org.apache.lucene.document.Fieldable; +import java.io.IOException; + import org.apache.lucene.document.NumericField; import org.apache.lucene.store.AlreadyClosedException; import org.apache.lucene.store.BufferedIndexInput; @@ -49,7 +44,8 @@ private final static int FORMAT_SIZE = 4; private final FieldInfos fieldInfos; - + private CloseableThreadLocal fieldsStreamTL = new CloseableThreadLocal(); + // The main fieldStream, used only for cloning. private final IndexInput cloneableFieldsStream; @@ -68,7 +64,6 @@ // file. This will be 0 if we have our own private file. private int docStoreOffset; - private CloseableThreadLocal fieldsStreamTL = new CloseableThreadLocal(); private boolean isOriginal = false; /** Returns a cloned FieldsReader that shares open @@ -200,50 +195,52 @@ indexStream.seek(FORMAT_SIZE + (docID + docStoreOffset) * 8L); } - public final Document doc(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException { + public final void visitDocument(int n, StoredFieldVisitor visitor) throws CorruptIndexException, IOException { seekIndex(n); - long position = indexStream.readLong(); - fieldsStream.seek(position); + fieldsStream.seek(indexStream.readLong()); - Document doc = new Document(); - int numFields = fieldsStream.readVInt(); - out: for (int i = 0; i < numFields; i++) { + final int numFields = fieldsStream.readVInt(); + for (int fieldIDX = 0; fieldIDX < numFields; fieldIDX++) { int fieldNumber = fieldsStream.readVInt(); - FieldInfo fi = fieldInfos.fieldInfo(fieldNumber); - FieldSelectorResult acceptField = fieldSelector == null ? FieldSelectorResult.LOAD : fieldSelector.accept(fi.name); + FieldInfo fieldInfo = fieldInfos.fieldInfo(fieldNumber); int bits = fieldsStream.readByte() & 0xFF; - assert bits <= (FieldsWriter.FIELD_IS_NUMERIC_MASK | FieldsWriter.FIELD_IS_TOKENIZED | FieldsWriter.FIELD_IS_BINARY): "bits=" + Integer.toHexString(bits); + assert bits <= (FieldsWriter.FIELD_IS_NUMERIC_MASK | FieldsWriter.FIELD_IS_BINARY): "bits=" + Integer.toHexString(bits); - boolean tokenize = (bits & FieldsWriter.FIELD_IS_TOKENIZED) != 0; - boolean binary = (bits & FieldsWriter.FIELD_IS_BINARY) != 0; + final boolean binary = (bits & FieldsWriter.FIELD_IS_BINARY) != 0; final int numeric = bits & FieldsWriter.FIELD_IS_NUMERIC_MASK; - switch (acceptField) { - case LOAD: - addField(doc, fi, binary, tokenize, numeric); + final boolean doStop; + if (binary) { + final int numBytes = fieldsStream.readVInt(); + doStop = visitor.binaryField(fieldInfo, fieldsStream, numBytes); + } else if (numeric != 0) { + switch(numeric) { + case FieldsWriter.FIELD_IS_NUMERIC_INT: + doStop = visitor.intField(fieldInfo, fieldsStream.readInt()); break; - case LOAD_AND_BREAK: - addField(doc, fi, binary, tokenize, numeric); - break out; //Get out of this loop - case LAZY_LOAD: - addFieldLazy(doc, fi, binary, tokenize, true, numeric); + case FieldsWriter.FIELD_IS_NUMERIC_LONG: + doStop = visitor.longField(fieldInfo, fieldsStream.readLong()); break; - case LATENT: - addFieldLazy(doc, fi, binary, tokenize, false, numeric); + case FieldsWriter.FIELD_IS_NUMERIC_FLOAT: + doStop = visitor.floatField(fieldInfo, Float.intBitsToFloat(fieldsStream.readInt())); break; - case SIZE: - skipFieldBytes(addFieldSize(doc, fi, binary, numeric)); + case FieldsWriter.FIELD_IS_NUMERIC_DOUBLE: + doStop = visitor.doubleField(fieldInfo, Double.longBitsToDouble(fieldsStream.readLong())); break; - case SIZE_AND_BREAK: - addFieldSize(doc, fi, binary, numeric); - break out; //Get out of this loop default: - skipField(numeric); + throw new FieldReaderException("Invalid numeric type: " + Integer.toHexString(numeric)); + } + } else { + // Text: + final int numUTF8Bytes = fieldsStream.readVInt(); + doStop = visitor.stringField(fieldInfo, fieldsStream, numUTF8Bytes); } - } - return doc; + if (doStop) { + return; + } + } } /** Returns the length in bytes of each raw document in a @@ -300,225 +297,4 @@ private void skipFieldBytes(int toRead) throws IOException { fieldsStream.seek(fieldsStream.getFilePointer() + toRead); } - - private NumericField loadNumericField(FieldInfo fi, int numeric) throws IOException { - assert numeric != 0; - switch(numeric) { - case FieldsWriter.FIELD_IS_NUMERIC_INT: - return new NumericField(fi.name, Field.Store.YES, fi.isIndexed).setIntValue(fieldsStream.readInt()); - case FieldsWriter.FIELD_IS_NUMERIC_LONG: - return new NumericField(fi.name, Field.Store.YES, fi.isIndexed).setLongValue(fieldsStream.readLong()); - case FieldsWriter.FIELD_IS_NUMERIC_FLOAT: - return new NumericField(fi.name, Field.Store.YES, fi.isIndexed).setFloatValue(Float.intBitsToFloat(fieldsStream.readInt())); - case FieldsWriter.FIELD_IS_NUMERIC_DOUBLE: - return new NumericField(fi.name, Field.Store.YES, fi.isIndexed).setDoubleValue(Double.longBitsToDouble(fieldsStream.readLong())); - default: - throw new FieldReaderException("Invalid numeric type: " + Integer.toHexString(numeric)); - } - } - - private void addFieldLazy(Document doc, FieldInfo fi, boolean binary, boolean tokenize, boolean cacheResult, int numeric) throws IOException { - final AbstractField f; - if (binary) { - int toRead = fieldsStream.readVInt(); - long pointer = fieldsStream.getFilePointer(); - f = new LazyField(fi.name, Field.Store.YES, toRead, pointer, binary, cacheResult); - //Need to move the pointer ahead by toRead positions - fieldsStream.seek(pointer + toRead); - } else if (numeric != 0) { - f = loadNumericField(fi, numeric); - } else { - Field.Store store = Field.Store.YES; - Field.Index index = Field.Index.toIndex(fi.isIndexed, tokenize); - Field.TermVector termVector = Field.TermVector.toTermVector(fi.storeTermVector, fi.storeOffsetWithTermVector, fi.storePositionWithTermVector); - - int length = fieldsStream.readVInt(); - long pointer = fieldsStream.getFilePointer(); - //Skip ahead of where we are by the length of what is stored - fieldsStream.seek(pointer+length); - f = new LazyField(fi.name, store, index, termVector, length, pointer, binary, cacheResult); - } - - f.setOmitNorms(fi.omitNorms); - f.setIndexOptions(fi.indexOptions); - doc.add(f); - } - - private void addField(Document doc, FieldInfo fi, boolean binary, boolean tokenize, int numeric) throws CorruptIndexException, IOException { - final AbstractField f; - - if (binary) { - int toRead = fieldsStream.readVInt(); - final byte[] b = new byte[toRead]; - fieldsStream.readBytes(b, 0, b.length); - f = new Field(fi.name, b); - } else if (numeric != 0) { - f = loadNumericField(fi, numeric); - } else { - Field.Index index = Field.Index.toIndex(fi.isIndexed, tokenize); - Field.TermVector termVector = Field.TermVector.toTermVector(fi.storeTermVector, fi.storeOffsetWithTermVector, fi.storePositionWithTermVector); - f = new Field(fi.name, // name - fieldsStream.readString(), // read value - Field.Store.YES, - index, - termVector); - } - - f.setIndexOptions(fi.indexOptions); - f.setOmitNorms(fi.omitNorms); - doc.add(f); - } - - // Add the size of field as a byte[] containing the 4 bytes of the integer byte size (high order byte first; char = 2 bytes) - // Read just the size -- caller must skip the field content to continue reading fields - // Return the size in bytes or chars, depending on field type - private int addFieldSize(Document doc, FieldInfo fi, boolean binary, int numeric) throws IOException { - final int bytesize, size; - switch(numeric) { - case 0: - size = fieldsStream.readVInt(); - bytesize = binary ? size : 2*size; - break; - case FieldsWriter.FIELD_IS_NUMERIC_INT: - case FieldsWriter.FIELD_IS_NUMERIC_FLOAT: - size = bytesize = 4; - break; - case FieldsWriter.FIELD_IS_NUMERIC_LONG: - case FieldsWriter.FIELD_IS_NUMERIC_DOUBLE: - size = bytesize = 8; - break; - default: - throw new FieldReaderException("Invalid numeric type: " + Integer.toHexString(numeric)); - } - byte[] sizebytes = new byte[4]; - sizebytes[0] = (byte) (bytesize>>>24); - sizebytes[1] = (byte) (bytesize>>>16); - sizebytes[2] = (byte) (bytesize>>> 8); - sizebytes[3] = (byte) bytesize ; - doc.add(new Field(fi.name, sizebytes)); - return size; - } - - /** - * A Lazy implementation of Fieldable that defers loading of fields until asked for, instead of when the Document is - * loaded. - */ - private class LazyField extends AbstractField implements Fieldable { - private int toRead; - private long pointer; - private final boolean cacheResult; - - public LazyField(String name, Field.Store store, int toRead, long pointer, boolean isBinary, boolean cacheResult) { - super(name, store, Field.Index.NO, Field.TermVector.NO); - this.toRead = toRead; - this.pointer = pointer; - this.isBinary = isBinary; - this.cacheResult = cacheResult; - if (isBinary) - binaryLength = toRead; - lazy = true; - } - - public LazyField(String name, Field.Store store, Field.Index index, Field.TermVector termVector, int toRead, long pointer, boolean isBinary, boolean cacheResult) { - super(name, store, index, termVector); - this.toRead = toRead; - this.pointer = pointer; - this.isBinary = isBinary; - this.cacheResult = cacheResult; - if (isBinary) - binaryLength = toRead; - lazy = true; - } - - private IndexInput getFieldStream() { - IndexInput localFieldsStream = fieldsStreamTL.get(); - if (localFieldsStream == null) { - localFieldsStream = (IndexInput) cloneableFieldsStream.clone(); - fieldsStreamTL.set(localFieldsStream); - } - return localFieldsStream; - } - - /** The value of the field as a Reader, or null. If null, the String value, - * binary value, or TokenStream value is used. Exactly one of stringValue(), - * readerValue(), getBinaryValue(), and tokenStreamValue() must be set. */ - public Reader readerValue() { - ensureOpen(); - return null; - } - - /** The value of the field as a TokenStream, or null. If null, the Reader value, - * String value, or binary value is used. Exactly one of stringValue(), - * readerValue(), getBinaryValue(), and tokenStreamValue() must be set. */ - public TokenStream tokenStreamValue() { - ensureOpen(); - return null; - } - - /** The value of the field as a String, or null. If null, the Reader value, - * binary value, or TokenStream value is used. Exactly one of stringValue(), - * readerValue(), getBinaryValue(), and tokenStreamValue() must be set. */ - public String stringValue() { - ensureOpen(); - if (isBinary) - return null; - else { - if (fieldsData == null) { - String result = null; - IndexInput localFieldsStream = getFieldStream(); - try { - localFieldsStream.seek(pointer); - byte[] bytes = new byte[toRead]; - localFieldsStream.readBytes(bytes, 0, toRead); - result = new String(bytes, "UTF-8"); - } catch (IOException e) { - throw new FieldReaderException(e); - } - if (cacheResult == true){ - fieldsData = result; - } - return result; - } else { - return (String) fieldsData; - } - } - } - - @Override - public byte[] getBinaryValue(byte[] result) { - ensureOpen(); - - if (isBinary) { - if (fieldsData == null) { - // Allocate new buffer if result is null or too small - final byte[] b; - if (result == null || result.length < toRead) - b = new byte[toRead]; - else - b = result; - - IndexInput localFieldsStream = getFieldStream(); - - // Throw this IOException since IndexReader.document does so anyway, so probably not that big of a change for people - // since they are already handling this exception when getting the document - try { - localFieldsStream.seek(pointer); - localFieldsStream.readBytes(b, 0, toRead); - } catch (IOException e) { - throw new FieldReaderException(e); - } - - binaryOffset = 0; - binaryLength = toRead; - if (cacheResult == true){ - fieldsData = b; - } - return b; - } else { - return (byte[]) fieldsData; - } - } else - return null; - } - } } Index: lucene/src/java/org/apache/lucene/index/FieldsWriter.java =================================================================== --- lucene/src/java/org/apache/lucene/index/FieldsWriter.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/FieldsWriter.java (working copy) @@ -17,19 +17,16 @@ */ import java.io.IOException; -import java.util.List; -import org.apache.lucene.document.Document; -import org.apache.lucene.document.Fieldable; -import org.apache.lucene.document.NumericField; import org.apache.lucene.store.Directory; import org.apache.lucene.store.IOContext; import org.apache.lucene.store.IndexInput; import org.apache.lucene.store.IndexOutput; +import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IOUtils; final class FieldsWriter { - static final int FIELD_IS_TOKENIZED = 1 << 0; + // NOTE: bit 0 is free here! You can steal it! static final int FIELD_IS_BINARY = 1 << 1; // the old bit 1 << 2 was compressed, is now left out @@ -138,15 +135,17 @@ } } - final void writeField(int fieldNumber, Fieldable field) throws IOException { + final void writeField(int fieldNumber, IndexableField field) throws IOException { fieldsStream.writeVInt(fieldNumber); int bits = 0; - if (field.isTokenized()) - bits |= FIELD_IS_TOKENIZED; - if (field.isBinary()) - bits |= FIELD_IS_BINARY; - if (field instanceof NumericField) { - switch (((NumericField) field).getDataType()) { + final BytesRef bytes; + final String string; + // TODO: maybe a field should serialize itself? + // this way we don't bake into indexer all these + // specific encodings for different fields? and apps + // can customize... + if (field.numeric()) { + switch (field.numericDataType()) { case INT: bits |= FIELD_IS_NUMERIC_INT; break; case LONG: @@ -158,23 +157,31 @@ default: assert false : "Should never get here"; } + string = null; + bytes = null; + } else { + bytes = field.binaryValue(); + if (bytes != null) { + bits |= FIELD_IS_BINARY; + string = null; + } else { + string = field.stringValue(); + } } + fieldsStream.writeByte((byte) bits); - if (field.isBinary()) { - final byte[] data; - final int len; - final int offset; - data = field.getBinaryValue(); - len = field.getBinaryLength(); - offset = field.getBinaryOffset(); - - fieldsStream.writeVInt(len); - fieldsStream.writeBytes(data, offset, len); - } else if (field instanceof NumericField) { - final NumericField nf = (NumericField) field; - final Number n = nf.getNumericValue(); - switch (nf.getDataType()) { + if (bytes != null) { + fieldsStream.writeVInt(bytes.length); + fieldsStream.writeBytes(bytes.bytes, bytes.offset, bytes.length); + } else if (string != null) { + fieldsStream.writeString(field.stringValue()); + } else { + final Number n = field.numericValue(); + if (n == null) { + throw new IllegalArgumentException("field " + field.name() + " is stored but does not have binaryValue, stringValue nor numericValue"); + } + switch (field.numericDataType()) { case INT: fieldsStream.writeInt(n.intValue()); break; case LONG: @@ -186,8 +193,6 @@ default: assert false : "Should never get here"; } - } else { - fieldsStream.writeString(field.stringValue()); } } @@ -207,21 +212,21 @@ assert fieldsStream.getFilePointer() == position; } - final void addDocument(Document doc, FieldInfos fieldInfos) throws IOException { + final void addDocument(Iterable doc, FieldInfos fieldInfos) throws IOException { indexStream.writeLong(fieldsStream.getFilePointer()); int storedCount = 0; - List fields = doc.getFields(); - for (Fieldable field : fields) { - if (field.isStored()) - storedCount++; + for (IndexableField field : doc) { + if (field.stored()) { + storedCount++; + } } fieldsStream.writeVInt(storedCount); - - for (Fieldable field : fields) { - if (field.isStored()) + for (IndexableField field : doc) { + if (field.stored()) { writeField(fieldInfos.fieldNumber(field.name()), field); + } } } } Index: lucene/src/java/org/apache/lucene/index/values/IntsImpl.java =================================================================== --- lucene/src/java/org/apache/lucene/index/values/IntsImpl.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/values/IntsImpl.java (working copy) @@ -21,7 +21,6 @@ import java.util.concurrent.atomic.AtomicLong; import org.apache.lucene.index.IndexFileNames; -import org.apache.lucene.index.values.IndexDocValuesArray; import org.apache.lucene.index.values.IndexDocValues.Source; import org.apache.lucene.index.values.IndexDocValues.SourceEnum; import org.apache.lucene.index.values.IndexDocValuesArray.ByteValues; @@ -319,7 +318,7 @@ try { input = (IndexInput) datIn.clone(); input.seek(CodecUtil.headerLength(CODEC_NAME) + 1); - source = loadFixedSource(type, input, numDocs); + source = loadFixedSource(type, input, numDocs); success = true; return source; } finally { Index: lucene/src/java/org/apache/lucene/index/values/PerDocFieldValues.java =================================================================== --- lucene/src/java/org/apache/lucene/index/values/PerDocFieldValues.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/values/PerDocFieldValues.java (working copy) @@ -19,14 +19,12 @@ import java.util.Comparator; import org.apache.lucene.document.IndexDocValuesField; -import org.apache.lucene.document.Fieldable; import org.apache.lucene.index.codecs.DocValuesConsumer; import org.apache.lucene.util.BytesRef; /** * Per document and field values consumed by {@link DocValuesConsumer}. * @see IndexDocValuesField - * @see Fieldable#setDocValues(PerDocFieldValues) * * @lucene.experimental */ @@ -91,11 +89,10 @@ /** * Sets the {@link ValueType} */ - public void setType(ValueType type); + public void setDocValuesType(ValueType type); /** * Returns the {@link ValueType} */ - public ValueType type(); - -} \ No newline at end of file + public ValueType docValuesType(); +} Index: lucene/src/java/org/apache/lucene/index/IndexableField.java =================================================================== --- lucene/src/java/org/apache/lucene/index/IndexableField.java (revision 0) +++ lucene/src/java/org/apache/lucene/index/IndexableField.java (revision 1160484) @@ -0,0 +1,104 @@ +package org.apache.lucene.index; + +/** + * 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. + */ + +import java.io.Reader; + +import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.document.NumericField; +import org.apache.lucene.index.FieldInfo.IndexOptions; +import org.apache.lucene.index.values.PerDocFieldValues; +import org.apache.lucene.index.values.ValueType; +import org.apache.lucene.util.BytesRef; + +// TODO: how to handle versioning here...? + +// TODO: we need to break out separate StoredField... + +/** Represents a single field for indexing. IndexWriter + * consumes Iterable as a document. + * + * @lucene.experimental */ + +public interface IndexableField { + + // TODO: add attrs to this API? + + /* Field name */ + public String name(); + + // NOTE: if doc/field impl has the notion of "doc level boost" + // it must be multiplied in w/ this field's boost + + /** Field boost (you must pre-multiply in any doc boost). */ + public float boost(); + + /* True if the field's value should be stored */ + public boolean stored(); + + /* Non-null if this field has a binary value */ + public BytesRef binaryValue(); + + /* Non-null if this field has a string value */ + public String stringValue(); + + /* Non-null if this field has a Reader value */ + public Reader readerValue(); + + /* Non-null if this field has a pre-tokenized ({@link TokenStream}) value */ + public TokenStream tokenStreamValue(); + + // Numeric field: + /* True if this field is numeric */ + public boolean numeric(); + + /* Numeric {@link NumericField.DataType}; only used if + * the field is numeric */ + public NumericField.DataType numericDataType(); + + /* Numeric value; only used if the field is numeric */ + public Number numericValue(); + + /* True if this field should be indexed (inverted) */ + public boolean indexed(); + + /* True if this field's value should be analyzed */ + public boolean tokenized(); + + /* True if norms should not be indexed */ + public boolean omitNorms(); + + /* {@link IndexOptions}, describing what should be + * recorded into the inverted index */ + public IndexOptions indexOptions(); + + /* True if term vectors should be indexed */ + public boolean storeTermVectors(); + + /* True if term vector offsets should be indexed */ + public boolean storeTermVectorOffsets(); + + /* True if term vector positions should be indexed */ + public boolean storeTermVectorPositions(); + + /* Non-null if doc values should be indexed */ + public PerDocFieldValues docValues(); + + /* DocValues type; only used if docValues is non-null */ + public ValueType docValuesType(); +} Property changes on: lucene/src/java/org/apache/lucene/index/IndexableField.java ___________________________________________________________________ Added: svn:eol-style + native Index: lucene/src/java/org/apache/lucene/index/PersistentSnapshotDeletionPolicy.java =================================================================== --- lucene/src/java/org/apache/lucene/index/PersistentSnapshotDeletionPolicy.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/PersistentSnapshotDeletionPolicy.java (working copy) @@ -25,9 +25,7 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; -import org.apache.lucene.document.Fieldable; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; +import org.apache.lucene.document.FieldType; import org.apache.lucene.index.IndexWriterConfig.OpenMode; import org.apache.lucene.store.Directory; import org.apache.lucene.store.LockObtainFailedException; @@ -71,12 +69,11 @@ // index is allowed to have exactly one document or 0. if (numDocs == 1) { Document doc = r.document(r.maxDoc() - 1); - Field sid = doc.getField(SNAPSHOTS_ID); - if (sid == null) { + if (doc.getField(SNAPSHOTS_ID) == null) { throw new IllegalStateException("directory is not a valid snapshots store!"); } doc.removeField(SNAPSHOTS_ID); - for (Fieldable f : doc.getFields()) { + for (IndexableField f : doc) { snapshots.put(f.name(), f.stringValue()); } } else if (numDocs != 0) { @@ -189,12 +186,14 @@ private void persistSnapshotInfos(String id, String segment) throws IOException { writer.deleteAll(); Document d = new Document(); - d.add(new Field(SNAPSHOTS_ID, "", Store.YES, Index.NO)); + FieldType ft = new FieldType(); + ft.setStored(true); + d.add(new Field(SNAPSHOTS_ID, ft, "")); for (Entry e : super.getSnapshots().entrySet()) { - d.add(new Field(e.getKey(), e.getValue(), Store.YES, Index.NO)); + d.add(new Field(e.getKey(), ft, e.getValue())); } if (id != null) { - d.add(new Field(id, segment, Store.YES, Index.NO)); + d.add(new Field(id, ft, segment)); } writer.addDocument(d); writer.commit(); Index: lucene/src/java/org/apache/lucene/index/DocFieldProcessor.java =================================================================== --- lucene/src/java/org/apache/lucene/index/DocFieldProcessor.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/DocFieldProcessor.java (working copy) @@ -22,15 +22,13 @@ import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; -import java.util.List; import java.util.Map; -import org.apache.lucene.document.Document; -import org.apache.lucene.document.Fieldable; import org.apache.lucene.index.DocumentsWriterPerThread.DocState; import org.apache.lucene.index.codecs.Codec; -import org.apache.lucene.index.codecs.PerDocConsumer; import org.apache.lucene.index.codecs.DocValuesConsumer; +import org.apache.lucene.index.codecs.PerDocConsumer; +import org.apache.lucene.index.values.PerDocFieldValues; import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.IOUtils; @@ -199,22 +197,16 @@ consumer.startDocument(); fieldsWriter.startDocument(); - final Document doc = docState.doc; - fieldCount = 0; final int thisFieldGen = fieldGen++; - final List docFields = doc.getFields(); - final int numDocFields = docFields.size(); - // Absorb any new fields first seen in this document. // Also absorb any changes to fields we had already // seen before (eg suddenly turning on norms or // vectors, etc.): - for(int i=0;i= fieldHash.length/2) + if (totalFieldCount >= fieldHash.length/2) { rehash(); + } } else { - fieldInfos.addOrUpdate(fp.fieldInfo.name, field.isIndexed(), field.isTermVectorStored(), - field.isStorePositionWithTermVector(), field.isStoreOffsetWithTermVector(), - field.getOmitNorms(), false, field.getIndexOptions(), field.docValuesType()); + fieldInfos.addOrUpdate(fp.fieldInfo.name, field.indexed(), field.storeTermVectors(), + field.storeTermVectorPositions(), field.storeTermVectorOffsets(), + field.omitNorms(), false, field.indexOptions(), field.docValuesType()); } if (thisFieldGen != fp.lastGen) { @@ -266,12 +259,12 @@ fp.addField(field); - if (field.isStored()) { + if (field.stored()) { fieldsWriter.addField(field, fp.fieldInfo); } - if (field.hasDocValues()) { - final DocValuesConsumer docValuesConsumer = docValuesConsumer(docState, fp.fieldInfo); - docValuesConsumer.add(docState.docID, field.getDocValues()); + final PerDocFieldValues docValues = field.docValues(); + if (docValues != null) { + docValuesConsumer(docState, fp.fieldInfo).add(docState.docID, docValues); } } @@ -339,5 +332,4 @@ docValues.put(fieldInfo.name, docValuesConsumer); return docValuesConsumer; } - } Index: lucene/src/java/org/apache/lucene/index/IndexReader.java =================================================================== --- lucene/src/java/org/apache/lucene/index/IndexReader.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/IndexReader.java (working copy) @@ -17,29 +17,28 @@ * limitations under the License. */ +import java.io.Closeable; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + import org.apache.lucene.document.Document; -import org.apache.lucene.document.FieldSelector; -import org.apache.lucene.search.FieldCache; // javadocs -import org.apache.lucene.search.Similarity; import org.apache.lucene.index.codecs.Codec; import org.apache.lucene.index.codecs.CodecProvider; import org.apache.lucene.index.codecs.PerDocValues; import org.apache.lucene.index.values.IndexDocValues; +import org.apache.lucene.search.FieldCache; // javadocs +import org.apache.lucene.search.Similarity; import org.apache.lucene.store.*; import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.ReaderUtil; // for javadocs -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.Closeable; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; - /** IndexReader is an abstract class, providing an interface for accessing an index. Search of an index is done entirely through this abstract interface, so that any subclass which implements it is searchable. @@ -859,7 +858,6 @@ * @return array of term frequency vectors. May be null if no term vectors have been * stored for the specified document. * @throws IOException if index cannot be accessed - * @see org.apache.lucene.document.Field.TermVector */ abstract public TermFreqVector[] getTermFreqVectors(int docNumber) throws IOException; @@ -877,7 +875,6 @@ * @return term frequency vector May be null if field does not exist in the specified * document or term vector was not stored. * @throws IOException if index cannot be accessed - * @see org.apache.lucene.document.Field.TermVector */ abstract public TermFreqVector getTermFreqVector(int docNumber, String field) throws IOException; @@ -946,57 +943,42 @@ return maxDoc() - numDocs(); } + /** Expert: visits the fields of a stored document, for + * custom processing/loading of each field. If you + * simply want to load all fields, use {@link + * #document(int)}. If you want to load a subset, use + * {@link DocumentStoredFieldVisitor}. */ + public abstract void document(int docID, StoredFieldVisitor visitor) throws CorruptIndexException, IOException; + /** * Returns the stored fields of the nth - * Document in this index. + * Document in this index. This is just + * sugar for using {@link DocumentStoredFieldVisitor}. *

      * NOTE: for performance reasons, this method does not check if the * requested document is deleted, and therefore asking for a deleted document * may yield unspecified results. Usually this is not required, however you * can test if the doc is deleted by checking the {@link * Bits} returned from {@link MultiFields#getLiveDocs}. + * + * NOTE: only the content of a field is returned, + * if that field was stored during indexing. Metadata + * like boost, omitNorm, IndexOptions, tokenized, etc., + * are not preserved. * * @throws CorruptIndexException if the index is corrupt * @throws IOException if there is a low-level IO error */ - public Document document(int n) throws CorruptIndexException, IOException { + // TODO: we need a separate StoredField, so that the + // Document returned here contains that class not + // IndexableField + public Document document(int docID) throws CorruptIndexException, IOException { ensureOpen(); - return document(n, null); + final DocumentStoredFieldVisitor visitor = new DocumentStoredFieldVisitor(); + document(docID, visitor); + return visitor.getDocument(); } - /** - * Get the {@link org.apache.lucene.document.Document} at the n - * th position. The {@link FieldSelector} may be used to determine - * what {@link org.apache.lucene.document.Field}s to load and how they should - * be loaded. NOTE: If this Reader (more specifically, the underlying - * FieldsReader) is closed before the lazy - * {@link org.apache.lucene.document.Field} is loaded an exception may be - * thrown. If you want the value of a lazy - * {@link org.apache.lucene.document.Field} to be available after closing you - * must explicitly load it or fetch the Document again with a new loader. - *

      - * NOTE: for performance reasons, this method does not check if the - * requested document is deleted, and therefore asking for a deleted document - * may yield unspecified results. Usually this is not required, however you - * can test if the doc is deleted by checking the {@link - * Bits} returned from {@link MultiFields#getLiveDocs}. - * - * @param n Get the document at the nth position - * @param fieldSelector The {@link FieldSelector} to use to determine what - * Fields should be loaded on the Document. May be null, in which case - * all Fields will be loaded. - * @return The stored fields of the - * {@link org.apache.lucene.document.Document} at the nth position - * @throws CorruptIndexException if the index is corrupt - * @throws IOException if there is a low-level IO error - * @see org.apache.lucene.document.Fieldable - * @see org.apache.lucene.document.FieldSelector - * @see org.apache.lucene.document.SetBasedFieldSelector - * @see org.apache.lucene.document.LoadFirstFieldSelector - */ - // TODO (1.5): When we convert to JDK 1.5 make this Set - public abstract Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException; - /** Returns true if any documents have been deleted */ public abstract boolean hasDeletions(); @@ -1017,8 +999,8 @@ public abstract byte[] norms(String field) throws IOException; /** Expert: Resets the normalization factor for the named field of the named - * document. By default, The norm represents the product of the field's {@link - * org.apache.lucene.document.Fieldable#setBoost(float) boost} and its + * document. By default, the norm represents the product of the field's {@link + * org.apache.lucene.document.Field#setBoost(float) boost} and its * length normalization}. Thus, to preserve the length normalization * values when resetting this, one should base the new value upon the old. * Index: lucene/src/java/org/apache/lucene/index/DocumentStoredFieldVisitor.java =================================================================== --- lucene/src/java/org/apache/lucene/index/DocumentStoredFieldVisitor.java (revision 0) +++ lucene/src/java/org/apache/lucene/index/DocumentStoredFieldVisitor.java (revision 1160484) @@ -0,0 +1,142 @@ +package org.apache.lucene.index; + +/** + * 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. + */ + +import java.io.IOException; +import java.util.Set; +import java.util.HashSet; + +import org.apache.lucene.document.BinaryField; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.NumericField; +import org.apache.lucene.document.TextField; +import org.apache.lucene.store.IndexInput; + +/** A {@link StoredFieldVisitor} that creates a {@link + * Document} containing all stored fields, or only specific + * requested fields provided to {@link #DocumentStoredFieldVisitor(Set)} + * This is used by {@link IndexReader#document(int)} to load a + * document. + * + * @lucene.experimental */ + +public class DocumentStoredFieldVisitor extends StoredFieldVisitor { + private final Document doc = new Document(); + private final Set fieldsToAdd; + + /** Load only fields named in the provided Set<String>. */ + public DocumentStoredFieldVisitor(Set fieldsToAdd) { + this.fieldsToAdd = fieldsToAdd; + } + + /** Load only fields named in the provided Set<String>. */ + public DocumentStoredFieldVisitor(String... fields) { + fieldsToAdd = new HashSet(fields.length); + for(String field : fields) { + fieldsToAdd.add(field); + } + } + + /** Load all stored fields. */ + public DocumentStoredFieldVisitor() { + this.fieldsToAdd = null; + } + + @Override + public boolean binaryField(FieldInfo fieldInfo, IndexInput in, int numBytes) throws IOException { + if (accept(fieldInfo)) { + final byte[] b = new byte[numBytes]; + in.readBytes(b, 0, b.length); + doc.add(new BinaryField(fieldInfo.name, b)); + } else { + in.seek(in.getFilePointer() + numBytes); + } + return false; + } + + @Override + public boolean stringField(FieldInfo fieldInfo, IndexInput in, int numUTF8Bytes) throws IOException { + if (accept(fieldInfo)) { + final byte[] b = new byte[numUTF8Bytes]; + in.readBytes(b, 0, b.length); + FieldType ft = new FieldType(TextField.TYPE_STORED); + ft.setStoreTermVectors(fieldInfo.storeTermVector); + ft.setStoreTermVectorPositions(fieldInfo.storePositionWithTermVector); + ft.setStoreTermVectorOffsets(fieldInfo.storeOffsetWithTermVector); + ft.setStoreTermVectors(fieldInfo.storeTermVector); + ft.setOmitNorms(fieldInfo.omitNorms); + ft.setIndexOptions(fieldInfo.indexOptions); + doc.add(new Field(fieldInfo.name, + ft, + new String(b, "UTF-8"))); + } else { + in.seek(in.getFilePointer() + numUTF8Bytes); + } + return false; + } + + @Override + public boolean intField(FieldInfo fieldInfo, int value) { + if (accept(fieldInfo)) { + FieldType ft = new FieldType(NumericField.TYPE_STORED); + ft.setIndexed(fieldInfo.isIndexed); + doc.add(new NumericField(fieldInfo.name, ft).setIntValue(value)); + } + return false; + } + + @Override + public boolean longField(FieldInfo fieldInfo, long value) { + if (accept(fieldInfo)) { + FieldType ft = new FieldType(NumericField.TYPE_STORED); + ft.setIndexed(fieldInfo.isIndexed); + doc.add(new NumericField(fieldInfo.name, ft).setLongValue(value)); + } + return false; + } + + @Override + public boolean floatField(FieldInfo fieldInfo, float value) { + if (accept(fieldInfo)) { + FieldType ft = new FieldType(NumericField.TYPE_STORED); + ft.setIndexed(fieldInfo.isIndexed); + doc.add(new NumericField(fieldInfo.name, ft).setFloatValue(value)); + } + return false; + } + + @Override + public boolean doubleField(FieldInfo fieldInfo, double value) { + if (accept(fieldInfo)) { + FieldType ft = new FieldType(NumericField.TYPE_STORED); + ft.setIndexed(fieldInfo.isIndexed); + doc.add(new NumericField(fieldInfo.name, ft).setDoubleValue(value)); + } + return false; + } + + private boolean accept(FieldInfo fieldInfo) { + return fieldsToAdd == null || fieldsToAdd.contains(fieldInfo.name); + } + + public Document getDocument() { + return doc; + } +} Property changes on: lucene/src/java/org/apache/lucene/index/DocumentStoredFieldVisitor.java ___________________________________________________________________ Added: svn:eol-style + native Index: lucene/src/java/org/apache/lucene/index/StoredFieldVisitor.java =================================================================== --- lucene/src/java/org/apache/lucene/index/StoredFieldVisitor.java (revision 0) +++ lucene/src/java/org/apache/lucene/index/StoredFieldVisitor.java (revision 1159961) @@ -0,0 +1,87 @@ +package org.apache.lucene.index; + +/** + * 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. + */ + +import java.io.IOException; + +import org.apache.lucene.document.Document; +import org.apache.lucene.store.IndexInput; + +/** + * Expert: provides a low-level means of accessing the stored field + * values in an index. See {@link IndexReader#document(int, + * StoredFieldVisitor)}. + * + * See {@link DocumentStoredFieldVisitor}, which is a + * StoredFieldVisitor that builds the + * {@link Document} containing all stored fields. This is + * used by {@link IndexReader#document(int)}. + * + * @lucene.experimental */ + +public class StoredFieldVisitor { + /** Process a binary field. Note that if you want to + * skip the field you must seek the IndexInput + * (e.g., call in.seek(numUTF8Bytes + in.getFilePointer()) + * + *

      Return true to stop loading fields. */ + public boolean binaryField(FieldInfo fieldInfo, IndexInput in, int numBytes) throws IOException { + in.seek(in.getFilePointer() + numBytes); + return false; + } + + /** Process a string field by reading numUTF8Bytes. + * Note that if you want to skip the field you must + * seek the IndexInput as if you had read numBytes by + * (e.g., call in.seek(numUTF8Bytes + in.getFilePointer()) + * + *

      Return true to stop loading fields. */ + public boolean stringField(FieldInfo fieldInfo, IndexInput in, int numUTF8Bytes) throws IOException { + in.seek(in.getFilePointer() + numUTF8Bytes); + return false; + } + + /** Process a int numeric field. + * + *

      Return true to stop loading fields. */ + public boolean intField(FieldInfo fieldInfo, int value) throws IOException { + return false; + } + + /** Process a long numeric field. + * + *

      Return true to stop loading fields. */ + public boolean longField(FieldInfo fieldInfo, long value) throws IOException { + return false; + } + + /** Process a float numeric field. + * + *

      Return true to stop loading fields. */ + public boolean floatField(FieldInfo fieldInfo, float value) throws IOException { + return false; + } + + /** Process a double numeric field. + * + *

      Return true to stop loading fields. */ + public boolean doubleField(FieldInfo fieldInfo, double value) throws IOException { + return false; + } +} + Property changes on: lucene/src/java/org/apache/lucene/index/StoredFieldVisitor.java ___________________________________________________________________ Added: svn:eol-style + native Index: lucene/src/java/org/apache/lucene/index/FieldInfos.java =================================================================== --- lucene/src/java/org/apache/lucene/index/FieldInfos.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/FieldInfos.java (working copy) @@ -39,8 +39,8 @@ import org.apache.lucene.store.IndexOutput; import org.apache.lucene.util.CodecUtil; -/** Access to the Fieldable Info file that describes document fields and whether or - * not they are indexed. Each segment has a separate Fieldable Info file. Objects +/** Access to the Field Info file that describes document fields and whether or + * not they are indexed. Each segment has a separate Field Info file. Objects * of this class are thread-safe for multiple readers, but only one thread can * be adding documents at a time, with no other reader or writer threads * accessing this object. @@ -381,7 +381,7 @@ /** * Calls 5 parameter add with false for all TermVector parameters. * - * @param name The name of the Fieldable + * @param name The name of the IndexableField * @param isIndexed true if the field is indexed * @see #addOrUpdate(String, boolean, boolean, boolean, boolean) */ Index: lucene/src/java/org/apache/lucene/index/DocumentsWriterPerThread.java =================================================================== --- lucene/src/java/org/apache/lucene/index/DocumentsWriterPerThread.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/DocumentsWriterPerThread.java (working copy) @@ -26,7 +26,6 @@ import java.util.concurrent.atomic.AtomicLong; import org.apache.lucene.analysis.Analyzer; -import org.apache.lucene.document.Document; import org.apache.lucene.index.DocumentsWriterDeleteQueue.DeleteSlice; import org.apache.lucene.search.SimilarityProvider; import org.apache.lucene.store.Directory; @@ -90,7 +89,7 @@ PrintStream infoStream; SimilarityProvider similarityProvider; int docID; - Document doc; + Iterable doc; String maxTermPrefix; DocState(DocumentsWriterPerThread docWriter) { @@ -213,7 +212,7 @@ return retval; } - public void updateDocument(Document doc, Analyzer analyzer, Term delTerm) throws IOException { + public void updateDocument(Iterable doc, Analyzer analyzer, Term delTerm) throws IOException { assert writer.testPoint("DocumentsWriterPerThread addDocument start"); assert deleteQueue != null; docState.doc = doc; @@ -263,7 +262,7 @@ finishDocument(delTerm); } - public int updateDocuments(Iterable docs, Analyzer analyzer, Term delTerm) throws IOException { + public int updateDocuments(Iterable> docs, Analyzer analyzer, Term delTerm) throws IOException { assert writer.testPoint("DocumentsWriterPerThread addDocuments start"); assert deleteQueue != null; docState.analyzer = analyzer; @@ -280,7 +279,7 @@ } int docCount = 0; try { - for(Document doc : docs) { + for(Iterable doc : docs) { docState.doc = doc; docState.docID = numDocsInRAM; docCount++; Index: lucene/src/java/org/apache/lucene/index/ParallelReader.java =================================================================== --- lucene/src/java/org/apache/lucene/index/ParallelReader.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/ParallelReader.java (working copy) @@ -18,9 +18,6 @@ */ import org.apache.lucene.document.Document; -import org.apache.lucene.document.FieldSelector; -import org.apache.lucene.document.FieldSelectorResult; -import org.apache.lucene.document.Fieldable; import org.apache.lucene.index.codecs.PerDocValues; import org.apache.lucene.index.values.IndexDocValues; import org.apache.lucene.util.Bits; @@ -351,30 +348,12 @@ hasDeletions = false; } - // append fields from storedFieldReaders @Override - public Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException { + public void document(int docID, StoredFieldVisitor visitor) throws CorruptIndexException, IOException { ensureOpen(); - Document result = new Document(); for (final IndexReader reader: storedFieldReaders) { - - boolean include = (fieldSelector==null); - if (!include) { - Collection fields = readerToFields.get(reader); - for (final String field : fields) - if (fieldSelector.accept(field) != FieldSelectorResult.NO_LOAD) { - include = true; - break; - } - } - if (include) { - List fields = reader.document(n, fieldSelector).getFields(); - for (Fieldable field : fields) { - result.add(field); - } - } + reader.document(docID, visitor); } - return result; } // get all vectors Index: lucene/src/java/org/apache/lucene/index/SegmentReader.java =================================================================== --- lucene/src/java/org/apache/lucene/index/SegmentReader.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/SegmentReader.java (working copy) @@ -28,7 +28,9 @@ import java.util.concurrent.atomic.AtomicInteger; import org.apache.lucene.document.Document; -import org.apache.lucene.document.FieldSelector; +import org.apache.lucene.store.BufferedIndexInput; +import org.apache.lucene.store.Directory; +import org.apache.lucene.store.IndexInput; import org.apache.lucene.index.FieldInfo.IndexOptions; import org.apache.lucene.index.codecs.PerDocValues; import org.apache.lucene.store.Directory; @@ -455,10 +457,9 @@ return core.fieldInfos; } - @Override - public Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException { + public void document(int docID, StoredFieldVisitor visitor) throws CorruptIndexException, IOException { ensureOpen(); - return getFieldsReader().doc(n, fieldSelector); + getFieldsReader().visitDocument(docID, visitor); } @Override Index: lucene/src/java/org/apache/lucene/index/InvertedDocConsumerPerField.java =================================================================== --- lucene/src/java/org/apache/lucene/index/InvertedDocConsumerPerField.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/InvertedDocConsumerPerField.java (working copy) @@ -19,24 +19,22 @@ import java.io.IOException; -import org.apache.lucene.document.Fieldable; - abstract class InvertedDocConsumerPerField { - // Called once per field, and is given all Fieldable + // Called once per field, and is given all IndexableField // occurrences for this field in the document. Return // true if you wish to see inverted tokens for these // fields: - abstract boolean start(Fieldable[] fields, int count) throws IOException; + abstract boolean start(IndexableField[] fields, int count) throws IOException; // Called before a field instance is being processed - abstract void start(Fieldable field); + abstract void start(IndexableField field); // Called once per inverted token abstract void add() throws IOException; - // Called once per field per document, after all Fieldable - // occurrences are inverted + // Called once per field per document, after all IndexableFields + // are inverted abstract void finish() throws IOException; // Called on hitting an aborting exception Index: lucene/src/java/org/apache/lucene/index/DocFieldConsumerPerField.java =================================================================== --- lucene/src/java/org/apache/lucene/index/DocFieldConsumerPerField.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/DocFieldConsumerPerField.java (working copy) @@ -18,11 +18,10 @@ */ import java.io.IOException; -import org.apache.lucene.document.Fieldable; abstract class DocFieldConsumerPerField { /** Processes all occurrences of a single field */ - abstract void processFields(Fieldable[] fields, int count) throws IOException; + abstract void processFields(IndexableField[] fields, int count) throws IOException; abstract void abort(); abstract FieldInfo getFieldInfo(); } Index: lucene/src/java/org/apache/lucene/index/DocFieldConsumersPerField.java =================================================================== --- lucene/src/java/org/apache/lucene/index/DocFieldConsumersPerField.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/DocFieldConsumersPerField.java (working copy) @@ -18,7 +18,6 @@ */ import java.io.IOException; -import org.apache.lucene.document.Fieldable; final class DocFieldConsumersPerField extends DocFieldConsumerPerField { @@ -35,7 +34,7 @@ } @Override - public void processFields(Fieldable[] fields, int count) throws IOException { + public void processFields(IndexableField[] fields, int count) throws IOException { one.processFields(fields, count); two.processFields(fields, count); } Index: lucene/src/java/org/apache/lucene/index/StoredFieldsWriter.java =================================================================== --- lucene/src/java/org/apache/lucene/index/StoredFieldsWriter.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/StoredFieldsWriter.java (working copy) @@ -19,7 +19,6 @@ import java.io.IOException; -import org.apache.lucene.document.Fieldable; import org.apache.lucene.store.IOContext; import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.RamUsageEstimator; @@ -41,12 +40,12 @@ } private int numStoredFields; - private Fieldable[] storedFields; + private IndexableField[] storedFields; private int[] fieldNumbers; public void reset() { numStoredFields = 0; - storedFields = new Fieldable[1]; + storedFields = new IndexableField[1]; fieldNumbers = new int[1]; } @@ -123,10 +122,10 @@ assert docWriter.writer.testPoint("StoredFieldsWriter.finishDocument end"); } - public void addField(Fieldable field, FieldInfo fieldInfo) throws IOException { + public void addField(IndexableField field, FieldInfo fieldInfo) throws IOException { if (numStoredFields == storedFields.length) { int newSize = ArrayUtil.oversize(numStoredFields + 1, RamUsageEstimator.NUM_BYTES_OBJECT_REF); - Fieldable[] newArray = new Fieldable[newSize]; + IndexableField[] newArray = new IndexableField[newSize]; System.arraycopy(storedFields, 0, newArray, 0, numStoredFields); storedFields = newArray; } Index: lucene/src/java/org/apache/lucene/index/TermsHashConsumerPerField.java =================================================================== --- lucene/src/java/org/apache/lucene/index/TermsHashConsumerPerField.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/TermsHashConsumerPerField.java (working copy) @@ -24,13 +24,11 @@ import java.io.IOException; -import org.apache.lucene.document.Fieldable; - abstract class TermsHashConsumerPerField { - abstract boolean start(Fieldable[] fields, int count) throws IOException; + abstract boolean start(IndexableField[] fields, int count) throws IOException; abstract void finish() throws IOException; abstract void skippingLongTerm() throws IOException; - abstract void start(Fieldable field); + abstract void start(IndexableField field); abstract void newTerm(int termID) throws IOException; abstract void addTerm(int termID) throws IOException; abstract int getStreamCount(); Index: lucene/src/java/org/apache/lucene/index/CheckIndex.java =================================================================== --- lucene/src/java/org/apache/lucene/index/CheckIndex.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/CheckIndex.java (working copy) @@ -17,6 +17,7 @@ * limitations under the License. */ +import org.apache.lucene.document.FieldType; // for javadocs import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.TermQuery; @@ -24,6 +25,9 @@ import org.apache.lucene.store.Directory; import org.apache.lucene.store.IOContext; import org.apache.lucene.store.IndexInput; +import org.apache.lucene.document.Document; +import org.apache.lucene.index.codecs.CodecProvider; +import org.apache.lucene.index.codecs.DefaultSegmentInfosWriter; import java.io.File; import java.io.IOException; import java.io.PrintStream; @@ -34,7 +38,6 @@ import java.util.List; import java.util.Map; -import org.apache.lucene.document.AbstractField; // for javadocs import org.apache.lucene.document.Document; import org.apache.lucene.index.codecs.CodecProvider; import org.apache.lucene.index.codecs.DefaultSegmentInfosWriter; @@ -187,7 +190,7 @@ /** True if at least one of the fields in this segment * has position data - * @see AbstractField#setIndexOptions(org.apache.lucene.index.FieldInfo.IndexOptions) */ + * @see FieldType#setIndexOptions(org.apache.lucene.index.FieldInfo.IndexOptions) */ public boolean hasProx; /** Map that includes certain Index: lucene/src/java/org/apache/lucene/index/MultiReader.java =================================================================== --- lucene/src/java/org/apache/lucene/index/MultiReader.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/MultiReader.java (working copy) @@ -23,7 +23,6 @@ import java.util.concurrent.ConcurrentHashMap; import org.apache.lucene.document.Document; -import org.apache.lucene.document.FieldSelector; import org.apache.lucene.index.codecs.PerDocValues; import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; @@ -258,12 +257,11 @@ return maxDoc; } - // inherit javadoc @Override - public Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException { + public void document(int docID, StoredFieldVisitor visitor) throws CorruptIndexException, IOException { ensureOpen(); - int i = readerIndex(n); // find segment num - return subReaders[i].document(n - starts[i], fieldSelector); // dispatch to segment reader + int i = readerIndex(docID); // find segment num + subReaders[i].document(docID - starts[i], visitor); // dispatch to segment reader } @Override Index: lucene/src/java/org/apache/lucene/index/DirectoryReader.java =================================================================== --- lucene/src/java/org/apache/lucene/index/DirectoryReader.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/DirectoryReader.java (working copy) @@ -29,8 +29,6 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import org.apache.lucene.document.Document; -import org.apache.lucene.document.FieldSelector; import org.apache.lucene.store.Directory; import org.apache.lucene.store.IOContext; import org.apache.lucene.store.Lock; @@ -559,12 +557,11 @@ return maxDoc; } - // inherit javadoc @Override - public Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException { + public void document(int docID, StoredFieldVisitor visitor) throws CorruptIndexException, IOException { ensureOpen(); - int i = readerIndex(n); // find segment num - return subReaders[i].document(n - starts[i], fieldSelector); // dispatch to segment reader + int i = readerIndex(docID); // find segment num + subReaders[i].document(docID - starts[i], visitor); // dispatch to segment reader } @Override Index: lucene/src/java/org/apache/lucene/index/FilterIndexReader.java =================================================================== --- lucene/src/java/org/apache/lucene/index/FilterIndexReader.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/FilterIndexReader.java (working copy) @@ -18,8 +18,8 @@ */ import org.apache.lucene.document.Document; -import org.apache.lucene.document.FieldSelector; import org.apache.lucene.index.codecs.PerDocValues; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.store.Directory; import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; @@ -351,9 +351,9 @@ } @Override - public Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException { + public void document(int docID, StoredFieldVisitor visitor) throws CorruptIndexException, IOException { ensureOpen(); - return in.document(n, fieldSelector); + in.document(docID, visitor); } @Override Index: lucene/src/java/org/apache/lucene/index/SegmentMerger.java =================================================================== --- lucene/src/java/org/apache/lucene/index/SegmentMerger.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/SegmentMerger.java (working copy) @@ -335,6 +335,10 @@ // skip deleted docs continue; } + // TODO: this could be more efficient using + // FieldVisitor instead of loading/writing entire + // doc; ie we just have to renumber the field number + // on the fly? // NOTE: it's very important to first assign to doc then pass it to // termVectorsWriter.addAllDocVectors; see LUCENE-1282 Document doc = reader.reader.document(j); Index: lucene/src/java/org/apache/lucene/index/TermsHashPerField.java =================================================================== --- lucene/src/java/org/apache/lucene/index/TermsHashPerField.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/TermsHashPerField.java (working copy) @@ -22,7 +22,6 @@ import java.util.concurrent.atomic.AtomicLong; import org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute; -import org.apache.lucene.document.Fieldable; import org.apache.lucene.util.ByteBlockPool; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRefHash; @@ -116,7 +115,7 @@ private boolean doNextCall; @Override - void start(Fieldable f) { + void start(IndexableField f) { termAtt = fieldState.attributeSource.getAttribute(TermToBytesRefAttribute.class); termBytesRef = termAtt.getBytesRef(); consumer.start(f); @@ -126,11 +125,12 @@ } @Override - boolean start(Fieldable[] fields, int count) throws IOException { + boolean start(IndexableField[] fields, int count) throws IOException { doCall = consumer.start(fields, count); bytesHash.reinit(); - if (nextPerField != null) + if (nextPerField != null) { doNextCall = nextPerField.start(fields, count); + } return doCall || doNextCall; } Index: lucene/src/java/org/apache/lucene/index/DocFieldProcessorPerField.java =================================================================== --- lucene/src/java/org/apache/lucene/index/DocFieldProcessorPerField.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/DocFieldProcessorPerField.java (working copy) @@ -17,7 +17,6 @@ * limitations under the License. */ -import org.apache.lucene.document.Fieldable; import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.RamUsageEstimator; @@ -34,17 +33,17 @@ int lastGen = -1; int fieldCount; - Fieldable[] fields = new Fieldable[1]; + IndexableField[] fields = new IndexableField[1]; public DocFieldProcessorPerField(final DocFieldProcessor docFieldProcessor, final FieldInfo fieldInfo) { this.consumer = docFieldProcessor.consumer.addField(fieldInfo); this.fieldInfo = fieldInfo; } - public void addField(Fieldable field) { + public void addField(IndexableField field) { if (fieldCount == fields.length) { int newSize = ArrayUtil.oversize(fieldCount + 1, RamUsageEstimator.NUM_BYTES_OBJECT_REF); - Fieldable[] newArray = new Fieldable[newSize]; + IndexableField[] newArray = new IndexableField[newSize]; System.arraycopy(fields, 0, newArray, 0, fieldCount); fields = newArray; } Index: lucene/src/java/org/apache/lucene/index/FreqProxTermsWriterPerField.java =================================================================== --- lucene/src/java/org/apache/lucene/index/FreqProxTermsWriterPerField.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/FreqProxTermsWriterPerField.java (working copy) @@ -22,7 +22,6 @@ import java.util.Map; import org.apache.lucene.analysis.tokenattributes.PayloadAttribute; -import org.apache.lucene.document.Fieldable; import org.apache.lucene.index.FieldInfo.IndexOptions; import org.apache.lucene.index.codecs.FieldsConsumer; import org.apache.lucene.index.codecs.PostingsConsumer; @@ -82,15 +81,17 @@ } @Override - boolean start(Fieldable[] fields, int count) { - for(int i=0;i docs, final Analyzer analyzer, + boolean updateDocuments(final Iterable> docs, final Analyzer analyzer, final Term delTerm) throws CorruptIndexException, IOException { boolean maybeMerge = preUpdate(); @@ -351,7 +350,7 @@ return postUpdate(flushingDWPT, maybeMerge); } - boolean updateDocument(final Document doc, final Analyzer analyzer, + boolean updateDocument(final Iterable doc, final Analyzer analyzer, final Term delTerm) throws CorruptIndexException, IOException { boolean maybeMerge = preUpdate(); Index: lucene/src/java/org/apache/lucene/index/TermVectorsTermsWriterPerField.java =================================================================== --- lucene/src/java/org/apache/lucene/index/TermVectorsTermsWriterPerField.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/TermVectorsTermsWriterPerField.java (working copy) @@ -20,7 +20,6 @@ import java.io.IOException; import org.apache.lucene.analysis.tokenattributes.OffsetAttribute; -import org.apache.lucene.document.Fieldable; import org.apache.lucene.store.IndexOutput; import org.apache.lucene.util.ByteBlockPool; import org.apache.lucene.util.BytesRef; @@ -55,17 +54,17 @@ } @Override - boolean start(Fieldable[] fields, int count) { + boolean start(IndexableField[] fields, int count) { doVectors = false; doVectorPositions = false; doVectorOffsets = false; for(int i=0;i -

      In either case, documents are added with {@link #addDocument(Document) +

      In either case, documents are added with {@link #addDocument(Iterable) addDocument} and removed with {@link #deleteDocuments(Term)} or {@link #deleteDocuments(Query)}. A document can be updated with {@link - #updateDocument(Term, Document) updateDocument} (which just deletes + #updateDocument(Term, Iterable) updateDocument} (which just deletes and then adds the entire document). When finished adding, deleting and updating documents, {@link #close() close} should be called.

      @@ -1283,7 +1282,7 @@ * @throws CorruptIndexException if the index is corrupt * @throws IOException if there is a low-level IO error */ - public void addDocument(Document doc) throws CorruptIndexException, IOException { + public void addDocument(Iterable doc) throws CorruptIndexException, IOException { addDocument(doc, analyzer); } @@ -1291,7 +1290,7 @@ * Adds a document to this index, using the provided analyzer instead of the * value of {@link #getAnalyzer()}. * - *

      See {@link #addDocument(Document)} for details on + *

      See {@link #addDocument(Iterable)} for details on * index and IndexWriter state after an Exception, and * flushing/merging temporary free space requirements.

      * @@ -1302,7 +1301,7 @@ * @throws CorruptIndexException if the index is corrupt * @throws IOException if there is a low-level IO error */ - public void addDocument(Document doc, Analyzer analyzer) throws CorruptIndexException, IOException { + public void addDocument(Iterable doc, Analyzer analyzer) throws CorruptIndexException, IOException { updateDocument(null, doc, analyzer); } @@ -1320,7 +1319,7 @@ * compression), in which case you may need to fully * re-index your documents at that time. * - *

      See {@link #addDocument(Document)} for details on + *

      See {@link #addDocument(Iterable)} for details on * index and IndexWriter state after an Exception, and * flushing/merging temporary free space requirements.

      * @@ -1340,7 +1339,7 @@ * * @lucene.experimental */ - public void addDocuments(Iterable docs) throws CorruptIndexException, IOException { + public void addDocuments(Iterable> docs) throws CorruptIndexException, IOException { addDocuments(docs, analyzer); } @@ -1355,7 +1354,7 @@ * * @lucene.experimental */ - public void addDocuments(Iterable docs, Analyzer analyzer) throws CorruptIndexException, IOException { + public void addDocuments(Iterable> docs, Analyzer analyzer) throws CorruptIndexException, IOException { updateDocuments(null, docs, analyzer); } @@ -1372,7 +1371,7 @@ * * @lucene.experimental */ - public void updateDocuments(Term delTerm, Iterable docs) throws CorruptIndexException, IOException { + public void updateDocuments(Term delTerm, Iterable> docs) throws CorruptIndexException, IOException { updateDocuments(delTerm, docs, analyzer); } @@ -1390,7 +1389,7 @@ * * @lucene.experimental */ - public void updateDocuments(Term delTerm, Iterable docs, Analyzer analyzer) throws CorruptIndexException, IOException { + public void updateDocuments(Term delTerm, Iterable> docs, Analyzer analyzer) throws CorruptIndexException, IOException { ensureOpen(); try { boolean success = false; @@ -1513,7 +1512,7 @@ * @throws CorruptIndexException if the index is corrupt * @throws IOException if there is a low-level IO error */ - public void updateDocument(Term term, Document doc) throws CorruptIndexException, IOException { + public void updateDocument(Term term, Iterable doc) throws CorruptIndexException, IOException { ensureOpen(); updateDocument(term, doc, getAnalyzer()); } @@ -1536,7 +1535,7 @@ * @throws CorruptIndexException if the index is corrupt * @throws IOException if there is a low-level IO error */ - public void updateDocument(Term term, Document doc, Analyzer analyzer) + public void updateDocument(Term term, Iterable doc, Analyzer analyzer) throws CorruptIndexException, IOException { ensureOpen(); try { @@ -3036,7 +3035,7 @@ DocumentsWriter getDocsWriter() { boolean test = false; assert test = true; - return test?docWriter: null; + return test ? docWriter : null; } /** Expert: Return the number of documents currently Index: lucene/src/java/org/apache/lucene/index/TermFreqVector.java =================================================================== --- lucene/src/java/org/apache/lucene/index/TermFreqVector.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/index/TermFreqVector.java (working copy) @@ -26,7 +26,7 @@ */ public interface TermFreqVector { /** - * The {@link org.apache.lucene.document.Fieldable} name. + * The {@link org.apache.lucene.index.IndexableField} name. * @return The name of the field this vector is associated with. * */ Index: lucene/src/java/org/apache/lucene/document/IndexDocValuesField.java =================================================================== --- lucene/src/java/org/apache/lucene/document/IndexDocValuesField.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/document/IndexDocValuesField.java (working copy) @@ -20,16 +20,13 @@ import java.util.Comparator; import org.apache.lucene.analysis.TokenStream; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; -import org.apache.lucene.document.Field.TermVector; import org.apache.lucene.index.values.PerDocFieldValues; import org.apache.lucene.index.values.ValueType; import org.apache.lucene.util.BytesRef; /** *

      - * This class provides a {@link AbstractField} that enables storing of typed + * This class provides a {@link Field} that enables storing of typed * per-document values for scoring, sorting or value retrieval. Here's an * example usage, adding an int value: * @@ -54,9 +51,9 @@ *

    * *

    - * If doc values are stored in addition to an indexed ({@link Index}) or stored - * ({@link Store}) value it's recommended to use the {@link IndexDocValuesField}'s - * {@link #set(AbstractField)} API: + * If doc values are stored in addition to an indexed ({@link FieldType#setIndexed(boolean)}) or stored + * ({@link FieldType#setStored(boolean)}) value it's recommended to use the {@link IndexDocValuesField}'s + * {@link #set(Field)} API: * *

      *  IndexDocValuesField field = new IndexDocValuesField(name);
    @@ -73,7 +70,8 @@
      * 
    * * */ -public class IndexDocValuesField extends AbstractField implements PerDocFieldValues { +// TODO: maybe rename to DocValuesField? +public class IndexDocValuesField extends Field implements PerDocFieldValues { protected BytesRef bytes; protected double doubleValue; @@ -85,21 +83,27 @@ * Creates a new {@link IndexDocValuesField} with the given name. */ public IndexDocValuesField(String name) { - super(name, Store.NO, Index.NO, TermVector.NO); - setDocValues(this); + this(name, new FieldType()); } - /** - * Creates a {@link IndexDocValuesField} prototype - */ - IndexDocValuesField() { - this(""); + public IndexDocValuesField(String name, FieldType type) { + this(name, type, null); } + public IndexDocValuesField(String name, FieldType type, String value) { + super(name, type); + fieldsData = value; + } + + @Override + public PerDocFieldValues docValues() { + return this; + } + /** * Sets the given long value and sets the field's {@link ValueType} to * {@link ValueType#VAR_INTS} unless already set. If you want to change the - * default type use {@link #setType(ValueType)}. + * default type use {@link #setDocValuesType(ValueType)}. */ public void setInt(long value) { setInt(value, false); @@ -124,7 +128,7 @@ /** * Sets the given int value and sets the field's {@link ValueType} to * {@link ValueType#VAR_INTS} unless already set. If you want to change the - * default type use {@link #setType(ValueType)}. + * default type use {@link #setDocValuesType(ValueType)}. */ public void setInt(int value) { setInt(value, false); @@ -149,7 +153,7 @@ /** * Sets the given short value and sets the field's {@link ValueType} to * {@link ValueType#VAR_INTS} unless already set. If you want to change the - * default type use {@link #setType(ValueType)}. + * default type use {@link #setDocValuesType(ValueType)}. */ public void setInt(short value) { setInt(value, false); @@ -174,11 +178,12 @@ /** * Sets the given byte value and sets the field's {@link ValueType} to * {@link ValueType#VAR_INTS} unless already set. If you want to change the - * default type use {@link #setType(ValueType)}. + * default type use {@link #setDocValuesType(ValueType)}. */ public void setInt(byte value) { setInt(value, false); } + /** * Sets the given byte value as a 8 bit signed integer. * @@ -198,7 +203,7 @@ /** * Sets the given float value and sets the field's {@link ValueType} * to {@link ValueType#FLOAT_32} unless already set. If you want to - * change the type use {@link #setType(ValueType)}. + * change the type use {@link #setDocValuesType(ValueType)}. */ public void setFloat(float value) { if (type == null) { @@ -210,7 +215,7 @@ /** * Sets the given double value and sets the field's {@link ValueType} * to {@link ValueType#FLOAT_64} unless already set. If you want to - * change the default type use {@link #setType(ValueType)}. + * change the default type use {@link #setDocValuesType(ValueType)}. */ public void setFloat(double value) { if (type == null) { @@ -241,7 +246,7 @@ if (value == null) { throw new IllegalArgumentException("value must not be null"); } - setType(type); + setDocValuesType(type); if (bytes == null) { bytes = new BytesRef(value); } else { @@ -289,7 +294,7 @@ /** * Sets the {@link ValueType} for this field. */ - public void setType(ValueType type) { + public void setDocValuesType(ValueType type) { if (type == null) { throw new IllegalArgumentException("Type must not be null"); } @@ -297,13 +302,6 @@ } /** - * Returns the field's {@link ValueType} - */ - public ValueType type() { - return type; - } - - /** * Returns always null */ public Reader readerValue() { @@ -313,36 +311,54 @@ /** * Returns always null */ - public String stringValue() { + public TokenStream tokenStreamValue() { return null; } - /** - * Returns always null - */ - public TokenStream tokenStreamValue() { - return null; + @Override + public ValueType docValuesType() { + return type; } - /** - * Sets this {@link IndexDocValuesField} to the given {@link AbstractField} and - * returns the given field. Any modifications to this instance will be visible - * to the given field. - */ - public T set(T field) { - field.setDocValues(this); - return field; + @Override + public String toString() { + final String value; + switch (type) { + case BYTES_FIXED_DEREF: + case BYTES_FIXED_SORTED: + case BYTES_FIXED_STRAIGHT: + case BYTES_VAR_DEREF: + case BYTES_VAR_SORTED: + case BYTES_VAR_STRAIGHT: + value = "bytes:bytes.utf8ToString();"; + break; + case VAR_INTS: + value = "int:" + longValue; + break; + case FLOAT_32: + value = "float32:" + doubleValue; + break; + case FLOAT_64: + value = "float64:" + doubleValue; + break; + default: + throw new IllegalArgumentException("unknown type: " + type); + } + return "<" + name() + ": IndexDocValuesField " + value + ">"; } /** - * Sets a new {@link PerDocFieldValues} instance on the given field with the - * given type and returns it. - * + * Returns an IndexDocValuesField holding the value from + * the provided string field, as the specified type. The + * incoming field must have a string value. The name, {@link + * FieldType} and string value are carried over from the + * incoming Field. */ - public static T set(T field, ValueType type) { - if (field instanceof IndexDocValuesField) - return field; - final IndexDocValuesField valField = new IndexDocValuesField(); + public static IndexDocValuesField build(Field field, ValueType type) { + if (field instanceof IndexDocValuesField) { + return (IndexDocValuesField) field; + } + final IndexDocValuesField valField = new IndexDocValuesField(field.name(), field.getFieldType(), field.stringValue()); switch (type) { case BYTES_FIXED_DEREF: case BYTES_FIXED_SORTED: @@ -350,9 +366,7 @@ case BYTES_VAR_DEREF: case BYTES_VAR_SORTED: case BYTES_VAR_STRAIGHT: - BytesRef ref = field.isBinary() ? new BytesRef(field.getBinaryValue(), - field.getBinaryOffset(), field.getBinaryLength()) : new BytesRef( - field.stringValue()); + BytesRef ref = field.isBinary() ? field.binaryValue() : new BytesRef(field.stringValue()); valField.setBytes(ref, type); break; case VAR_INTS: @@ -367,7 +381,6 @@ default: throw new IllegalArgumentException("unknown type: " + type); } - return valField.set(field); + return valField; } - } Index: lucene/src/java/org/apache/lucene/document/CompressionTools.java =================================================================== --- lucene/src/java/org/apache/lucene/document/CompressionTools.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/document/CompressionTools.java (working copy) @@ -92,16 +92,24 @@ return compress(result.bytes, 0, result.length, compressionLevel); } + public static byte[] decompress(BytesRef bytes) throws DataFormatException { + return decompress(bytes.bytes, bytes.offset, bytes.length); + } + + public static byte[] decompress(byte[] value) throws DataFormatException { + return decompress(value, 0, value.length); + } + /** Decompress the byte array previously returned by * compress */ - public static byte[] decompress(byte[] value) throws DataFormatException { + public static byte[] decompress(byte[] value, int offset, int length) throws DataFormatException { // Create an expandable byte array to hold the decompressed data - ByteArrayOutputStream bos = new ByteArrayOutputStream(value.length); + ByteArrayOutputStream bos = new ByteArrayOutputStream(length); Inflater decompressor = new Inflater(); try { - decompressor.setInput(value); + decompressor.setInput(value, offset, length); // Decompress the data final byte[] buf = new byte[1024]; @@ -119,9 +127,17 @@ /** Decompress the byte array previously returned by * compressString back into a String */ public static String decompressString(byte[] value) throws DataFormatException { - final byte[] bytes = decompress(value); + return decompressString(value, 0, value.length); + } + + public static String decompressString(byte[] value, int offset, int length) throws DataFormatException { + final byte[] bytes = decompress(value, offset, length); CharsRef result = new CharsRef(bytes.length); UnicodeUtil.UTF8toUTF16(bytes, 0, bytes.length, result); return new String(result.chars, 0, result.length); } + + public static String decompressString(BytesRef bytes) throws DataFormatException { + return decompressString(bytes.bytes, bytes.offset, bytes.length); + } } Index: lucene/src/java/org/apache/lucene/document/Field.java =================================================================== --- lucene/src/java/org/apache/lucene/document/Field.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/document/Field.java (working copy) @@ -21,514 +21,325 @@ import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.index.FieldInfo.IndexOptions; -import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexableField; +import org.apache.lucene.index.values.PerDocFieldValues; +import org.apache.lucene.index.values.ValueType; +import org.apache.lucene.util.BytesRef; /** - A field is a section of a Document. Each field has two parts, a name and a - value. Values may be free text, provided as a String or as a Reader, or they - may be atomic keywords, which are not further processed. Such keywords may - be used to represent dates, urls, etc. Fields are optionally stored in the - index, so that they may be returned with hits on the document. - */ + * A field is a section of a Document. Each field has two parts, a name and a + * value. Values may be free text, provided as a String or as a Reader, or they + * may be atomic keywords, which are not further processed. Such keywords may be + * used to represent dates, urls, etc. Fields are optionally stored in the + * index, so that they may be returned with hits on the document. + */ -public final class Field extends AbstractField implements Fieldable { +public class Field implements IndexableField { - /** Specifies whether and how a field should be stored. */ - public static enum Store { + protected FieldType type; + protected String name = "body"; + // the data object for all different kind of field values + protected Object fieldsData; + // pre-analyzed tokenStream for indexed fields + protected TokenStream tokenStream; + // length/offset for all primitive types + protected PerDocFieldValues docValues; + + protected float boost = 1.0f; - /** Store the original field value in the index. This is useful for short texts - * like a document's title which should be displayed with the results. The - * value is stored in its original form, i.e. no analyzer is used before it is - * stored. - */ - YES { - @Override - public boolean isStored() { return true; } - }, - - /** Do not store the field value in the index. */ - NO { - @Override - public boolean isStored() { return false; } - }; - - public abstract boolean isStored(); + public Field(String name, FieldType type) { + this.name = name; + this.type = type; } - - /** Specifies whether and how a field should be indexed. */ - public static enum Index { - - /** Do not index the field value. This field can thus not be searched, - * but one can still access its contents provided it is - * {@link Field.Store stored}. */ - NO { - @Override - public boolean isIndexed() { return false; } - @Override - public boolean isAnalyzed() { return false; } - @Override - public boolean omitNorms() { return true; } - }, - - /** Index the tokens produced by running the field's - * value through an Analyzer. This is useful for - * common text. */ - ANALYZED { - @Override - public boolean isIndexed() { return true; } - @Override - public boolean isAnalyzed() { return true; } - @Override - public boolean omitNorms() { return false; } - }, - - /** Index the field's value without using an Analyzer, so it can be searched. - * As no analyzer is used the value will be stored as a single term. This is - * useful for unique Ids like product numbers. - */ - NOT_ANALYZED { - @Override - public boolean isIndexed() { return true; } - @Override - public boolean isAnalyzed() { return false; } - @Override - public boolean omitNorms() { return false; } - }, - - /** Expert: Index the field's value without an Analyzer, - * and also disable the indexing of norms. Note that you - * can also separately enable/disable norms by calling - * {@link Field#setOmitNorms}. No norms means that - * index-time field and document boosting and field - * length normalization are disabled. The benefit is - * less memory usage as norms take up one byte of RAM - * per indexed field for every document in the index, - * during searching. Note that once you index a given - * field with norms disabled, enabling norms will - * have no effect. In other words, for this to have the - * above described effect on a field, one instance of - * that field must be indexed with NOT_ANALYZED_NO_NORMS - * at some point. */ - NOT_ANALYZED_NO_NORMS { - @Override - public boolean isIndexed() { return true; } - @Override - public boolean isAnalyzed() { return false; } - @Override - public boolean omitNorms() { return true; } - }, - - /** Expert: Index the tokens produced by running the - * field's value through an Analyzer, and also - * separately disable the storing of norms. See - * {@link #NOT_ANALYZED_NO_NORMS} for what norms are - * and why you may want to disable them. */ - ANALYZED_NO_NORMS { - @Override - public boolean isIndexed() { return true; } - @Override - public boolean isAnalyzed() { return true; } - @Override - public boolean omitNorms() { return true; } - }; - - /** Get the best representation of the index given the flags. */ - public static Index toIndex(boolean indexed, boolean analyzed) { - return toIndex(indexed, analyzed, false); + + public Field(String name, FieldType type, Reader reader) { + if (name == null) { + throw new NullPointerException("name cannot be null"); } - - /** Expert: Get the best representation of the index given the flags. */ - public static Index toIndex(boolean indexed, boolean analyzed, boolean omitNorms) { - - // If it is not indexed nothing else matters - if (!indexed) { - return Index.NO; - } - - // typical, non-expert - if (!omitNorms) { - if (analyzed) { - return Index.ANALYZED; - } - return Index.NOT_ANALYZED; - } - - // Expert: Norms omitted - if (analyzed) { - return Index.ANALYZED_NO_NORMS; - } - return Index.NOT_ANALYZED_NO_NORMS; + if (reader == null) { + throw new NullPointerException("reader cannot be null"); } - - public abstract boolean isIndexed(); - public abstract boolean isAnalyzed(); - public abstract boolean omitNorms(); + + this.name = name; + this.fieldsData = reader; + this.type = type; } - - /** Specifies whether and how a field should have term vectors. */ - public static enum TermVector { + + public Field(String name, FieldType type, TokenStream tokenStream) { + if (name == null) { + throw new NullPointerException("name cannot be null"); + } + if (tokenStream == null) { + throw new NullPointerException("tokenStream cannot be null"); + } - /** Do not store term vectors. - */ - NO { - @Override - public boolean isStored() { return false; } - @Override - public boolean withPositions() { return false; } - @Override - public boolean withOffsets() { return false; } - }, - - /** Store the term vectors of each document. A term vector is a list - * of the document's terms and their number of occurrences in that document. */ - YES { - @Override - public boolean isStored() { return true; } - @Override - public boolean withPositions() { return false; } - @Override - public boolean withOffsets() { return false; } - }, - - /** - * Store the term vector + token position information - * - * @see #YES - */ - WITH_POSITIONS { - @Override - public boolean isStored() { return true; } - @Override - public boolean withPositions() { return true; } - @Override - public boolean withOffsets() { return false; } - }, - - /** - * Store the term vector + Token offset information - * - * @see #YES - */ - WITH_OFFSETS { - @Override - public boolean isStored() { return true; } - @Override - public boolean withPositions() { return false; } - @Override - public boolean withOffsets() { return true; } - }, - - /** - * Store the term vector + Token position and offset information - * - * @see #YES - * @see #WITH_POSITIONS - * @see #WITH_OFFSETS - */ - WITH_POSITIONS_OFFSETS { - @Override - public boolean isStored() { return true; } - @Override - public boolean withPositions() { return true; } - @Override - public boolean withOffsets() { return true; } - }; + this.name = name; + this.fieldsData = null; + this.tokenStream = tokenStream; + this.type = type; + } + + public Field(String name, FieldType type, byte[] value) { + this(name, type, value, 0, value.length); + } - /** Get the best representation of a TermVector given the flags. */ - public static TermVector toTermVector(boolean stored, boolean withOffsets, boolean withPositions) { + public Field(String name, FieldType type, byte[] value, int offset, int length) { + this.fieldsData = new BytesRef(value, offset, length); + this.type = type; + this.name = name; + } - // If it is not stored, nothing else matters. - if (!stored) { - return TermVector.NO; - } - - if (withOffsets) { - if (withPositions) { - return Field.TermVector.WITH_POSITIONS_OFFSETS; - } - return Field.TermVector.WITH_OFFSETS; - } - - if (withPositions) { - return Field.TermVector.WITH_POSITIONS; - } - return Field.TermVector.YES; + public Field(String name, FieldType type, BytesRef bytes) { + this.fieldsData = bytes; + this.type = type; + this.name = name; + } + + public Field(String name, FieldType type, String value) { + if (name == null) { + throw new IllegalArgumentException("name cannot be null"); } + if (value == null) { + throw new IllegalArgumentException("value cannot be null"); + } + if (!type.stored() && !type.indexed()) { + throw new IllegalArgumentException("it doesn't make sense to have a field that " + + "is neither indexed nor stored"); + } + if (!type.indexed() && !type.tokenized() && (type.storeTermVectors())) { + throw new IllegalArgumentException("cannot store term vector information " + + "for a field that is not indexed"); + } + + this.type = type; + this.name = name; + this.fieldsData = value; + } - public abstract boolean isStored(); - public abstract boolean withPositions(); - public abstract boolean withOffsets(); + /** + * The value of the field as a String, or null. If null, the Reader value or + * binary value is used. Exactly one of stringValue(), readerValue(), and + * getBinaryValue() must be set. + */ + public String stringValue() { + return fieldsData instanceof String ? (String) fieldsData : null; } + /** + * The value of the field as a Reader, or null. If null, the String value or + * binary value is used. Exactly one of stringValue(), readerValue(), and + * getBinaryValue() must be set. + */ + public Reader readerValue() { + return fieldsData instanceof Reader ? (Reader) fieldsData : null; + } - /** The value of the field as a String, or null. If null, the Reader value or - * binary value is used. Exactly one of stringValue(), - * readerValue(), and getBinaryValue() must be set. */ - public String stringValue() { return fieldsData instanceof String ? (String)fieldsData : null; } + /** + * The TokesStream for this field to be used when indexing, or null. If null, + * the Reader value or String value is analyzed to produce the indexed tokens. + */ + public TokenStream tokenStreamValue() { + return tokenStream; + } - /** The value of the field as a Reader, or null. If null, the String value or - * binary value is used. Exactly one of stringValue(), - * readerValue(), and getBinaryValue() must be set. */ - public Reader readerValue() { return fieldsData instanceof Reader ? (Reader)fieldsData : null; } - - /** The TokesStream for this field to be used when indexing, or null. If null, the Reader value - * or String value is analyzed to produce the indexed tokens. */ - public TokenStream tokenStreamValue() { return tokenStream; } - - - /**

    Expert: change the value of this field. This can - * be used during indexing to re-use a single Field - * instance to improve indexing speed by avoiding GC cost - * of new'ing and reclaiming Field instances. Typically - * a single {@link Document} instance is re-used as - * well. This helps most on small documents.

    + /** + *

    + * Expert: change the value of this field. This can be used during indexing to + * re-use a single Field instance to improve indexing speed by avoiding GC + * cost of new'ing and reclaiming Field instances. Typically a single + * {@link Document} instance is re-used as well. This helps most on small + * documents. + *

    * - *

    Each Field instance should only be used once - * within a single {@link Document} instance. See ImproveIndexingSpeed - * for details.

    */ + *

    + * Each Field instance should only be used once within a single + * {@link Document} instance. See ImproveIndexingSpeed for details. + *

    + */ public void setValue(String value) { - if (isBinary) { - throw new IllegalArgumentException("cannot set a String value on a binary field"); + if (isBinary()) { + throw new IllegalArgumentException( + "cannot set a String value on a binary field"); } fieldsData = value; } - - /** Expert: change the value of this field. See setValue(String). */ + + /** + * Expert: change the value of this field. See setValue(String). + */ public void setValue(Reader value) { - if (isBinary) { - throw new IllegalArgumentException("cannot set a Reader value on a binary field"); + if (isBinary()) { + throw new IllegalArgumentException( + "cannot set a Reader value on a binary field"); } - if (isStored) { - throw new IllegalArgumentException("cannot set a Reader value on a stored field"); + if (stored()) { + throw new IllegalArgumentException( + "cannot set a Reader value on a stored field"); } fieldsData = value; } - - /** Expert: change the value of this field. See setValue(String). */ + + /** + * Expert: change the value of this field. See setValue(String). + */ public void setValue(byte[] value) { - if (!isBinary) { - throw new IllegalArgumentException("cannot set a byte[] value on a non-binary field"); + if (!isBinary()) { + throw new IllegalArgumentException( + "cannot set a byte[] value on a non-binary field"); } - fieldsData = value; - binaryLength = value.length; - binaryOffset = 0; + fieldsData = new BytesRef(value); } - - /** Expert: change the value of this field. See setValue(String). */ + + /** + * Expert: change the value of this field. See setValue(String). + */ + /* public void setValue(byte[] value, int offset, int length) { if (!isBinary) { - throw new IllegalArgumentException("cannot set a byte[] value on a non-binary field"); + throw new IllegalArgumentException( + "cannot set a byte[] value on a non-binary field"); } fieldsData = value; binaryLength = length; binaryOffset = offset; } + */ - /** Expert: sets the token stream to be used for indexing and causes isIndexed() and isTokenized() to return true. - * May be combined with stored values from stringValue() or getBinaryValue() */ + /** + * Expert: sets the token stream to be used for indexing and causes + * isIndexed() and isTokenized() to return true. May be combined with stored + * values from stringValue() or getBinaryValue() + */ public void setTokenStream(TokenStream tokenStream) { - this.isIndexed = true; - this.isTokenized = true; + if (!indexed() || !tokenized()) { + throw new IllegalArgumentException( + "cannot set token stream on non indexed and tokenized field"); + } this.tokenStream = tokenStream; } + + public String name() { + return name; + } + + public float boost() { + return boost; + } - /** - * Create a field by specifying its name, value and how it will - * be saved in the index. Term vectors will not be stored in the index. - * - * @param name The name of the field - * @param value The string to process - * @param store Whether value should be stored in the index - * @param index Whether the field should be indexed, and if so, if it should - * be tokenized before indexing - * @throws NullPointerException if name or value is null - * @throws IllegalArgumentException if the field is neither stored nor indexed + /** Sets the boost factor hits on this field. This value will be + * multiplied into the score of all hits on this this field of this + * document. + * + *

    The boost is used to compute the norm factor for the field. By + * default, in the {@link org.apache.lucene.search.Similarity#computeNorm(FieldInvertState)} method, + * the boost value is multiplied by the length normalization factor and then + * rounded by {@link org.apache.lucene.search.DefaultSimilarity#encodeNormValue(float)} before it is stored in the + * index. One should attempt to ensure that this product does not overflow + * the range of that encoding. + * + * @see org.apache.lucene.search.Similarity#computeNorm(FieldInvertState) + * @see org.apache.lucene.search.DefaultSimilarity#encodeNormValue(float) */ - public Field(String name, String value, Store store, Index index) { - this(name, value, store, index, TermVector.NO); + public void setBoost(float boost) { + this.boost = boost; } - /** - * Create a field by specifying its name, value and how it will - * be saved in the index. - * - * @param name The name of the field - * @param value The string to process - * @param store Whether value should be stored in the index - * @param index Whether the field should be indexed, and if so, if it should - * be tokenized before indexing - * @param termVector Whether term vector should be stored - * @throws NullPointerException if name or value is null - * @throws IllegalArgumentException in any of the following situations: - *

      - *
    • the field is neither stored nor indexed
    • - *
    • the field is not indexed but termVector is TermVector.YES
    • - *
    - */ - public Field(String name, String value, Store store, Index index, TermVector termVector) { - if (name == null) - throw new NullPointerException("name cannot be null"); - if (value == null) - throw new NullPointerException("value cannot be null"); - if (name.length() == 0 && value.length() == 0) - throw new IllegalArgumentException("name and value cannot both be empty"); - if (index == Index.NO && store == Store.NO) - throw new IllegalArgumentException("it doesn't make sense to have a field that " - + "is neither indexed nor stored"); - if (index == Index.NO && termVector != TermVector.NO) - throw new IllegalArgumentException("cannot store term vector information " - + "for a field that is not indexed"); - - this.name = name; - - this.fieldsData = value; + public boolean numeric() { + return false; + } - this.isStored = store.isStored(); - - this.isIndexed = index.isIndexed(); - this.isTokenized = index.isAnalyzed(); - this.omitNorms = index.omitNorms(); - if (index == Index.NO) { - // note: now this reads even wierder than before - this.indexOptions = IndexOptions.DOCS_AND_FREQS_AND_POSITIONS; - } + public Number numericValue() { + return null; + } - this.isBinary = false; - - setStoreTermVector(termVector); + public NumericField.DataType numericDataType() { + return null; } - /** - * Create a tokenized and indexed field that is not stored. Term vectors will - * not be stored. The Reader is read only when the Document is added to the index, - * i.e. you may not close the Reader until {@link IndexWriter#addDocument(Document)} - * has been called. - * - * @param name The name of the field - * @param reader The reader with the content - * @throws NullPointerException if name or reader is null - */ - public Field(String name, Reader reader) { - this(name, reader, TermVector.NO); + public BytesRef binaryValue() { + if (!isBinary()) { + return null; + } else { + return (BytesRef) fieldsData; + } } - - /** - * Create a tokenized and indexed field that is not stored, optionally with - * storing term vectors. The Reader is read only when the Document is added to the index, - * i.e. you may not close the Reader until {@link IndexWriter#addDocument(Document)} - * has been called. - * - * @param name The name of the field - * @param reader The reader with the content - * @param termVector Whether term vector should be stored - * @throws NullPointerException if name or reader is null - */ - public Field(String name, Reader reader, TermVector termVector) { - if (name == null) - throw new NullPointerException("name cannot be null"); - if (reader == null) - throw new NullPointerException("reader cannot be null"); - - this.name = name; - this.fieldsData = reader; - - this.isStored = false; - - this.isIndexed = true; - this.isTokenized = true; - - this.isBinary = false; - - setStoreTermVector(termVector); + + /** methods from inner FieldType */ + + public boolean isBinary() { + return fieldsData instanceof BytesRef; } - - /** - * Create a tokenized and indexed field that is not stored. Term vectors will - * not be stored. This is useful for pre-analyzed fields. - * The TokenStream is read only when the Document is added to the index, - * i.e. you may not close the TokenStream until {@link IndexWriter#addDocument(Document)} - * has been called. - * - * @param name The name of the field - * @param tokenStream The TokenStream with the content - * @throws NullPointerException if name or tokenStream is null - */ - public Field(String name, TokenStream tokenStream) { - this(name, tokenStream, TermVector.NO); + + public boolean stored() { + return type.stored(); } - /** - * Create a tokenized and indexed field that is not stored, optionally with - * storing term vectors. This is useful for pre-analyzed fields. - * The TokenStream is read only when the Document is added to the index, - * i.e. you may not close the TokenStream until {@link IndexWriter#addDocument(Document)} - * has been called. - * - * @param name The name of the field - * @param tokenStream The TokenStream with the content - * @param termVector Whether term vector should be stored - * @throws NullPointerException if name or tokenStream is null - */ - public Field(String name, TokenStream tokenStream, TermVector termVector) { - if (name == null) - throw new NullPointerException("name cannot be null"); - if (tokenStream == null) - throw new NullPointerException("tokenStream cannot be null"); - - this.name = name; - this.fieldsData = null; - this.tokenStream = tokenStream; + public boolean indexed() { + return type.indexed(); + } + + public boolean tokenized() { + return type.tokenized(); + } + + public boolean omitNorms() { + return type.omitNorms(); + } + + public IndexOptions indexOptions() { + return type.indexOptions(); + } + + public boolean storeTermVectors() { + return type.storeTermVectors(); + } + + public boolean storeTermVectorOffsets() { + return type.storeTermVectorOffsets(); + } + + public boolean storeTermVectorPositions() { + return type.storeTermVectorPositions(); + } + + /** Prints a Field for human consumption. */ + @Override + public String toString() { + StringBuilder result = new StringBuilder(); + result.append(type.toString()); + result.append('<'); + result.append(name); + result.append(':'); - this.isStored = false; - - this.isIndexed = true; - this.isTokenized = true; - - this.isBinary = false; - - setStoreTermVector(termVector); + if (fieldsData != null && type.lazy() == false) { + result.append(fieldsData); + } + + result.append('>'); + return result.toString(); } + + public void setDocValues(PerDocFieldValues docValues) { + this.docValues = docValues; + } + @Override + public PerDocFieldValues docValues() { + return null; + } - /** - * Create a stored field with binary value. Optionally the value may be compressed. - * - * @param name The name of the field - * @param value The binary value - */ - public Field(String name, byte[] value) { - this(name, value, 0, value.length); + @Override + public ValueType docValuesType() { + return null; } - /** - * Create a stored field with binary value. Optionally the value may be compressed. - * - * @param name The name of the field - * @param value The binary value - * @param offset Starting offset in value where this Field's bytes are - * @param length Number of bytes to use for this Field, starting at offset - */ - public Field(String name, byte[] value, int offset, int length) { - - if (name == null) - throw new IllegalArgumentException("name cannot be null"); - if (value == null) - throw new IllegalArgumentException("value cannot be null"); - - this.name = name; - fieldsData = value; - - isStored = true; - isIndexed = false; - isTokenized = false; - indexOptions = IndexOptions.DOCS_AND_FREQS_AND_POSITIONS; - omitNorms = true; - - isBinary = true; - binaryLength = length; - binaryOffset = offset; - - setStoreTermVector(TermVector.NO); + /** Returns FieldType for this field. */ + public FieldType getFieldType() { + return type; } } Index: lucene/src/java/org/apache/lucene/document/NumericField.java =================================================================== --- lucene/src/java/org/apache/lucene/document/NumericField.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/document/NumericField.java (working copy) @@ -22,28 +22,30 @@ import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.NumericTokenStream; import org.apache.lucene.index.FieldInfo.IndexOptions; +import org.apache.lucene.document.NumericField.DataType; import org.apache.lucene.util.NumericUtils; import org.apache.lucene.search.NumericRangeQuery; // javadocs import org.apache.lucene.search.NumericRangeFilter; // javadocs import org.apache.lucene.search.FieldCache; // javadocs /** - *

    This class provides a {@link Field} that enables indexing - * of numeric values for efficient range filtering and - * sorting. Here's an example usage, adding an int value: + *

    + * This class provides a {@link Field} that enables indexing of numeric values + * for efficient range filtering and sorting. Here's an example usage, adding an + * int value: + * *

    - *  document.add(new NumericField(name).setIntValue(value));
    + * document.add(new NumericField(name).setIntValue(value));
      * 
    - * - * For optimal performance, re-use the - * NumericField and {@link Document} instance for more than - * one document: - * + * + * For optimal performance, re-use the NumericField and + * {@link Document} instance for more than one document: + * *
      *  NumericField field = new NumericField(name);
      *  Document document = new Document();
      *  document.add(field);
    - *
    + * 
      *  for(all documents) {
      *    ...
      *    field.setIntValue(value)
    @@ -74,7 +76,7 @@
      *
      * 

    By default, a NumericField's value is not stored but * is indexed for range filtering and sorting. You can use - * the {@link #NumericField(String,Field.Store,boolean)} + * the {@link #NumericField(String, FieldType)} * constructor if you need to change these defaults.

    * *

    You may add the same field name as a NumericField to @@ -102,7 +104,7 @@ * default value, 4, was selected for a reasonable tradeoff * of disk space consumption versus performance. You can * use the expert constructor {@link - * #NumericField(String,int,Field.Store,boolean)} if you'd + * #NumericField(String,int,FieldType)} if you'd * like to change the value. Note that you must also * specify a congruent value when creating {@link * NumericRangeQuery} or {@link NumericRangeFilter}. @@ -129,94 +131,136 @@ * * @since 2.9 */ -public final class NumericField extends AbstractField { - +public final class NumericField extends Field { + /** Data type of the value in {@link NumericField}. * @since 3.2 */ public static enum DataType { INT, LONG, FLOAT, DOUBLE } + public static final FieldType TYPE_UNSTORED = new FieldType(); + public static final FieldType TYPE_STORED = new FieldType(); + static { + TYPE_UNSTORED.setIndexed(true); + TYPE_UNSTORED.setTokenized(true); + TYPE_UNSTORED.setOmitNorms(true); + TYPE_UNSTORED.setIndexOptions(IndexOptions.DOCS_ONLY); + TYPE_UNSTORED.freeze(); + + TYPE_STORED.setIndexed(true); + TYPE_STORED.setStored(true); + TYPE_STORED.setTokenized(true); + TYPE_STORED.setOmitNorms(true); + TYPE_STORED.setIndexOptions(IndexOptions.DOCS_ONLY); + TYPE_STORED.freeze(); + } + + //public static enum DataType { INT, LONG, FLOAT, DOUBLE } + + private DataType dataType; private transient NumericTokenStream numericTS; - private DataType type; private final int precisionStep; - + /** - * Creates a field for numeric values using the default precisionStep - * {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). The instance is not yet initialized with - * a numeric value, before indexing a document containing this field, - * set a value using the various set???Value() methods. - * This constructor creates an indexed, but not stored field. - * @param name the field name + * Creates a field for numeric values using the default + * precisionStep {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). + * The instance is not yet initialized with a numeric value, before indexing a + * document containing this field, set a value using the various set + * ???Value() methods. This constructor creates an indexed, but not + * stored field. + * + * @param name + * the field name */ public NumericField(String name) { - this(name, NumericUtils.PRECISION_STEP_DEFAULT, Field.Store.NO, true); + this(name, NumericUtils.PRECISION_STEP_DEFAULT, NumericField.TYPE_UNSTORED); } /** - * Creates a field for numeric values using the default precisionStep - * {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). The instance is not yet initialized with - * a numeric value, before indexing a document containing this field, - * set a value using the various set???Value() methods. - * @param name the field name - * @param store if the field should be stored, {@link Document#getFieldable} - * then returns {@code NumericField} instances on search results. - * @param index if the field should be indexed using {@link NumericTokenStream} + * Creates a field for numeric values using the default + * precisionStep {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). + * The instance is not yet initialized with a numeric value, before indexing a + * document containing this field, set a value using the various set + * ???Value() methods. + * + * @param name + * the field name + * @param type + * if the defualt field should be altered, e.g. stored, + * {@link Document#getField} then returns {@code NumericField} + * instances on search results, or indexed using + * {@link NumericTokenStream} */ - public NumericField(String name, Field.Store store, boolean index) { - this(name, NumericUtils.PRECISION_STEP_DEFAULT, store, index); + public NumericField(String name, FieldType type) { + this(name, NumericUtils.PRECISION_STEP_DEFAULT, type); } /** * Creates a field for numeric values with the specified - * precisionStep. The instance is not yet initialized with - * a numeric value, before indexing a document containing this field, - * set a value using the various set???Value() methods. - * This constructor creates an indexed, but not stored field. - * @param name the field name - * @param precisionStep the used precision step + * precisionStep. The instance is not yet initialized with a + * numeric value, before indexing a document containing this field, set a + * value using the various set???Value() methods. This constructor + * creates an indexed, but not stored field. + * + * @param name + * the field name + * @param precisionStep + * the used precision step */ public NumericField(String name, int precisionStep) { - this(name, precisionStep, Field.Store.NO, true); + this(name, precisionStep, NumericField.TYPE_UNSTORED); } - + /** * Creates a field for numeric values with the specified - * precisionStep. The instance is not yet initialized with - * a numeric value, before indexing a document containing this field, - * set a value using the various set???Value() methods. - * @param name the field name - * @param precisionStep the used precision step - * @param store if the field should be stored, {@link Document#getFieldable} - * then returns {@code NumericField} instances on search results. - * @param index if the field should be indexed using {@link NumericTokenStream} + * precisionStep. The instance is not yet initialized with a + * numeric value, before indexing a document containing this field, set a + * value using the various set???Value() methods. + * + * @param name + * the field name + * @param precisionStep + * the used precision step + * @param type + * if the defualt field should be altered, e.g. stored, + * {@link Document#getField} then returns {@code NumericField} + * instances on search results, or indexed using + * {@link NumericTokenStream} */ - public NumericField(String name, int precisionStep, Field.Store store, boolean index) { - super(name, store, index ? Field.Index.ANALYZED_NO_NORMS : Field.Index.NO, Field.TermVector.NO); + public NumericField(String name, int precisionStep, FieldType type) { + super(name, type); this.precisionStep = precisionStep; - setIndexOptions(IndexOptions.DOCS_ONLY); } - + /** Returns a {@link NumericTokenStream} for indexing the numeric value. */ - public TokenStream tokenStreamValue() { - if (!isIndexed()) - return null; + public TokenStream tokenStreamValue() { + if (!indexed()) return null; if (numericTS == null) { - // lazy init the TokenStream as it is heavy to instantiate (attributes,...), + // lazy init the TokenStream as it is heavy to instantiate + // (attributes,...), // if not needed (stored field loading) numericTS = new NumericTokenStream(precisionStep); // initialize value in TokenStream if (fieldsData != null) { - assert type != null; + assert dataType != null; final Number val = (Number) fieldsData; - switch (type) { + switch (dataType) { case INT: - numericTS.setIntValue(val.intValue()); break; + numericTS.setIntValue(val.intValue()); + break; case LONG: - numericTS.setLongValue(val.longValue()); break; + numericTS.setLongValue(val.longValue()); + break; case FLOAT: - numericTS.setFloatValue(val.floatValue()); break; + numericTS.setFloatValue(val.floatValue()); + break; case DOUBLE: - numericTS.setDoubleValue(val.doubleValue()); break; + numericTS.setDoubleValue(val.doubleValue()); + break; default: assert false : "Should never get here"; } @@ -226,26 +270,27 @@ } /** Returns always null for numeric fields */ - @Override - public byte[] getBinaryValue(byte[] result){ - return null; - } - - /** Returns always null for numeric fields */ public Reader readerValue() { return null; } - - /** Returns the numeric value as a string. This format is also returned if you call {@link Document#get(String)} - * on search results. It is recommended to use {@link Document#getFieldable} instead - * that returns {@code NumericField} instances. You can then use {@link #getNumericValue} - * to return the stored value. */ - public String stringValue() { + + /** + * Returns the numeric value as a string. It is recommended to + * use {@link Document#getField} instead that returns {@code NumericField} + * instances. You can then use {@link #numericValue} to return the stored + * value. + */ + @Override + public String stringValue() { return (fieldsData == null) ? null : fieldsData.toString(); } - /** Returns the current numeric value as a subclass of {@link Number}, null if not yet initialized. */ - public Number getNumericValue() { + /** + * Returns the current numeric value as a subclass of {@link Number}, + * null if not yet initialized. + */ + @Override + public Number numericValue() { return (Number) fieldsData; } @@ -254,63 +299,79 @@ return precisionStep; } - /** Returns the data type of the current value, {@code null} if not yet set. + /** + * Returns the data type of the current value, {@code null} if not yet set. + * * @since 3.2 */ - public DataType getDataType() { - return type; + @Override + public DataType numericDataType() { + return dataType; } - + + @Override + public boolean numeric() { + return true; + } + /** * Initializes the field with the supplied long value. - * @param value the numeric value + * + * @param value + * the numeric value * @return this instance, because of this you can use it the following way: - * document.add(new NumericField(name, precisionStep).setLongValue(value)) + * document.add(new NumericField(name, precisionStep).setLongValue(value)) */ public NumericField setLongValue(final long value) { if (numericTS != null) numericTS.setLongValue(value); fieldsData = Long.valueOf(value); - type = DataType.LONG; + dataType = DataType.LONG; return this; } /** * Initializes the field with the supplied int value. - * @param value the numeric value + * + * @param value + * the numeric value * @return this instance, because of this you can use it the following way: - * document.add(new NumericField(name, precisionStep).setIntValue(value)) + * document.add(new NumericField(name, precisionStep).setIntValue(value)) */ public NumericField setIntValue(final int value) { if (numericTS != null) numericTS.setIntValue(value); fieldsData = Integer.valueOf(value); - type = DataType.INT; + dataType = DataType.INT; return this; } /** * Initializes the field with the supplied double value. - * @param value the numeric value + * + * @param value + * the numeric value * @return this instance, because of this you can use it the following way: - * document.add(new NumericField(name, precisionStep).setDoubleValue(value)) + * document.add(new NumericField(name, precisionStep).setDoubleValue(value)) */ public NumericField setDoubleValue(final double value) { if (numericTS != null) numericTS.setDoubleValue(value); fieldsData = Double.valueOf(value); - type = DataType.DOUBLE; + dataType = DataType.DOUBLE; return this; } /** * Initializes the field with the supplied float value. - * @param value the numeric value + * + * @param value + * the numeric value * @return this instance, because of this you can use it the following way: - * document.add(new NumericField(name, precisionStep).setFloatValue(value)) + * document.add(new NumericField(name, precisionStep).setFloatValue(value)) */ public NumericField setFloatValue(final float value) { if (numericTS != null) numericTS.setFloatValue(value); fieldsData = Float.valueOf(value); - type = DataType.FLOAT; + dataType = DataType.FLOAT; return this; } - + } Index: lucene/src/java/org/apache/lucene/document/BinaryField.java =================================================================== --- lucene/src/java/org/apache/lucene/document/BinaryField.java (revision 0) +++ lucene/src/java/org/apache/lucene/document/BinaryField.java (revision 1160484) @@ -0,0 +1,49 @@ +package org.apache.lucene.document; + +import org.apache.lucene.util.BytesRef; + +/** + * 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. + */ + +public final class BinaryField extends Field { + + public static final FieldType TYPE_STORED = new FieldType(); + static { + TYPE_STORED.setStored(true); + TYPE_STORED.freeze(); + } + + public BinaryField(String name, byte[] value) { + super(name, BinaryField.TYPE_STORED, value); + } + + public BinaryField(String name, byte[] value, int offset, int length) { + super(name, BinaryField.TYPE_STORED, value, offset, length); + } + + public BinaryField(String name, BytesRef bytes) { + super(name, BinaryField.TYPE_STORED, bytes.bytes, bytes.offset, bytes.length); + } + + public BinaryField(String name, FieldType custom, byte[] value) { + super(name, custom, value); + } + + public boolean isNumeric() { + return false; + } +} Property changes on: lucene/src/java/org/apache/lucene/document/BinaryField.java ___________________________________________________________________ Added: svn:eol-style + native Index: lucene/src/java/org/apache/lucene/document/StringField.java =================================================================== --- lucene/src/java/org/apache/lucene/document/StringField.java (revision 0) +++ lucene/src/java/org/apache/lucene/document/StringField.java (revision 1160484) @@ -0,0 +1,51 @@ +package org.apache.lucene.document; + +import org.apache.lucene.index.FieldInfo.IndexOptions; + +/** + * 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. + */ + +public final class StringField extends Field { + + public static final FieldType TYPE_UNSTORED = new FieldType(); + public static final FieldType TYPE_STORED = new FieldType(); + static { + TYPE_UNSTORED.setIndexed(true); + TYPE_UNSTORED.setOmitNorms(true); + TYPE_UNSTORED.setIndexOptions(IndexOptions.DOCS_ONLY); + TYPE_UNSTORED.freeze(); + + TYPE_STORED.setIndexed(true); + TYPE_STORED.setStored(true); + TYPE_STORED.setOmitNorms(true); + TYPE_STORED.setIndexOptions(IndexOptions.DOCS_ONLY); + TYPE_STORED.freeze(); + } + + public StringField(String name, String value) { + super(name, TYPE_UNSTORED, value); + } + + @Override + public String stringValue() { + return (fieldsData == null) ? null : fieldsData.toString(); + } + + public boolean isNumeric() { + return false; + } +} Property changes on: lucene/src/java/org/apache/lucene/document/StringField.java ___________________________________________________________________ Added: svn:eol-style + native Index: lucene/src/java/org/apache/lucene/document/Document.java =================================================================== --- lucene/src/java/org/apache/lucene/document/Document.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/document/Document.java (working copy) @@ -17,61 +17,55 @@ * limitations under the License. */ -import java.util.*; // for javadoc +import java.util.*; + +import org.apache.lucene.index.IndexReader; // for javadoc +import org.apache.lucene.index.IndexableField; import org.apache.lucene.search.IndexSearcher; // for javadoc import org.apache.lucene.search.ScoreDoc; // for javadoc -import org.apache.lucene.index.IndexReader; // for javadoc +import org.apache.lucene.util.BytesRef; /** Documents are the unit of indexing and search. * * A Document is a set of fields. Each field has a name and a textual value. - * A field may be {@link Fieldable#isStored() stored} with the document, in which + * A field may be {@link IndexableField#stored() stored} with the document, in which * case it is returned with search hits on the document. Thus each document * should typically contain one or more stored fields which uniquely identify * it. * - *

    Note that fields which are not {@link Fieldable#isStored() stored} are + *

    Note that fields which are not {@link IndexableField#stored() stored} are * not available in documents retrieved from the index, e.g. with {@link * ScoreDoc#doc} or {@link IndexReader#document(int)}. */ -public final class Document { - List fields = new ArrayList(); - private float boost = 1.0f; +public final class Document implements Iterable { + private final List fields = new ArrayList(); + /** Constructs a new document with no fields. */ public Document() {} + @Override + public Iterator iterator() { - /** Sets a boost factor for hits on any field of this document. This value - * will be multiplied into the score of all hits on this document. - * - *

    The default value is 1.0. - * - *

    Values are multiplied into the value of {@link Fieldable#getBoost()} of - * each field in this document. Thus, this method in effect sets a default - * boost for the fields of this document. - * - * @see Fieldable#setBoost(float) - */ - public void setBoost(float boost) { - this.boost = boost; - } + return new Iterator() { + private int fieldUpto = 0; + + @Override + public boolean hasNext() { + return fieldUpto < fields.size(); + } - /** Returns, at indexing time, the boost factor as set by {@link #setBoost(float)}. - * - *

    Note that once a document is indexed this value is no longer available - * from the index. At search time, for retrieved documents, this method always - * returns 1. This however does not mean that the boost value set at indexing - * time was ignored - it was just combined with other indexing time factors and - * stored elsewhere, for better indexing and search performance. (For more - * information see the "norm(t,d)" part of the scoring formula in - * {@link org.apache.lucene.search.Similarity Similarity}.) - * - * @see #setBoost(float) - */ - public float getBoost() { - return boost; + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + @Override + public IndexableField next() { + return fields.get(fieldUpto++); + } + }; } /** @@ -84,7 +78,7 @@ * a document has to be deleted from an index and a new changed version of that * document has to be added.

    */ - public final void add(Fieldable field) { + public final void add(IndexableField field) { fields.add(field); } @@ -99,9 +93,9 @@ * document has to be added.

    */ public final void removeField(String name) { - Iterator it = fields.iterator(); + Iterator it = fields.iterator(); while (it.hasNext()) { - Fieldable field = it.next(); + IndexableField field = it.next(); if (field.name().equals(name)) { it.remove(); return; @@ -119,150 +113,17 @@ * document has to be added.

    */ public final void removeFields(String name) { - Iterator it = fields.iterator(); + Iterator it = fields.iterator(); while (it.hasNext()) { - Fieldable field = it.next(); + IndexableField field = it.next(); if (field.name().equals(name)) { it.remove(); } } } - /** Returns a field with the given name if any exist in this document, or - * null. If multiple fields exists with this name, this method returns the - * first value added. - * Do not use this method with lazy loaded fields or {@link NumericField}. - * @deprecated use {@link #getFieldable} instead and cast depending on - * data type. - * @throws ClassCastException if you try to retrieve a numerical or - * lazy loaded field. - */ - @Deprecated - public final Field getField(String name) { - return (Field) getFieldable(name); - } - - /** Returns a field with the given name if any exist in this document, or - * null. If multiple fields exists with this name, this method returns the - * first value added. - */ - public Fieldable getFieldable(String name) { - for (Fieldable field : fields) { - if (field.name().equals(name)) - return field; - } - return null; - } - - /** Returns the string value of the field with the given name if any exist in - * this document, or null. If multiple fields exist with this name, this - * method returns the first value added. If only binary fields with this name - * exist, returns null. - * For {@link NumericField} it returns the string value of the number. If you want - * the actual {@code NumericField} instance back, use {@link #getFieldable}. - */ - public final String get(String name) { - for (Fieldable field : fields) { - if (field.name().equals(name) && (!field.isBinary())) - return field.stringValue(); - } - return null; - } - - /** Returns a List of all the fields in a document. - *

    Note that fields which are not {@link Fieldable#isStored() stored} are - * not available in documents retrieved from the - * index, e.g. {@link IndexSearcher#doc(int)} or {@link - * IndexReader#document(int)}. - */ - public final List getFields() { - return fields; - } - - private final static Field[] NO_FIELDS = new Field[0]; - /** - * Returns an array of {@link Field}s with the given name. - * This method returns an empty array when there are no - * matching fields. It never returns null. - * Do not use this method with lazy loaded fields or {@link NumericField}. - * - * @param name the name of the field - * @return a Field[] array - * @deprecated use {@link #getFieldable} instead and cast depending on - * data type. - * @throws ClassCastException if you try to retrieve a numerical or - * lazy loaded field. - */ - @Deprecated - public final Field[] getFields(String name) { - List result = new ArrayList(); - for (Fieldable field : fields) { - if (field.name().equals(name)) { - result.add((Field) field); - } - } - - if (result.size() == 0) - return NO_FIELDS; - - return result.toArray(new Field[result.size()]); - } - - - private final static Fieldable[] NO_FIELDABLES = new Fieldable[0]; - - /** - * Returns an array of {@link Fieldable}s with the given name. - * This method returns an empty array when there are no - * matching fields. It never returns null. - * - * @param name the name of the field - * @return a Fieldable[] array - */ - public Fieldable[] getFieldables(String name) { - List result = new ArrayList(); - for (Fieldable field : fields) { - if (field.name().equals(name)) { - result.add(field); - } - } - - if (result.size() == 0) - return NO_FIELDABLES; - - return result.toArray(new Fieldable[result.size()]); - } - - - private final static String[] NO_STRINGS = new String[0]; - - /** - * Returns an array of values of the field specified as the method parameter. - * This method returns an empty array when there are no - * matching fields. It never returns null. - * For {@link NumericField}s it returns the string value of the number. If you want - * the actual {@code NumericField} instances back, use {@link #getFieldables}. - * @param name the name of the field - * @return a String[] of field values - */ - public final String[] getValues(String name) { - List result = new ArrayList(); - for (Fieldable field : fields) { - if (field.name().equals(name) && (!field.isBinary())) - result.add(field.stringValue()); - } - - if (result.size() == 0) - return NO_STRINGS; - - return result.toArray(new String[result.size()]); - } - - private final static byte[][] NO_BYTES = new byte[0][]; - - /** * Returns an array of byte arrays for of the fields that have the name specified * as the method parameter. This method returns an empty * array when there are no matching fields. It never @@ -271,17 +132,18 @@ * @param name the name of the field * @return a byte[][] of binary field values */ - public final byte[][] getBinaryValues(String name) { - List result = new ArrayList(); - for (Fieldable field : fields) { - if (field.name().equals(name) && (field.isBinary())) - result.add(field.getBinaryValue()); + public final BytesRef[] getBinaryValues(String name) { + final List result = new ArrayList(); + for (IndexableField field : fields) { + if (field.name().equals(name)) { + final BytesRef bytes = field.binaryValue(); + if (bytes != null) { + result.add(bytes); + } + } } - if (result.size() == 0) - return NO_BYTES; - - return result.toArray(new byte[result.size()][]); + return result.toArray(new BytesRef[result.size()]); } /** @@ -293,21 +155,83 @@ * @param name the name of the field. * @return a byte[] containing the binary field value or null */ - public final byte[] getBinaryValue(String name) { - for (Fieldable field : fields) { - if (field.name().equals(name) && (field.isBinary())) - return field.getBinaryValue(); + public final BytesRef getBinaryValue(String name) { + for (IndexableField field : fields) { + if (field.name().equals(name)) { + final BytesRef bytes = field.binaryValue(); + if (bytes != null) { + return bytes; + } + } } return null; } + + /** Returns a field with the given name if any exist in this document, or + * null. If multiple fields exists with this name, this method returns the + * first value added. + */ + public final IndexableField getField(String name) { + for (IndexableField field : fields) { + if (field.name().equals(name)) { + return field; + } + } + return null; + } + + /** + * Returns an array of {@link IndexablField}s with the given name. + * This method returns an empty array when there are no + * matching fields. It never returns null. + * + * @param name the name of the field + * @return a Fieldable[] array + */ + public IndexableField[] getFields(String name) { + List result = new ArrayList(); + for (IndexableField field : fields) { + if (field.name().equals(name)) { + result.add(field); + } + } + + return result.toArray(new IndexableField[result.size()]); + } + /** Returns a List of all the fields in a document. + *

    Note that fields which are not stored are + * not available in documents retrieved from the + * index, e.g. {@link IndexSearcher#doc(int)} or {@link + * IndexReader#document(int)}. + */ + public final List getFields() { + return fields; + } + + /** Returns the string value of the field with the given name if any exist in + * this document, or null. If multiple fields exist with this name, this + * method returns the first value added. If only binary fields with this name + * exist, returns null. + * For {@link NumericField} it returns the string value of the number. If you want + * the actual {@code NumericField} instance back, use {@link #getFieldable}. + */ + public final String get(String name) { + for (IndexableField field : fields) { + if (field.name().equals(name) && field.stringValue() != null) { + return field.stringValue(); + } + } + return null; + } + /** Prints the fields of a document for human consumption. */ @Override public final String toString() { StringBuilder buffer = new StringBuilder(); buffer.append("Document<"); for (int i = 0; i < fields.size(); i++) { - Fieldable field = fields.get(i); + IndexableField field = fields.get(i); buffer.append(field.toString()); if (i != fields.size()-1) buffer.append(" "); Index: lucene/src/java/org/apache/lucene/document/FieldType.java =================================================================== --- lucene/src/java/org/apache/lucene/document/FieldType.java (revision 0) +++ lucene/src/java/org/apache/lucene/document/FieldType.java (revision 1159961) @@ -0,0 +1,186 @@ +package org.apache.lucene.document; + +/* + * 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. + */ + +import org.apache.lucene.index.FieldInfo.IndexOptions; + +public class FieldType { + + private boolean indexed; + private boolean stored; + private boolean tokenized; + private boolean storeTermVectors; + private boolean storeTermVectorOffsets; + private boolean storeTermVectorPositions; + private boolean omitNorms; + private IndexOptions indexOptions = IndexOptions.DOCS_AND_FREQS_AND_POSITIONS; + private boolean lazy; + private boolean frozen; + + public FieldType(FieldType ref) { + this.indexed = ref.indexed(); + this.stored = ref.stored(); + this.tokenized = ref.tokenized(); + this.storeTermVectors = ref.storeTermVectors(); + this.storeTermVectorOffsets = ref.storeTermVectorOffsets(); + this.storeTermVectorPositions = ref.storeTermVectorPositions(); + this.omitNorms = ref.omitNorms(); + this.indexOptions = ref.indexOptions(); + this.lazy = ref.lazy(); + } + + public FieldType() { + } + + private void checkIfFrozen() { + if (frozen) { + throw new IllegalStateException(); + } + } + + public void freeze() { + this.frozen = true; + } + + public boolean indexed() { + return this.indexed; + } + + public void setIndexed(boolean value) { + checkIfFrozen(); + this.indexed = value; + } + + public boolean stored() { + return this.stored; + } + + public void setStored(boolean value) { + checkIfFrozen(); + this.stored = value; + } + + public boolean tokenized() { + return this.tokenized; + } + + public void setTokenized(boolean value) { + checkIfFrozen(); + this.tokenized = value; + } + + public boolean storeTermVectors() { + return this.storeTermVectors; + } + + public void setStoreTermVectors(boolean value) { + checkIfFrozen(); + this.storeTermVectors = value; + } + + public boolean storeTermVectorOffsets() { + return this.storeTermVectorOffsets; + } + + public void setStoreTermVectorOffsets(boolean value) { + checkIfFrozen(); + this.storeTermVectorOffsets = value; + } + + public boolean storeTermVectorPositions() { + return this.storeTermVectorPositions; + } + + public void setStoreTermVectorPositions(boolean value) { + checkIfFrozen(); + this.storeTermVectorPositions = value; + } + + public boolean omitNorms() { + return this.omitNorms; + } + + public void setOmitNorms(boolean value) { + checkIfFrozen(); + this.omitNorms = value; + } + + public IndexOptions indexOptions() { + return this.indexOptions; + } + + public void setIndexOptions(IndexOptions value) { + checkIfFrozen(); + this.indexOptions = value; + } + + public boolean lazy() { + return this.lazy; + } + + public void setLazy(boolean value) { + checkIfFrozen(); + this.lazy = value; + } + + /** Prints a Field for human consumption. */ + @Override + public final String toString() { + StringBuilder result = new StringBuilder(); + if (stored()) { + result.append("stored"); + } + if (indexed()) { + if (result.length() > 0) + result.append(","); + result.append("indexed"); + } + if (tokenized()) { + if (result.length() > 0) + result.append(","); + result.append("tokenized"); + } + if (storeTermVectors()) { + if (result.length() > 0) + result.append(","); + result.append("termVector"); + } + if (storeTermVectorOffsets()) { + if (result.length() > 0) + result.append(","); + result.append("termVectorOffsets"); + } + if (storeTermVectorPositions()) { + if (result.length() > 0) + result.append(","); + result.append("termVectorPosition"); + } + if (omitNorms()) { + result.append(",omitNorms"); + } + if (indexOptions != IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) { + result.append(",indexOptions="); + result.append(indexOptions); + } + if (lazy()){ + result.append(",lazy"); + } + + return result.toString(); + } +} Property changes on: lucene/src/java/org/apache/lucene/document/FieldType.java ___________________________________________________________________ Added: svn:eol-style + native Index: lucene/src/java/org/apache/lucene/document/TextField.java =================================================================== --- lucene/src/java/org/apache/lucene/document/TextField.java (revision 0) +++ lucene/src/java/org/apache/lucene/document/TextField.java (revision 1159961) @@ -0,0 +1,54 @@ +package org.apache.lucene.document; + +/** + * 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. + */ + +import java.io.Reader; + +import org.apache.lucene.analysis.TokenStream; + +public final class TextField extends Field { + + public static final FieldType TYPE_UNSTORED = new FieldType(); + public static final FieldType TYPE_STORED = new FieldType(); + static { + TYPE_UNSTORED.setIndexed(true); + TYPE_UNSTORED.setTokenized(true); + TYPE_UNSTORED.freeze(); + + TYPE_STORED.setIndexed(true); + TYPE_STORED.setStored(true); + TYPE_STORED.setTokenized(true); + TYPE_STORED.freeze(); + } + + public TextField(String name, Reader reader) { + super(name, TextField.TYPE_UNSTORED, reader); + } + + public TextField(String name, String value) { + super(name, TextField.TYPE_UNSTORED, value); + } + + public TextField(String name, TokenStream stream) { + super(name, TextField.TYPE_UNSTORED, stream); + } + + public boolean isNumeric() { + return false; + } +} Property changes on: lucene/src/java/org/apache/lucene/document/TextField.java ___________________________________________________________________ Added: svn:eol-style + native Index: lucene/src/java/org/apache/lucene/document/SetBasedFieldSelector.java =================================================================== --- lucene/src/java/org/apache/lucene/document/SetBasedFieldSelector.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/document/SetBasedFieldSelector.java (working copy) @@ -1,58 +0,0 @@ -package org.apache.lucene.document; - -import java.util.Set; -/** - * Copyright 2004 The Apache Software Foundation - * - * Licensed 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. - */ - -/** - * Declare what fields to load normally and what fields to load lazily - * - **/ -public class SetBasedFieldSelector implements FieldSelector { - - private Set fieldsToLoad; - private Set lazyFieldsToLoad; - - /** - * Pass in the Set of {@link Field} names to load and the Set of {@link Field} names to load lazily. If both are null, the - * Document will not have any {@link Field} on it. - * @param fieldsToLoad A Set of {@link String} field names to load. May be empty, but not null - * @param lazyFieldsToLoad A Set of {@link String} field names to load lazily. May be empty, but not null - */ - public SetBasedFieldSelector(Set fieldsToLoad, Set lazyFieldsToLoad) { - this.fieldsToLoad = fieldsToLoad; - this.lazyFieldsToLoad = lazyFieldsToLoad; - } - - /** - * Indicate whether to load the field with the given name or not. If the {@link Field#name()} is not in either of the - * initializing Sets, then {@link org.apache.lucene.document.FieldSelectorResult#NO_LOAD} is returned. If a Field name - * is in both fieldsToLoad and lazyFieldsToLoad, lazy has precedence. - * - * @param fieldName The {@link Field} name to check - * @return The {@link FieldSelectorResult} - */ - public FieldSelectorResult accept(String fieldName) { - FieldSelectorResult result = FieldSelectorResult.NO_LOAD; - if (fieldsToLoad.contains(fieldName) == true){ - result = FieldSelectorResult.LOAD; - } - if (lazyFieldsToLoad.contains(fieldName) == true){ - result = FieldSelectorResult.LAZY_LOAD; - } - return result; - } -} \ No newline at end of file Index: lucene/src/java/org/apache/lucene/document/MapFieldSelector.java =================================================================== --- lucene/src/java/org/apache/lucene/document/MapFieldSelector.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/document/MapFieldSelector.java (working copy) @@ -1,67 +0,0 @@ -package org.apache.lucene.document; - -/** - * 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. - */ - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * A {@link FieldSelector} based on a Map of field names to {@link FieldSelectorResult}s - * - */ -public class MapFieldSelector implements FieldSelector { - - Map fieldSelections; - - /** Create a a MapFieldSelector - * @param fieldSelections maps from field names (String) to {@link FieldSelectorResult}s - */ - public MapFieldSelector(Map fieldSelections) { - this.fieldSelections = fieldSelections; - } - - /** Create a a MapFieldSelector - * @param fields fields to LOAD. List of Strings. All other fields are NO_LOAD. - */ - public MapFieldSelector(List fields) { - fieldSelections = new HashMap(fields.size()*5/3); - for (final String field : fields) - fieldSelections.put(field, FieldSelectorResult.LOAD); - } - - /** Create a a MapFieldSelector - * @param fields fields to LOAD. All other fields are NO_LOAD. - */ - public MapFieldSelector(String... fields) { - this(Arrays.asList(fields)); - } - - - - /** Load field according to its associated value in fieldSelections - * @param field a field name - * @return the fieldSelections value that field maps to or NO_LOAD if none. - */ - public FieldSelectorResult accept(String field) { - FieldSelectorResult selection = fieldSelections.get(field); - return selection!=null ? selection : FieldSelectorResult.NO_LOAD; - } - -} Index: lucene/src/java/org/apache/lucene/document/FieldSelectorResult.java =================================================================== --- lucene/src/java/org/apache/lucene/document/FieldSelectorResult.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/document/FieldSelectorResult.java (working copy) @@ -1,76 +0,0 @@ -package org.apache.lucene.document; - -/** - * Copyright 2004 The Apache Software Foundation - * - * Licensed 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. - */ - -/** - * Provides information about what should be done with this Field - * - **/ -public enum FieldSelectorResult { - - /** - * Load this {@link Field} every time the {@link Document} is loaded, reading in the data as it is encountered. - * {@link Document#getField(String)} and {@link Document#getFieldable(String)} should not return null. - *

    - * {@link Document#add(Fieldable)} should be called by the Reader. - */ - LOAD, - - /** - * Lazily load this {@link Field}. This means the {@link Field} is valid, but it may not actually contain its data until - * invoked. {@link Document#getField(String)} SHOULD NOT BE USED. {@link Document#getFieldable(String)} is safe to use and should - * return a valid instance of a {@link Fieldable}. - *

    - * {@link Document#add(Fieldable)} should be called by the Reader. - */ - LAZY_LOAD, - - /** - * Do not load the {@link Field}. {@link Document#getField(String)} and {@link Document#getFieldable(String)} should return null. - * {@link Document#add(Fieldable)} is not called. - *

    - * {@link Document#add(Fieldable)} should not be called by the Reader. - */ - NO_LOAD, - - /** - * Load this field as in the {@link #LOAD} case, but immediately return from {@link Field} loading for the {@link Document}. Thus, the - * Document may not have its complete set of Fields. {@link Document#getField(String)} and {@link Document#getFieldable(String)} should - * both be valid for this {@link Field} - *

    - * {@link Document#add(Fieldable)} should be called by the Reader. - */ - LOAD_AND_BREAK, - - /** Expert: Load the size of this {@link Field} rather than its value. - * Size is measured as number of bytes required to store the field == bytes for a binary or any compressed value, and 2*chars for a String value. - * The size is stored as a binary value, represented as an int in a byte[], with the higher order byte first in [0] - */ - SIZE, - - /** Expert: Like {@link #SIZE} but immediately break from the field loading loop, i.e., stop loading further fields, after the size is loaded */ - SIZE_AND_BREAK, - - /** - * Lazily load this {@link Field}, but do not cache the result. This means the {@link Field} is valid, but it may not actually contain its data until - * invoked. {@link Document#getField(String)} SHOULD NOT BE USED. {@link Document#getFieldable(String)} is safe to use and should - * return a valid instance of a {@link Fieldable}. - *

    - * {@link Document#add(Fieldable)} should be called by the Reader. - */ - LATENT -} Index: lucene/src/java/org/apache/lucene/document/FieldSelector.java =================================================================== --- lucene/src/java/org/apache/lucene/document/FieldSelector.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/document/FieldSelector.java (working copy) @@ -1,33 +0,0 @@ -package org.apache.lucene.document; - -/** - * Copyright 2004 The Apache Software Foundation - * - * Licensed 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. - */ - -/** - * Similar to a {@link java.io.FileFilter}, the FieldSelector allows one to make decisions about - * what Fields get loaded on a {@link Document} by {@link org.apache.lucene.index.IndexReader#document(int,org.apache.lucene.document.FieldSelector)} - * - **/ -public interface FieldSelector { - - /** - * - * @param fieldName the field to accept or reject - * @return an instance of {@link FieldSelectorResult} - * if the {@link Field} named fieldName should be loaded. - */ - FieldSelectorResult accept(String fieldName); -} Index: lucene/src/java/org/apache/lucene/document/AbstractField.java =================================================================== --- lucene/src/java/org/apache/lucene/document/AbstractField.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/document/AbstractField.java (working copy) @@ -1,312 +0,0 @@ -package org.apache.lucene.document; -/** - * Copyright 2006 The Apache Software Foundation - * - * Licensed 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. - */ - -import org.apache.lucene.search.PhraseQuery; // for javadocs -import org.apache.lucene.search.spans.SpanQuery; // for javadocs -import org.apache.lucene.analysis.TokenStream; -import org.apache.lucene.index.FieldInfo.IndexOptions; -import org.apache.lucene.index.FieldInvertState; // for javadocs -import org.apache.lucene.index.values.PerDocFieldValues; -import org.apache.lucene.index.values.ValueType; - - -/** - * - * - **/ -public abstract class AbstractField implements Fieldable { - - protected String name = "body"; - protected boolean storeTermVector = false; - protected boolean storeOffsetWithTermVector = false; - protected boolean storePositionWithTermVector = false; - protected boolean omitNorms = false; - protected boolean isStored = false; - protected boolean isIndexed = true; - protected boolean isTokenized = true; - protected boolean isBinary = false; - protected boolean lazy = false; - protected IndexOptions indexOptions = IndexOptions.DOCS_AND_FREQS_AND_POSITIONS; - protected float boost = 1.0f; - // the data object for all different kind of field values - protected Object fieldsData = null; - // pre-analyzed tokenStream for indexed fields - protected TokenStream tokenStream; - // length/offset for all primitive types - protected int binaryLength; - protected int binaryOffset; - protected PerDocFieldValues docValues; - - protected AbstractField() - { - } - - protected AbstractField(String name, Field.Store store, Field.Index index, Field.TermVector termVector) { - if (name == null) - throw new NullPointerException("name cannot be null"); - this.name = name; - - this.isStored = store.isStored(); - this.isIndexed = index.isIndexed(); - this.isTokenized = index.isAnalyzed(); - this.omitNorms = index.omitNorms(); - - this.isBinary = false; - - setStoreTermVector(termVector); - } - - /** Sets the boost factor hits on this field. This value will be - * multiplied into the score of all hits on this this field of this - * document. - * - *

    The boost is multiplied by {@link org.apache.lucene.document.Document#getBoost()} of the document - * containing this field. If a document has multiple fields with the same - * name, all such values are multiplied together. This product is then - * used to compute the norm factor for the field. By - * default, in the {@link - * org.apache.lucene.search.Similarity#computeNorm(FieldInvertState)} method, the boost value is multiplied - * by the length normalization factor and then - * rounded by {@link org.apache.lucene.search.DefaultSimilarity#encodeNormValue(float)} before it is stored in the - * index. One should attempt to ensure that this product does not overflow - * the range of that encoding. - * - * @see org.apache.lucene.document.Document#setBoost(float) - * @see org.apache.lucene.search.Similarity#computeNorm(FieldInvertState) - * @see org.apache.lucene.search.DefaultSimilarity#encodeNormValue(float) - */ - public void setBoost(float boost) { - this.boost = boost; - } - - /** Returns the boost factor for hits for this field. - * - *

    The default value is 1.0. - * - *

    Note: this value is not stored directly with the document in the index. - * Documents returned from {@link org.apache.lucene.index.IndexReader#document(int)} and - * {@link org.apache.lucene.search.IndexSearcher#doc(int)} may thus not have the same value present as when - * this field was indexed. - * - * @see #setBoost(float) - */ - public float getBoost() { - return boost; - } - - /** Returns the name of the field. - * For example "date", "title", "body", ... - */ - public String name() { return name; } - - protected void setStoreTermVector(Field.TermVector termVector) { - this.storeTermVector = termVector.isStored(); - this.storePositionWithTermVector = termVector.withPositions(); - this.storeOffsetWithTermVector = termVector.withOffsets(); - } - - /** True iff the value of the field is to be stored in the index for return - with search hits. It is an error for this to be true if a field is - Reader-valued. */ - public final boolean isStored() { return isStored; } - - /** True iff the value of the field is to be indexed, so that it may be - searched on. */ - public final boolean isIndexed() { return isIndexed; } - - /** True iff the value of the field should be tokenized as text prior to - indexing. Un-tokenized fields are indexed as a single word and may not be - Reader-valued. */ - public final boolean isTokenized() { return isTokenized; } - - /** True iff the term or terms used to index this field are stored as a term - * vector, available from {@link org.apache.lucene.index.IndexReader#getTermFreqVector(int,String)}. - * These methods do not provide access to the original content of the field, - * only to terms used to index it. If the original content must be - * preserved, use the stored attribute instead. - * - * @see org.apache.lucene.index.IndexReader#getTermFreqVector(int, String) - */ - public final boolean isTermVectorStored() { return storeTermVector; } - - /** - * True iff terms are stored as term vector together with their offsets - * (start and end position in source text). - */ - public boolean isStoreOffsetWithTermVector(){ - return storeOffsetWithTermVector; - } - - /** - * True iff terms are stored as term vector together with their token positions. - */ - public boolean isStorePositionWithTermVector(){ - return storePositionWithTermVector; - } - - /** True iff the value of the filed is stored as binary */ - public final boolean isBinary() { - return isBinary; - } - - - /** - * Return the raw byte[] for the binary field. Note that - * you must also call {@link #getBinaryLength} and {@link - * #getBinaryOffset} to know which range of bytes in this - * returned array belong to the field. - * @return reference to the Field value as byte[]. - */ - public byte[] getBinaryValue() { - return getBinaryValue(null); - } - - public byte[] getBinaryValue(byte[] result){ - if (isBinary || fieldsData instanceof byte[]) - return (byte[]) fieldsData; - else - return null; - } - - /** - * Returns length of byte[] segment that is used as value, if Field is not binary - * returned value is undefined - * @return length of byte[] segment that represents this Field value - */ - public int getBinaryLength() { - if (isBinary) { - return binaryLength; - } else if (fieldsData instanceof byte[]) - return ((byte[]) fieldsData).length; - else - return 0; - } - - /** - * Returns offset into byte[] segment that is used as value, if Field is not binary - * returned value is undefined - * @return index of the first character in byte[] segment that represents this Field value - */ - public int getBinaryOffset() { - return binaryOffset; - } - - /** True if norms are omitted for this indexed field */ - public boolean getOmitNorms() { return omitNorms; } - - /** @see #setIndexOptions */ - public IndexOptions getIndexOptions() { return indexOptions; } - - /** Expert: - * - * If set, omit normalization factors associated with this indexed field. - * This effectively disables indexing boosts and length normalization for this field. - */ - public void setOmitNorms(boolean omitNorms) { this.omitNorms=omitNorms; } - - /** Expert: - * - * If set, omit term freq, and optionally also positions and payloads from - * postings for this field. - * - *

    NOTE: While this option reduces storage space - * required in the index, it also means any query - * requiring positional information, such as {@link - * PhraseQuery} or {@link SpanQuery} subclasses will - * silently fail to find results. - */ - public void setIndexOptions(IndexOptions indexOptions) { this.indexOptions=indexOptions; } - - public boolean isLazy() { - return lazy; - } - - /** Prints a Field for human consumption. */ - @Override - public final String toString() { - StringBuilder result = new StringBuilder(); - if (isStored) { - result.append("stored"); - } - if (isIndexed) { - if (result.length() > 0) - result.append(","); - result.append("indexed"); - } - if (isTokenized) { - if (result.length() > 0) - result.append(","); - result.append("tokenized"); - } - if (storeTermVector) { - if (result.length() > 0) - result.append(","); - result.append("termVector"); - } - if (storeOffsetWithTermVector) { - if (result.length() > 0) - result.append(","); - result.append("termVectorOffsets"); - } - if (storePositionWithTermVector) { - if (result.length() > 0) - result.append(","); - result.append("termVectorPosition"); - } - if (isBinary) { - if (result.length() > 0) - result.append(","); - result.append("binary"); - } - if (omitNorms) { - result.append(",omitNorms"); - } - if (indexOptions != IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) { - result.append(",indexOptions="); - result.append(indexOptions); - } - if (lazy){ - result.append(",lazy"); - } - result.append('<'); - result.append(name); - result.append(':'); - - if (fieldsData != null && lazy == false) { - result.append(fieldsData); - } - - result.append('>'); - return result.toString(); - } - - public PerDocFieldValues getDocValues() { - return docValues; - } - - public void setDocValues(PerDocFieldValues docValues) { - this.docValues = docValues; - } - - public boolean hasDocValues() { - return docValues != null && docValues.type() != null; - } - - public ValueType docValuesType() { - return docValues == null? null : docValues.type(); - } -} Index: lucene/src/java/org/apache/lucene/document/Fieldable.java =================================================================== --- lucene/src/java/org/apache/lucene/document/Fieldable.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/document/Fieldable.java (working copy) @@ -1,238 +0,0 @@ -package org.apache.lucene.document; - -/** - * Copyright 2004 The Apache Software Foundation - * - * Licensed 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. - */ - -import org.apache.lucene.analysis.TokenStream; -import org.apache.lucene.index.FieldInfo.IndexOptions; -import org.apache.lucene.index.FieldInvertState; // for javadocs -import org.apache.lucene.index.values.IndexDocValues; -import org.apache.lucene.index.values.PerDocFieldValues; -import org.apache.lucene.index.values.ValueType; -import org.apache.lucene.search.PhraseQuery; // for javadocs -import org.apache.lucene.search.spans.SpanQuery; // for javadocs - -import java.io.Reader; - -/** - * Synonymous with {@link Field}. - * - *

    WARNING: This interface may change within minor versions, despite Lucene's backward compatibility requirements. - * This means new methods may be added from version to version. This change only affects the Fieldable API; other backwards - * compatibility promises remain intact. For example, Lucene can still - * read and write indices created within the same major version. - *

    - * - **/ -public interface Fieldable { - /** Sets the boost factor hits on this field. This value will be - * multiplied into the score of all hits on this this field of this - * document. - * - *

    The boost is multiplied by {@link org.apache.lucene.document.Document#getBoost()} of the document - * containing this field. If a document has multiple fields with the same - * name, all such values are multiplied together. This product is then - * used to compute the norm factor for the field. By - * default, in the {@link - * org.apache.lucene.search.Similarity#computeNorm(FieldInvertState)} method, the boost value is multiplied - * by the length normalization factor - * and then rounded by {@link org.apache.lucene.search.DefaultSimilarity#encodeNormValue(float)} before it is stored in the - * index. One should attempt to ensure that this product does not overflow - * the range of that encoding. - * - * @see org.apache.lucene.document.Document#setBoost(float) - * @see org.apache.lucene.search.Similarity#computeNorm(FieldInvertState) - * @see org.apache.lucene.search.DefaultSimilarity#encodeNormValue(float) - */ - void setBoost(float boost); - - /** Returns the boost factor for hits for this field. - * - *

    The default value is 1.0. - * - *

    Note: this value is not stored directly with the document in the index. - * Documents returned from {@link org.apache.lucene.index.IndexReader#document(int)} and - * {@link org.apache.lucene.search.IndexSearcher#doc(int)} may thus not have the same value present as when - * this field was indexed. - * - * @see #setBoost(float) - */ - float getBoost(); - - /** Returns the name of the field. - * For example "date", "title", "body", ... - */ - String name(); - - /** The value of the field as a String, or null. - *

    - * For indexing, if isStored()==true, the stringValue() will be used as the stored field value - * unless isBinary()==true, in which case getBinaryValue() will be used. - * - * If isIndexed()==true and isTokenized()==false, this String value will be indexed as a single token. - * If isIndexed()==true and isTokenized()==true, then tokenStreamValue() will be used to generate indexed tokens if not null, - * else readerValue() will be used to generate indexed tokens if not null, else stringValue() will be used to generate tokens. - */ - public String stringValue(); - - /** The value of the field as a Reader, which can be used at index time to generate indexed tokens. - * @see #stringValue() - */ - public Reader readerValue(); - - /** The TokenStream for this field to be used when indexing, or null. - * @see #stringValue() - */ - public TokenStream tokenStreamValue(); - - /** True if the value of the field is to be stored in the index for return - with search hits. */ - boolean isStored(); - - /** True if the value of the field is to be indexed, so that it may be - searched on. */ - boolean isIndexed(); - - /** True if the value of the field should be tokenized as text prior to - indexing. Un-tokenized fields are indexed as a single word and may not be - Reader-valued. */ - boolean isTokenized(); - - /** True if the term or terms used to index this field are stored as a term - * vector, available from {@link org.apache.lucene.index.IndexReader#getTermFreqVector(int,String)}. - * These methods do not provide access to the original content of the field, - * only to terms used to index it. If the original content must be - * preserved, use the stored attribute instead. - * - * @see org.apache.lucene.index.IndexReader#getTermFreqVector(int, String) - */ - boolean isTermVectorStored(); - - /** - * True if terms are stored as term vector together with their offsets - * (start and end positon in source text). - */ - boolean isStoreOffsetWithTermVector(); - - /** - * True if terms are stored as term vector together with their token positions. - */ - boolean isStorePositionWithTermVector(); - - /** True if the value of the field is stored as binary */ - boolean isBinary(); - - /** True if norms are omitted for this indexed field */ - boolean getOmitNorms(); - - /** Expert: - * - * If set, omit normalization factors associated with this indexed field. - * This effectively disables indexing boosts and length normalization for this field. - */ - void setOmitNorms(boolean omitNorms); - - /** - * Indicates whether a Field is Lazy or not. The semantics of Lazy loading are such that if a Field is lazily loaded, retrieving - * it's values via {@link #stringValue()} or {@link #getBinaryValue()} is only valid as long as the {@link org.apache.lucene.index.IndexReader} that - * retrieved the {@link Document} is still open. - * - * @return true if this field can be loaded lazily - */ - boolean isLazy(); - - /** - * Returns offset into byte[] segment that is used as value, if Field is not binary - * returned value is undefined - * @return index of the first character in byte[] segment that represents this Field value - */ - abstract int getBinaryOffset(); - - /** - * Returns length of byte[] segment that is used as value, if Field is not binary - * returned value is undefined - * @return length of byte[] segment that represents this Field value - */ - abstract int getBinaryLength(); - - /** - * Return the raw byte[] for the binary field. Note that - * you must also call {@link #getBinaryLength} and {@link - * #getBinaryOffset} to know which range of bytes in this - * returned array belong to the field. - * @return reference to the Field value as byte[]. - */ - abstract byte[] getBinaryValue(); - - /** - * Return the raw byte[] for the binary field. Note that - * you must also call {@link #getBinaryLength} and {@link - * #getBinaryOffset} to know which range of bytes in this - * returned array belong to the field.

    - * About reuse: if you pass in the result byte[] and it is - * used, likely the underlying implementation will hold - * onto this byte[] and return it in future calls to - * {@link #getBinaryValue()}. - * So if you subsequently re-use the same byte[] elsewhere - * it will alter this Fieldable's value. - * @param result User defined buffer that will be used if - * possible. If this is null or not large enough, a new - * buffer is allocated - * @return reference to the Field value as byte[]. - */ - abstract byte[] getBinaryValue(byte[] result); - - /** @see #setIndexOptions */ - IndexOptions getIndexOptions(); - - /** Expert: - * - * If set, omit term freq, and optionally positions and payloads from - * postings for this field. - * - *

    NOTE: While this option reduces storage space - * required in the index, it also means any query - * requiring positional information, such as {@link - * PhraseQuery} or {@link SpanQuery} subclasses will - * fail with an exception. - */ - void setIndexOptions(IndexOptions indexOptions); - - /** - * Returns the {@link PerDocFieldValues} - */ - public PerDocFieldValues getDocValues(); - - /** - * Sets the {@link PerDocFieldValues} for this field. If - * {@link PerDocFieldValues} is set this field will store per-document values - * - * @see IndexDocValues - */ - public void setDocValues(PerDocFieldValues docValues); - - /** - * Returns true iff {@link PerDocFieldValues} are set on this - * field. - */ - public boolean hasDocValues(); - - /** - * Returns the {@link ValueType} of the set {@link PerDocFieldValues} or - * null if not set. - */ - public ValueType docValuesType(); -} Index: lucene/src/java/org/apache/lucene/document/LoadFirstFieldSelector.java =================================================================== --- lucene/src/java/org/apache/lucene/document/LoadFirstFieldSelector.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/document/LoadFirstFieldSelector.java (working copy) @@ -1,29 +0,0 @@ -package org.apache.lucene.document; -/** - * Copyright 2004 The Apache Software Foundation - * - * Licensed 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. - */ - - -/** - * Load the First field and break. - *

    - * See {@link FieldSelectorResult#LOAD_AND_BREAK} - */ -public class LoadFirstFieldSelector implements FieldSelector { - - public FieldSelectorResult accept(String fieldName) { - return FieldSelectorResult.LOAD_AND_BREAK; - } -} \ No newline at end of file Index: lucene/src/java/org/apache/lucene/document/package.html =================================================================== --- lucene/src/java/org/apache/lucene/document/package.html (revision 1158028) +++ lucene/src/java/org/apache/lucene/document/package.html (working copy) @@ -22,16 +22,16 @@

    The logical representation of a {@link org.apache.lucene.document.Document} for indexing and searching.

    The document package provides the user level logical representation of content to be indexed and searched. The -package also provides utilities for working with {@link org.apache.lucene.document.Document}s and {@link org.apache.lucene.document.Fieldable}s.

    -

    Document and Fieldable

    -

    A {@link org.apache.lucene.document.Document} is a collection of {@link org.apache.lucene.document.Fieldable}s. A - {@link org.apache.lucene.document.Fieldable} is a logical representation of a user's content that needs to be indexed or stored. - {@link org.apache.lucene.document.Fieldable}s have a number of properties that tell Lucene how to treat the content (like indexed, tokenized, - stored, etc.) See the {@link org.apache.lucene.document.Field} implementation of {@link org.apache.lucene.document.Fieldable} +package also provides utilities for working with {@link org.apache.lucene.document.Document}s and {@link org.apache.lucene.index.IndexableField}s.

    +

    Document and IndexableField

    +

    A {@link org.apache.lucene.document.Document} is a collection of {@link org.apache.lucene.index.IndexableField}s. A + {@link org.apache.lucene.index.IndexableField} is a logical representation of a user's content that needs to be indexed or stored. + {@link org.apache.lucene.index.IndexableField}s have a number of properties that tell Lucene how to treat the content (like indexed, tokenized, + stored, etc.) See the {@link org.apache.lucene.document.Field} implementation of {@link org.apache.lucene.index.IndexableField} for specifics on these properties.

    Note: it is common to refer to {@link org.apache.lucene.document.Document}s having {@link org.apache.lucene.document.Field}s, even though technically they have -{@link org.apache.lucene.document.Fieldable}s.

    +{@link org.apache.lucene.index.IndexableField}s.

    Working with Documents

    First and foremost, a {@link org.apache.lucene.document.Document} is something created by the user application. It is your job to create Documents based on the content of the files you are working with in your application (Word, txt, PDF, Excel or any other format.) @@ -45,7 +45,7 @@ to simplify indexing of numeric values (and also dates) for fast range range queries with {@link org.apache.lucene.search.NumericRangeQuery} (using a special sortable string representation of numeric values).

    The {@link org.apache.lucene.document.FieldSelector} class provides a mechanism to tell Lucene how to load Documents from -storage. If no FieldSelector is used, all Fieldables on a Document will be loaded. As an example of the FieldSelector usage, consider +storage. If no FieldSelector is used, all IndexableFields on a Document will be loaded. As an example of the FieldSelector usage, consider the common use case of displaying search results on a web page and then having users click through to see the full document. In this scenario, it is often the case that there are many small fields and one or two large fields (containing the contents of the original file). Before the FieldSelector, Index: lucene/src/java/org/apache/lucene/search/FieldCache.java =================================================================== --- lucene/src/java/org/apache/lucene/search/FieldCache.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/search/FieldCache.java (working copy) @@ -24,7 +24,7 @@ import org.apache.lucene.util.NumericUtils; import org.apache.lucene.util.RamUsageEstimator; import org.apache.lucene.util.BytesRef; -import org.apache.lucene.document.NumericField; // for javadocs +import org.apache.lucene.document.NumericField; import org.apache.lucene.analysis.NumericTokenStream; // for javadocs import org.apache.lucene.util.packed.PackedInts; Index: lucene/src/java/org/apache/lucene/search/NumericRangeFilter.java =================================================================== --- lucene/src/java/org/apache/lucene/search/NumericRangeFilter.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/search/NumericRangeFilter.java (working copy) @@ -18,7 +18,7 @@ */ import org.apache.lucene.analysis.NumericTokenStream; // for javadocs -import org.apache.lucene.document.NumericField; // for javadocs +import org.apache.lucene.document.NumericField; import org.apache.lucene.util.NumericUtils; // for javadocs /** Index: lucene/src/java/org/apache/lucene/search/Similarity.java =================================================================== --- lucene/src/java/org/apache/lucene/search/Similarity.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/search/Similarity.java (working copy) @@ -221,4 +221,4 @@ */ public abstract void normalize(float queryNorm, float topLevelBoost); } -} +} \ No newline at end of file Index: lucene/src/java/org/apache/lucene/search/FieldCacheRangeFilter.java =================================================================== --- lucene/src/java/org/apache/lucene/search/FieldCacheRangeFilter.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/search/FieldCacheRangeFilter.java (working copy) @@ -23,7 +23,7 @@ import org.apache.lucene.util.NumericUtils; import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; -import org.apache.lucene.document.NumericField; // for javadocs +import org.apache.lucene.document.NumericField; /** * A range filter built on top of a cached single term field (in {@link FieldCache}). Index: lucene/src/java/org/apache/lucene/search/NumericRangeQuery.java =================================================================== --- lucene/src/java/org/apache/lucene/search/NumericRangeQuery.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/search/NumericRangeQuery.java (working copy) @@ -22,7 +22,7 @@ import java.util.Comparator; import org.apache.lucene.analysis.NumericTokenStream; // for javadocs -import org.apache.lucene.document.NumericField; // for javadocs +import org.apache.lucene.document.NumericField; import org.apache.lucene.util.NumericUtils; import org.apache.lucene.util.ToStringUtils; import org.apache.lucene.index.Terms; Index: lucene/src/java/org/apache/lucene/search/TFIDFSimilarity.java =================================================================== --- lucene/src/java/org/apache/lucene/search/TFIDFSimilarity.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/search/TFIDFSimilarity.java (working copy) @@ -454,12 +454,8 @@ * norm(t,d) encapsulates a few (indexing time) boost and length factors: * *

      - *
    • Document boost - set by calling - * {@link org.apache.lucene.document.Document#setBoost(float) doc.setBoost()} - * before adding the document to the index. - *
    • *
    • Field boost - set by calling - * {@link org.apache.lucene.document.Fieldable#setBoost(float) field.setBoost()} + * {@link org.apache.lucene.document.Field#setBoost(float) field.setBoost()} * before adding the field to a document. *
    • *
    • lengthNorm - computed @@ -480,8 +476,6 @@ * * * norm(t,d)   =   - * {@link org.apache.lucene.document.Document#getBoost() doc.getBoost()} - *  ·  * lengthNorm *  ·  * @@ -489,7 +483,7 @@ * * * - * {@link org.apache.lucene.document.Fieldable#getBoost() f.getBoost}() + * {@link org.apache.lucene.index.IndexableField#boost() f.boost}() * * * Index: lucene/src/java/org/apache/lucene/search/IndexSearcher.java =================================================================== --- lucene/src/java/org/apache/lucene/search/IndexSearcher.java (revision 1158028) +++ lucene/src/java/org/apache/lucene/search/IndexSearcher.java (working copy) @@ -31,11 +31,11 @@ import java.util.concurrent.locks.ReentrantLock; import org.apache.lucene.document.Document; -import org.apache.lucene.document.FieldSelector; import org.apache.lucene.index.CorruptIndexException; -import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.StoredFieldVisitor; import org.apache.lucene.index.Term; import org.apache.lucene.search.Weight.ScorerContext; import org.apache.lucene.store.Directory; @@ -239,16 +239,16 @@ } } - /* Sugar for .getIndexReader().document(docID) */ + /* Sugar for .getIndexReader().document(docID) */ public Document doc(int docID) throws CorruptIndexException, IOException { return reader.document(docID); } - - /* Sugar for .getIndexReader().document(docID, fieldSelector) */ - public Document doc(int docID, FieldSelector fieldSelector) throws CorruptIndexException, IOException { - return reader.document(docID, fieldSelector); + + /* Sugar for .getIndexReader().document(docID, fieldVisitor) */ + public void doc(int docID, StoredFieldVisitor fieldVisitor) throws CorruptIndexException, IOException { + reader.document(docID, fieldVisitor); } - + /** Expert: Set the SimilarityProvider implementation used by this Searcher. * */ Index: lucene/src/test-framework/org/apache/lucene/index/DocHelper.java =================================================================== --- lucene/src/test-framework/org/apache/lucene/index/DocHelper.java (revision 1158028) +++ lucene/src/test-framework/org/apache/lucene/index/DocHelper.java (working copy) @@ -26,10 +26,12 @@ import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.analysis.MockTokenizer; +import org.apache.lucene.document.BinaryField; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; -import org.apache.lucene.document.Fieldable; import org.apache.lucene.index.FieldInfo.IndexOptions; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.TextField; import org.apache.lucene.search.SimilarityProvider; import org.apache.lucene.store.Directory; import org.apache.lucene.util.LuceneTestCase; @@ -37,63 +39,107 @@ import static org.apache.lucene.util.LuceneTestCase.TEST_VERSION_CURRENT; class DocHelper { + + public static final FieldType customType; public static final String FIELD_1_TEXT = "field one text"; public static final String TEXT_FIELD_1_KEY = "textField1"; - public static Field textField1 = new Field(TEXT_FIELD_1_KEY, FIELD_1_TEXT, - Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.NO); - + public static Field textField1; + static { + customType = new FieldType(TextField.TYPE_STORED); + textField1 = new Field(TEXT_FIELD_1_KEY, customType, FIELD_1_TEXT); + } + + public static final FieldType customType2; public static final String FIELD_2_TEXT = "field field field two text"; //Fields will be lexicographically sorted. So, the order is: field, text, two public static final int [] FIELD_2_FREQS = {3, 1, 1}; public static final String TEXT_FIELD_2_KEY = "textField2"; - public static Field textField2 = new Field(TEXT_FIELD_2_KEY, FIELD_2_TEXT, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS); + public static Field textField2; + static { + customType2 = new FieldType(TextField.TYPE_STORED); + customType2.setStoreTermVectors(true); + customType2.setStoreTermVectorPositions(true); + customType2.setStoreTermVectorOffsets(true); + textField2 = new Field(TEXT_FIELD_2_KEY, customType2, FIELD_2_TEXT); + } + public static final FieldType customType3; public static final String FIELD_3_TEXT = "aaaNoNorms aaaNoNorms bbbNoNorms"; public static final String TEXT_FIELD_3_KEY = "textField3"; - public static Field textField3 = new Field(TEXT_FIELD_3_KEY, FIELD_3_TEXT, Field.Store.YES, Field.Index.ANALYZED); - static { textField3.setOmitNorms(true); } + public static Field textField3; + + static { + customType3 = new FieldType(TextField.TYPE_STORED); + customType3.setOmitNorms(true); + textField3 = new Field(TEXT_FIELD_3_KEY, customType3, FIELD_3_TEXT); + } + public static final FieldType customType4; public static final String KEYWORD_TEXT = "Keyword"; public static final String KEYWORD_FIELD_KEY = "keyField"; - public static Field keyField = new Field(KEYWORD_FIELD_KEY, KEYWORD_TEXT, - Field.Store.YES, Field.Index.NOT_ANALYZED); + public static Field keyField; + static { + customType4 = new FieldType(TextField.TYPE_UNSTORED); + customType4.setStored(true); + customType4.setTokenized(false); + keyField = new Field(KEYWORD_FIELD_KEY, customType4, KEYWORD_TEXT); + } + public static final FieldType customType5; public static final String NO_NORMS_TEXT = "omitNormsText"; public static final String NO_NORMS_KEY = "omitNorms"; - public static Field noNormsField = new Field(NO_NORMS_KEY, NO_NORMS_TEXT, - Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS); + public static Field noNormsField; + static { + customType5 = new FieldType(TextField.TYPE_UNSTORED); + customType5.setOmitNorms(true); + customType5.setStored(true); + customType5.setTokenized(false); + noNormsField = new Field(NO_NORMS_KEY, customType5, NO_NORMS_TEXT); + } + public static final FieldType customType6; public static final String NO_TF_TEXT = "analyzed with no tf and positions"; public static final String NO_TF_KEY = "omitTermFreqAndPositions"; - public static Field noTFField = new Field(NO_TF_KEY, NO_TF_TEXT, - Field.Store.YES, Field.Index.ANALYZED); + public static Field noTFField; static { - noTFField.setIndexOptions(IndexOptions.DOCS_ONLY); + customType6 = new FieldType(TextField.TYPE_UNSTORED); + customType6.setIndexOptions(IndexOptions.DOCS_ONLY); + customType6.setStored(true); + noTFField = new Field(NO_TF_KEY, customType6, NO_TF_TEXT); } + public static final FieldType customType7; public static final String UNINDEXED_FIELD_TEXT = "unindexed field text"; public static final String UNINDEXED_FIELD_KEY = "unIndField"; - public static Field unIndField = new Field(UNINDEXED_FIELD_KEY, UNINDEXED_FIELD_TEXT, - Field.Store.YES, Field.Index.NO); + public static Field unIndField; + static { + customType7 = new FieldType(); + customType7.setStored(true); + unIndField = new Field(UNINDEXED_FIELD_KEY, customType7, UNINDEXED_FIELD_TEXT); + } public static final String UNSTORED_1_FIELD_TEXT = "unstored field text"; public static final String UNSTORED_FIELD_1_KEY = "unStoredField1"; - public static Field unStoredField1 = new Field(UNSTORED_FIELD_1_KEY, UNSTORED_1_FIELD_TEXT, - Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.NO); + public static Field unStoredField1 = new Field(UNSTORED_FIELD_1_KEY, TextField.TYPE_UNSTORED, UNSTORED_1_FIELD_TEXT); + public static final FieldType customType8; public static final String UNSTORED_2_FIELD_TEXT = "unstored field text"; public static final String UNSTORED_FIELD_2_KEY = "unStoredField2"; - public static Field unStoredField2 = new Field(UNSTORED_FIELD_2_KEY, UNSTORED_2_FIELD_TEXT, - Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.YES); + public static Field unStoredField2; + static { + customType8 = new FieldType(TextField.TYPE_UNSTORED); + customType8.setStoreTermVectors(true); + unStoredField2 = new Field(UNSTORED_FIELD_2_KEY, customType8, UNSTORED_2_FIELD_TEXT); + } public static final String LAZY_FIELD_BINARY_KEY = "lazyFieldBinary"; public static byte [] LAZY_FIELD_BINARY_BYTES; public static Field lazyFieldBinary; - + public static final String LAZY_FIELD_KEY = "lazyField"; public static final String LAZY_FIELD_TEXT = "These are some field bytes"; - public static Field lazyField = new Field(LAZY_FIELD_KEY, LAZY_FIELD_TEXT, Field.Store.YES, Field.Index.ANALYZED); + public static Field lazyField = new Field(LAZY_FIELD_KEY, customType, LAZY_FIELD_TEXT); public static final String LARGE_LAZY_FIELD_KEY = "largeLazyField"; public static String LARGE_LAZY_FIELD_TEXT; @@ -102,15 +148,13 @@ //From Issue 509 public static final String FIELD_UTF1_TEXT = "field one \u4e00text"; public static final String TEXT_FIELD_UTF1_KEY = "textField1Utf8"; - public static Field textUtfField1 = new Field(TEXT_FIELD_UTF1_KEY, FIELD_UTF1_TEXT, - Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.NO); + public static Field textUtfField1 = new Field(TEXT_FIELD_UTF1_KEY, customType, FIELD_UTF1_TEXT); public static final String FIELD_UTF2_TEXT = "field field field \u4e00two text"; //Fields will be lexicographically sorted. So, the order is: field, text, two public static final int [] FIELD_UTF2_FREQS = {3, 1, 1}; public static final String TEXT_FIELD_UTF2_KEY = "textField2Utf8"; - public static Field textUtfField2 = new Field(TEXT_FIELD_UTF2_KEY, FIELD_UTF2_TEXT, Field.Store.YES, - Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS); + public static Field textUtfField2 = new Field(TEXT_FIELD_UTF2_KEY, customType2, FIELD_UTF2_TEXT); @@ -136,16 +180,16 @@ largeLazyField//placeholder for large field, since this is null. It must always be last }; - public static Map all =new HashMap(); - public static Map indexed =new HashMap(); - public static Map stored =new HashMap(); - public static Map unstored=new HashMap(); - public static Map unindexed=new HashMap(); - public static Map termvector=new HashMap(); - public static Map notermvector=new HashMap(); - public static Map lazy= new HashMap(); - public static Map noNorms=new HashMap(); - public static Map noTf=new HashMap(); + public static Map all =new HashMap(); + public static Map indexed =new HashMap(); + public static Map stored =new HashMap(); + public static Map unstored=new HashMap(); + public static Map unindexed=new HashMap(); + public static Map termvector=new HashMap(); + public static Map notermvector=new HashMap(); + public static Map lazy= new HashMap(); + public static Map noNorms=new HashMap(); + public static Map noTf=new HashMap(); static { //Initialize the large Lazy Field @@ -159,28 +203,29 @@ LAZY_FIELD_BINARY_BYTES = "These are some binary field bytes".getBytes("UTF8"); } catch (UnsupportedEncodingException e) { } - lazyFieldBinary = new Field(LAZY_FIELD_BINARY_KEY, LAZY_FIELD_BINARY_BYTES); + lazyFieldBinary = new BinaryField(LAZY_FIELD_BINARY_KEY, LAZY_FIELD_BINARY_BYTES); fields[fields.length - 2] = lazyFieldBinary; LARGE_LAZY_FIELD_TEXT = buffer.toString(); - largeLazyField = new Field(LARGE_LAZY_FIELD_KEY, LARGE_LAZY_FIELD_TEXT, Field.Store.YES, Field.Index.ANALYZED); + largeLazyField = new Field(LARGE_LAZY_FIELD_KEY, customType, LARGE_LAZY_FIELD_TEXT); fields[fields.length - 1] = largeLazyField; for (int i=0; i map, Fieldable field) { + private static void add(Map map, IndexableField field) { map.put(field.name(), field); } Index: lucene/src/test-framework/org/apache/lucene/index/RandomIndexWriter.java =================================================================== --- lucene/src/test-framework/org/apache/lucene/index/RandomIndexWriter.java (revision 1158028) +++ lucene/src/test-framework/org/apache/lucene/index/RandomIndexWriter.java (working copy) @@ -120,23 +120,22 @@ /** * Adds a Document. - * @see IndexWriter#addDocument(Document) + * @see IndexWriter#addDocument(Iterable) */ - public void addDocument(final Document doc) throws IOException { - if (doDocValues) { - randomPerDocFieldValues(r, doc); + public void addDocument(final Iterable doc) throws IOException { + if (doDocValues && doc instanceof Document) { + randomPerDocFieldValues(r, (Document) doc); } - if (r.nextInt(5) == 3) { // TODO: maybe, we should simply buffer up added docs // (but we need to clone them), and only when // getReader, commit, etc. are called, we do an // addDocuments? Would be better testing. - w.addDocuments(new Iterable() { + w.addDocuments(new Iterable>() { @Override - public Iterator iterator() { - return new Iterator() { + public Iterator> iterator() { + return new Iterator>() { boolean done; @Override @@ -150,7 +149,7 @@ } @Override - public Document next() { + public Iterable next() { if (done) { throw new IllegalStateException(); } @@ -172,7 +171,7 @@ ValueType[] values = ValueType.values(); ValueType type = values[random.nextInt(values.length)]; String name = "random_" + type.name() + "" + docValuesFieldPrefix; - if ("PreFlex".equals(codecProvider.getFieldCodec(name)) || doc.getFieldable(name) != null) + if ("PreFlex".equals(codecProvider.getFieldCodec(name)) || doc.getField(name) != null) return; IndexDocValuesField docValuesField = new IndexDocValuesField(name); switch (type) { @@ -238,31 +237,30 @@ } } - public void addDocuments(Iterable docs) throws IOException { + public void addDocuments(Iterable> docs) throws IOException { w.addDocuments(docs); maybeCommit(); } - public void updateDocuments(Term delTerm, Iterable docs) throws IOException { + public void updateDocuments(Term delTerm, Iterable> docs) throws IOException { w.updateDocuments(delTerm, docs); maybeCommit(); } /** * Updates a document. - * @see IndexWriter#updateDocument(Term, Document) + * @see IndexWriter#updateDocument(Term, Iterable) */ - public void updateDocument(final Term t, final Document doc) throws IOException { + public void updateDocument(Term t, final Iterable doc) throws IOException { if (doDocValues) { - randomPerDocFieldValues(r, doc); + randomPerDocFieldValues(r, (Document) doc); } - if (r.nextInt(5) == 3) { - w.updateDocuments(t, new Iterable() { + w.updateDocuments(t, new Iterable>() { @Override - public Iterator iterator() { - return new Iterator() { + public Iterator> iterator() { + return new Iterator>() { boolean done; @Override @@ -276,7 +274,7 @@ } @Override - public Document next() { + public Iterable next() { if (done) { throw new IllegalStateException(); } Index: lucene/src/test-framework/org/apache/lucene/util/_TestUtil.java =================================================================== --- lucene/src/test-framework/org/apache/lucene/util/_TestUtil.java (revision 1158028) +++ lucene/src/test-framework/org/apache/lucene/util/_TestUtil.java (working copy) @@ -36,11 +36,11 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; -import org.apache.lucene.document.Fieldable; import org.apache.lucene.index.CheckIndex; import org.apache.lucene.index.ConcurrentMergeScheduler; import org.apache.lucene.index.FieldInfos; import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexableField; import org.apache.lucene.index.LogMergePolicy; import org.apache.lucene.index.MergePolicy; import org.apache.lucene.index.MergeScheduler; @@ -424,10 +424,9 @@ /** Adds field info for a Document. */ public static void add(Document doc, FieldInfos fieldInfos) { - List fields = doc.getFields(); - for (Fieldable field : fields) { - fieldInfos.addOrUpdate(field.name(), field.isIndexed(), field.isTermVectorStored(), field.isStorePositionWithTermVector(), - field.isStoreOffsetWithTermVector(), field.getOmitNorms(), false, field.getIndexOptions(), field.docValuesType()); + for (IndexableField field : doc) { + fieldInfos.addOrUpdate(field.name(), field.indexed(), field.storeTermVectors(), field.storeTermVectorPositions(), + field.storeTermVectorOffsets(), field.omitNorms(), false, field.indexOptions(), field.docValuesType()); } } @@ -504,15 +503,13 @@ // TODO: is there a pre-existing way to do this!!! public static Document cloneDocument(Document doc1) { final Document doc2 = new Document(); - for(Fieldable f : doc1.getFields()) { + for(IndexableField f : doc1) { Field field1 = (Field) f; Field field2 = new Field(field1.name(), - field1.stringValue(), - field1.isStored() ? Field.Store.YES : Field.Store.NO, - field1.isIndexed() ? (field1.isTokenized() ? Field.Index.ANALYZED : Field.Index.NOT_ANALYZED) : Field.Index.NO); - field2.setOmitNorms(field1.getOmitNorms()); - field2.setIndexOptions(field1.getIndexOptions()); + field1.getFieldType(), + field1.stringValue() + ); doc2.add(field2); } Index: lucene/src/test-framework/org/apache/lucene/util/LineFileDocs.java =================================================================== --- lucene/src/test-framework/org/apache/lucene/util/LineFileDocs.java (revision 1158028) +++ lucene/src/test-framework/org/apache/lucene/util/LineFileDocs.java (working copy) @@ -30,6 +30,9 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.StringField; +import org.apache.lucene.document.TextField; /** Minimal port of contrib/benchmark's LneDocSource + * DocMaker, so tests can enum docs from a line file created @@ -117,19 +120,24 @@ public DocState() { doc = new Document(); - title = new Field("title", "", Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS); + title = new StringField("title", ""); doc.add(title); - titleTokenized = new Field("titleTokenized", "", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS); + FieldType ft = new FieldType(TextField.TYPE_STORED); + ft.setStoreTermVectors(true); + ft.setStoreTermVectorOffsets(true); + ft.setStoreTermVectorPositions(true); + + titleTokenized = new Field("titleTokenized", ft, ""); doc.add(titleTokenized); - body = new Field("body", "", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS); + body = new Field("body", ft, ""); doc.add(body); - id = new Field("docid", "", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS); + id = new Field("docid", StringField.TYPE_STORED, ""); doc.add(id); - date = new Field("date", "", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS); + date = new Field("date", StringField.TYPE_STORED, ""); doc.add(date); } } Index: lucene/src/test-framework/org/apache/lucene/util/LuceneTestCase.java =================================================================== --- lucene/src/test-framework/org/apache/lucene/util/LuceneTestCase.java (revision 1158028) +++ lucene/src/test-framework/org/apache/lucene/util/LuceneTestCase.java (working copy) @@ -37,9 +37,7 @@ import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.document.Field; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; -import org.apache.lucene.document.Field.TermVector; +import org.apache.lucene.document.FieldType; import org.apache.lucene.index.*; import org.apache.lucene.index.codecs.Codec; import org.apache.lucene.index.codecs.CodecProvider; @@ -1108,85 +1106,46 @@ return dir; } - /** Returns a new field instance. - * See {@link #newField(String, String, Field.Store, Field.Index, Field.TermVector)} for more information */ - public static Field newField(String name, String value, Index index) { - return newField(random, name, value, index); + public static Field newField(String name, String value, FieldType type) { + return newField(random, name, value, type); } - /** Returns a new field instance. - * See {@link #newField(String, String, Field.Store, Field.Index, Field.TermVector)} for more information */ - public static Field newField(String name, String value, Store store, Index index) { - return newField(random, name, value, store, index); - } - - /** - * Returns a new Field instance. Use this when the test does not - * care about some specific field settings (most tests) - *
        - *
      • If the store value is set to Store.NO, sometimes the field will be randomly stored. - *
      • More term vector data than you ask for might be indexed, for example if you choose YES - * it might index term vectors with offsets too. - *
      - */ - public static Field newField(String name, String value, Store store, Index index, TermVector tv) { - return newField(random, name, value, store, index, tv); - } - - /** Returns a new field instance, using the specified random. - * See {@link #newField(String, String, Field.Store, Field.Index, Field.TermVector)} for more information */ - public static Field newField(Random random, String name, String value, Index index) { - return newField(random, name, value, Store.NO, index); - } - - /** Returns a new field instance, using the specified random. - * See {@link #newField(String, String, Field.Store, Field.Index, Field.TermVector)} for more information */ - public static Field newField(Random random, String name, String value, Store store, Index index) { - return newField(random, name, value, store, index, TermVector.NO); - } - - /** Returns a new field instance, using the specified random. - * See {@link #newField(String, String, Field.Store, Field.Index, Field.TermVector)} for more information */ - public static Field newField(Random random, String name, String value, Store store, Index index, TermVector tv) { - + public static Field newField(Random random, String name, String value, FieldType type) { if (usually(random)) { // most of the time, don't modify the params - return new Field(name, value, store, index, tv); + return new Field(name, type, value); } - if (random.nextBoolean()) { - // tickle any code still relying on field names being interned: - name = new String(name); + FieldType newType = new FieldType(type); + if (!newType.stored() && random.nextBoolean()) { + newType.setStored(true); // randomly store it } - if (!index.isIndexed()) - return new Field(name, value, store, index, tv); + if (newType.indexed() && !newType.storeTermVectors()) { + newType.setStoreTermVectors(random.nextBoolean()); + } - if (!store.isStored() && random.nextBoolean()) - store = Store.YES; // randomly store it + if (!newType.storeTermVectors()) { + if (!newType.storeTermVectorOffsets()) { + newType.setStoreTermVectorOffsets(random.nextBoolean()); + } + if (!newType.storeTermVectorPositions()) { + newType.setStoreTermVectorPositions(random.nextBoolean()); + } + } - tv = randomTVSetting(random, tv); - - return new Field(name, value, store, index, tv); - } - - static final TermVector tvSettings[] = { - TermVector.NO, TermVector.YES, TermVector.WITH_OFFSETS, - TermVector.WITH_POSITIONS, TermVector.WITH_POSITIONS_OFFSETS - }; - - private static TermVector randomTVSetting(Random random, TermVector minimum) { - switch(minimum) { - case NO: return tvSettings[_TestUtil.nextInt(random, 0, tvSettings.length-1)]; - case YES: return tvSettings[_TestUtil.nextInt(random, 1, tvSettings.length-1)]; - case WITH_OFFSETS: return random.nextBoolean() ? TermVector.WITH_OFFSETS - : TermVector.WITH_POSITIONS_OFFSETS; - case WITH_POSITIONS: return random.nextBoolean() ? TermVector.WITH_POSITIONS - : TermVector.WITH_POSITIONS_OFFSETS; - default: return TermVector.WITH_POSITIONS_OFFSETS; + // TODO: we need to do this, but smarter, ie, most of + // the time we set the same value for a given field but + // sometimes (rarely) we change it up: + /* + if (newType.omitNorms()) { + newType.setOmitNorms(random.nextBoolean()); } + */ + + return new Field(name, newType, value); } - + /** return a random Locale from the available locales on the system */ public static Locale randomLocale(Random random) { Locale locales[] = Locale.getAvailableLocales(); Index: lucene/CHANGES.txt =================================================================== --- lucene/CHANGES.txt (revision 1158028) +++ lucene/CHANGES.txt (working copy) @@ -251,6 +251,11 @@ * LUCENE-3146: IndexReader.setNorm throws IllegalStateException if the field does not store norms. (Shai Erera, Mike McCandless) + +* LUCENE-3309: Stored fields no longer record whether they were + tokenized or not. In general you should not rely on stored fields + to record any "metadata" from indexing (tokenized, omitNorms, + IndexOptions, boost, etc.) (Mike McCandless) API Changes