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 + -
显示快捷键?