searchindex.java

来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 1,046 行 · 第 1/3 页

JAVA
1,046
字号
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.jackrabbit.core.query.lucene;import org.apache.jackrabbit.core.ItemManager;import org.apache.jackrabbit.core.SessionImpl;import org.apache.jackrabbit.core.NodeId;import org.apache.jackrabbit.core.NodeIdIterator;import org.apache.jackrabbit.core.query.AbstractQueryHandler;import org.apache.jackrabbit.core.query.ExecutableQuery;import org.apache.jackrabbit.core.query.QueryHandlerContext;import org.apache.jackrabbit.core.query.QueryHandler;import org.apache.jackrabbit.core.state.NodeState;import org.apache.jackrabbit.core.state.NodeStateIterator;import org.apache.jackrabbit.extractor.DefaultTextExtractor;import org.apache.jackrabbit.extractor.TextExtractor;import org.apache.jackrabbit.name.NoPrefixDeclaredException;import org.apache.jackrabbit.name.QName;import org.apache.jackrabbit.name.NameFormat;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.apache.lucene.analysis.Analyzer;import org.apache.lucene.analysis.standard.StandardAnalyzer;import org.apache.lucene.index.IndexReader;import org.apache.lucene.index.MultiReader;import org.apache.lucene.search.Hits;import org.apache.lucene.search.IndexSearcher;import org.apache.lucene.search.Query;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.commons.collections.iterators.AbstractIteratorDecorator;import javax.jcr.RepositoryException;import javax.jcr.query.InvalidQueryException;import java.io.IOException;import java.io.File;import java.util.Iterator;import java.util.List;import java.util.ArrayList;import java.util.HashSet;import java.util.Set;import java.util.Arrays;/** * Implements a {@link org.apache.jackrabbit.core.query.QueryHandler} using * Lucene. */public class SearchIndex extends AbstractQueryHandler {    /** The logger instance for this class */    private static final Logger log = LoggerFactory.getLogger(SearchIndex.class);    /**     * Name of the file to persist search internal namespace mappings.     */    private static final String NS_MAPPING_FILE = "ns_mappings.properties";    /**     * The default value for property {@link #minMergeDocs}.     */    public static final int DEFAULT_MIN_MERGE_DOCS = 100;    /**     * The default value for property {@link #maxMergeDocs}.     */    public static final int DEFAULT_MAX_MERGE_DOCS = 100000;    /**     * the default value for property {@link #mergeFactor}.     */    public static final int DEFAULT_MERGE_FACTOR = 10;    /**     * the default value for property {@link #maxFieldLength}.     */    public static final int DEFAULT_MAX_FIELD_LENGTH = 10000;    /**     * The default value for property {@link #extractorPoolSize}.     */    public static final int DEFAULT_EXTRACTOR_POOL_SIZE = 0;    /**     * The default value for property {@link #extractorBackLog}.     */    public static final int DEFAULT_EXTRACTOR_BACK_LOG = 100;    /**     * The default timeout in milliseconds which is granted to the text     * extraction process until fulltext indexing is deferred to a background     * thread.     */    public static final long DEFAULT_EXTRACTOR_TIMEOUT = 100;    /**     * The actual index     */    private MultiIndex index;    /**     * The analyzer we use for indexing.     */    private Analyzer analyzer;    /**     * List of text extractor and text filter class names. The configured     * classes will be instantiated and used to extract text content from     * binary properties.     */    private String textFilterClasses =        DefaultTextExtractor.class.getName();    /**     * Text extractor for extracting text content of binary properties.     */    private TextExtractor extractor;    /**     * The location of the search index.     * <p/>     * Note: This is a <b>mandatory</b> parameter!     */    private String path;    /**     * minMergeDocs config parameter.     */    private int minMergeDocs = DEFAULT_MIN_MERGE_DOCS;    /**     * volatileIdleTime config parameter.     */    private int volatileIdleTime = 3;    /**     * maxMergeDocs config parameter     */    private int maxMergeDocs = DEFAULT_MAX_MERGE_DOCS;    /**     * mergeFactor config parameter     */    private int mergeFactor = DEFAULT_MERGE_FACTOR;    /**     * maxFieldLength config parameter     */    private int maxFieldLength = DEFAULT_MAX_FIELD_LENGTH;    /**     * extractorPoolSize config parameter     */    private int extractorPoolSize = DEFAULT_EXTRACTOR_POOL_SIZE;    /**     * extractorBackLog config parameter     */    private int extractorBackLog = DEFAULT_EXTRACTOR_BACK_LOG;    /**     * extractorTimeout config parameter     */    private long extractorTimeout = DEFAULT_EXTRACTOR_TIMEOUT;    /**     * Number of documents that are buffered before they are added to the index.     */    private int bufferSize = 10;    /**     * Compound file flag     */    private boolean useCompoundFile = true;    /**     * Flag indicating whether document order is enable as the default ordering.     */    private boolean documentOrder = true;    /**     * If set <code>true</code> the index is checked for consistency on startup.     * If <code>false</code> a consistency check is only performed when there     * are entries in the redo log on startup.     * <p/>     * Default value is: <code>false</code>.     */    private boolean forceConsistencyCheck = false;    /**     * If set <code>true</code> errors detected by the consistency check are     * repaired. If <code>false</code> the errors are only reported in the log.     * <p/>     * Default value is: <code>true</code>.     */    private boolean autoRepair = true;    /**     * The uuid resolver cache size.     * <p/>     * Default value is: <code>1000</code>.     */    private int cacheSize = 1000;    /**     * The number of documents that are pre fetched when a query is executed.     * <p/>     * Default value is: {@link Integer#MAX_VALUE}.     */    private int resultFetchSize = Integer.MAX_VALUE;    /**     * If set to <code>true</code> the fulltext field is stored and and a term     * vector is created with offset information.     * <p/>     * Default value is: <code>false</code>.     */    private boolean supportHighlighting = false;    /**     * The excerpt provider class. Implements {@link ExcerptProvider}.     */    private Class excerptProviderClass = DefaultXMLExcerpt.class;    /**     * Indicates if this <code>SearchIndex</code> is closed and cannot be used     * anymore.     */    private boolean closed = false;    /**     * Default constructor.     */    public SearchIndex() {        this.analyzer = new StandardAnalyzer(new String[]{});    }    /**     * Initializes this <code>QueryHandler</code>. This implementation requires     * that a path parameter is set in the configuration. If this condition     * is not met, a <code>IOException</code> is thrown.     *     * @throws IOException if an error occurs while initializing this handler.     */    protected void doInit() throws IOException {        QueryHandlerContext context = getContext();        if (path == null) {            throw new IOException("SearchIndex requires 'path' parameter in configuration!");        }        Set excludedIDs = new HashSet();        if (context.getExcludedNodeId() != null) {            excludedIDs.add(context.getExcludedNodeId());        }        extractor = createTextExtractor();        File indexDir = new File(path);        NamespaceMappings nsMappings;        if (context.getParentHandler() instanceof SearchIndex) {            // use system namespace mappings            SearchIndex sysIndex = (SearchIndex) context.getParentHandler();            nsMappings = sysIndex.getNamespaceMappings();        } else {            // read local namespace mappings            File mapFile = new File(indexDir, NS_MAPPING_FILE);            if (mapFile.exists()) {                // be backward compatible and use ns_mappings.properties from                // index folder                nsMappings = new FileBasedNamespaceMappings(mapFile);            } else {                // otherwise use repository wide stable index prefix from                // namespace registry                nsMappings = new NSRegistryBasedNamespaceMappings(                        context.getNamespaceRegistry());            }        }        index = new MultiIndex(indexDir, this, context.getItemStateManager(),                context.getRootId(), excludedIDs, nsMappings);        if (index.getRedoLogApplied() || forceConsistencyCheck) {            log.info("Running consistency check...");            try {                ConsistencyCheck check = ConsistencyCheck.run(index,                        context.getItemStateManager());                if (autoRepair) {                    check.repair(true);                } else {                    List errors = check.getErrors();                    if (errors.size() == 0) {                        log.info("No errors detected.");                    }                    for (Iterator it = errors.iterator(); it.hasNext();) {                        ConsistencyCheckError err = (ConsistencyCheckError) it.next();                        log.info(err.toString());                    }                }            } catch (Exception e) {                log.warn("Failed to run consistency check on index: " + e);            }        }        log.info("Index initialized: " + path);    }    /**     * Adds the <code>node</code> to the search index.     * @param node the node to add.     * @throws RepositoryException if an error occurs while indexing the node.     * @throws IOException if an error occurs while adding the node to the index.     */    public void addNode(NodeState node) throws RepositoryException, IOException {        throw new UnsupportedOperationException("addNode");    }    /**     * Removes the node with <code>uuid</code> from the search index.     * @param id the id of the node to remove from the index.     * @throws IOException if an error occurs while removing the node from     * the index.     */    public void deleteNode(NodeId id) throws IOException {        throw new UnsupportedOperationException("deleteNode");    }    /**     * This implementation forwards the call to     * {@link MultiIndex#update(java.util.Iterator, java.util.Iterator)} and     * transforms the two iterators to the required types.     *     * @param remove uuids of nodes to remove.     * @param add    NodeStates to add. Calls to <code>next()</code> on this     *               iterator may return <code>null</code>, to indicate that a     *               node could not be indexed successfully.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?