FileDocCategorySizeDatePackage
FieldNormModifier.javaAPI DocApache Lucene 2.2.04838Sat Jun 16 22:21:02 BST 2007org.apache.lucene.index

FieldNormModifier

public class FieldNormModifier extends Object
Given a directory and a list of fields, updates the fieldNorms in place for every document. If Similarity class is specified, uses its lengthNorm 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.

NOTE: This will overwrite any length normalization or field/document boosts.

author
Chris Hostetter
author
Otis Gospodnetic

Fields Summary
private Directory
dir
private Similarity
sim
Constructors Summary
public FieldNormModifier(Directory d, Similarity s)
Constructor for code that wishes to use this class programatically If Similarity is null, kill the field norms.

param
d the Directory to modify
param
s the Similiary to use (can be null)

    dir = d;
    sim = s;
  
Methods Summary
public static voidmain(java.lang.String[] args)
Command Line Execution method.
Usage: FieldNormModifier /path/index  field1 field2 ...

    if (args.length < 3) {
      System.err.println("Usage: FieldNormModifier <index> <package.SimilarityClassName | -n> <field1> [field2] ...");
      System.exit(1);
    }

    Similarity s = null;
    if (!args[1].equals("-n")) {
      try {
        Class simClass = Class.forName(args[1]);
        s = (Similarity)simClass.newInstance();
      } catch (Exception e) {
        System.err.println("Couldn't instantiate similarity with empty constructor: " + args[1]);
        e.printStackTrace(System.err);
        System.exit(1);
      }
    }

    Directory d = FSDirectory.getDirectory(args[0], false);
    FieldNormModifier fnm = new FieldNormModifier(d, s);

    for (int i = 2; i < args.length; i++) {
      System.out.print("Updating field: " + args[i] + " " + (new Date()).toString() + " ... ");
      fnm.reSetNorms(args[i]);
      System.out.println(new Date().toString());
    }
    
    d.close();
  
public voidreSetNorms(java.lang.String field)
Resets the norms for the specified field.

Opens a new IndexReader on the Directory given to this instance, modifies the norms (either using the Similarity given to this instance, or by using fake norms, and closes the IndexReader.

param
field the field whose norms should be reset

    String fieldName = field.intern();
    int[] termCounts = new int[0];
    byte[] fakeNorms = new byte[0];
    
    IndexReader reader = null;
    TermEnum termEnum = null;
    TermDocs termDocs = null;
    try {
      reader = IndexReader.open(dir);
      termCounts = new int[reader.maxDoc()];
      // if we are killing norms, get fake ones
      if (sim == null)
        fakeNorms = SegmentReader.createFakeNorms(reader.maxDoc());
      try {
        termEnum = reader.terms(new Term(field,""));
        try {
          termDocs = reader.termDocs();
          do {
            Term term = termEnum.term();
            if (term != null && term.field().equals(fieldName)) {
              termDocs.seek(termEnum.term());
              while (termDocs.next()) {
                termCounts[termDocs.doc()] += termDocs.freq();
              }
            }
          } while (termEnum.next());
          
        } finally {
          if (null != termDocs) termDocs.close();
        }
      } finally {
        if (null != termEnum) termEnum.close();
      }
    } finally {
      if (null != reader) reader.close();
    }
    
    try {
      reader = IndexReader.open(dir); 
      for (int d = 0; d < termCounts.length; d++) {
        if (! reader.isDeleted(d)) {
          if (sim == null)
            reader.setNorm(d, fieldName, fakeNorms[0]);
          else
            reader.setNorm(d, fieldName, sim.encodeNorm(sim.lengthNorm(fieldName, termCounts[d])));
        }
      }
      
    } finally {
      if (null != reader) reader.close();
    }