io.yucca.lucene.FieldRemover.java Source code

Java tutorial

Introduction

Here is the source code for io.yucca.lucene.FieldRemover.java

Source

package io.yucca.lucene;

/*
 * Copyright 2014 Rob Sessink
 * 
 * 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.File;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import org.apache.lucene.index.AtomicReader;
import org.apache.lucene.index.AtomicReaderContext;
import org.apache.lucene.index.FieldFilterAtomicReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.MultiReader;
import org.apache.lucene.util.IOUtils;
import org.apache.lucene.util.Version;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * FieldRemover, removes fields from an index. This reads an existing index and
 * writes a new index without the specified fields.
 * 
 * @author <a href="mailto:rob@yucca.io">Rob Sessink</a>
 * @version $Id$
 */
public class FieldRemover {

    static final Logger log = LoggerFactory.getLogger(FieldRemover.class);

    public FieldRemover() {
    }

    /**
     * Remove fields from an index
     * 
     * @param sourceIndexDirectory
     *            File source index directory
     * @param destIndexDirectory
     *            File destination index directory
     * @param fields
     *            String[] fields to remove
     * @param version
     *            Version Lucene index version i.e. 4.2
     */
    public void removeFields(File sourceIndexDirectory, File destIndexDirectory, String[] fields, Version version) {
        log.info("Writing a new index to: {}, based on source index: {}, thereby removing the fields: {}",
                destIndexDirectory, sourceIndexDirectory, join(fields, ","));
        IndexReader reader = IndexHelper.getIndexReader(sourceIndexDirectory);
        // Version version = helper.getIndexVersion(sourceIndexDirectory);
        IndexWriter writer = IndexHelper.getIndexWriter(destIndexDirectory, version);
        removeFields(reader, writer, fields);
        log.info("New index successfully written to: {}", destIndexDirectory);
    }

    /**
     * Remove fields from an index. All readers and writer are closed on
     * completion or on an exception.
     * 
     * @param reader
     *            IndexReader
     * @param writer
     *            IndexWriter
     *            File destination index directory
     * @param fields
     *            String[] fields to remove
     */
    public void removeFields(IndexReader reader, IndexWriter writer, String[] fields) {
        Set<String> removals = toTrimmedSet(fields);
        List<AtomicReaderContext> leaves = reader.leaves();
        AtomicReader wrappedLeaves[] = new AtomicReader[leaves.size()];
        for (int i = 0; i < leaves.size(); i++) {
            wrappedLeaves[i] = new FieldFilterAtomicReader(leaves.get(i).reader(), removals, true);
        }
        try {
            MultiReader mr = new MultiReader(wrappedLeaves, true);
            writer.addIndexes(mr);
            writer.commit();
            writer.close();
            mr.close();
        } catch (IOException e) {
            log.error("Writing new index failed.", e);
        } finally {
            IOUtils.closeWhileHandlingException(reader);
            IOUtils.closeWhileHandlingException(writer);
            IOUtils.closeWhileHandlingException(writer.getDirectory());
        }
    }

    private static Set<String> toTrimmedSet(String[] fields) {
        Set<String> removals = new TreeSet<String>();
        for (String field : fields) {
            removals.add(field.trim());
        }
        return removals;
    }

    private static String join(String[] array, String seperator) {
        String joined = "";
        if (array != null) {
            for (int i = 0; i < array.length; i++) {
                joined = joined.concat(array[i]);
                if (i + 1 < array.length) {
                    joined = joined.concat(seperator);
                }
            }
        }
        return joined;
    }

}