Index: src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java (revision 569308)
+++ src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java (working copy)
@@ -206,6 +206,12 @@
private boolean reindexing = false;
/**
+ * Flag indicating wether the current workspace did
+ * have a persistent index already or not.
+ */
+ private boolean newWorkSpaceIndex = false;
+
+ /**
* Creates a new MultiIndex.
*
* @param indexDir the base file system
@@ -312,6 +318,7 @@
// do an initial index if there are no indexes at all
if (indexNames.size() == 0) {
reindexing = true;
+ newWorkSpaceIndex = true;
// traverse and index workspace
executeAndLog(new Start(Action.INTERNAL_TRANSACTION));
NodeState rootState = (NodeState) stateMgr.getItemState(rootId);
@@ -837,6 +844,13 @@
attemptDelete();
}
+ /**
+ * @return wether this is the first index for the workspace
+ */
+ public boolean getNewWorkSpaceIndex() {
+ return newWorkSpaceIndex;
+ }
+
//-------------------------< internal >-------------------------------------
/**
@@ -1870,4 +1884,5 @@
return logLine.toString();
}
}
+
}
Index: src/main/java/org/apache/jackrabbit/core/query/lucene/IndexFormatVersion.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/query/lucene/IndexFormatVersion.java (revision 0)
+++ src/main/java/org/apache/jackrabbit/core/query/lucene/IndexFormatVersion.java (revision 0)
@@ -0,0 +1,59 @@
+/*
+ * 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;
+
+/**
+ * This class indicates the lucene index format that is used. Old formats
+ * do not have the PROPERTIES_SET lucene fieldname. Old formats
+ * are compatible. When the index is recreated from scratch, the new
+ * format will automatically be used. This format is faster certain queries, so
+ * if the index does not contain PROPERTIES_SET fieldname and re-indexing
+ * is an option, this is advisable.
+ */
+public class IndexFormatVersion {
+ /**
+ * V1 is the old index format
+ */
+ public static final IndexFormatVersion V1 = new IndexFormatVersion("1");
+
+ /**
+ * V2 is the new index format
+ */
+ public static final IndexFormatVersion V2 = new IndexFormatVersion("2");
+
+ /**
+ * The used version of the index format
+ */
+ private final String version;
+
+ /**
+ * Creates a index format version.
+ *
+ * @param version The version of the index.
+ */
+ private IndexFormatVersion(String version) {
+ this.version = version;
+ }
+
+ /**
+ * Returns the index format version
+ * @return the index format version.
+ */
+ public String getVersion(){
+ return version;
+ }
+}
Property changes on: src\main\java\org\apache\jackrabbit\core\query\lucene\IndexFormatVersion.java
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Index: src/main/java/org/apache/jackrabbit/core/query/lucene/QueryImpl.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/query/lucene/QueryImpl.java (revision 569308)
+++ src/main/java/org/apache/jackrabbit/core/query/lucene/QueryImpl.java (working copy)
@@ -146,7 +146,7 @@
// build lucene query
Query query = LuceneQueryBuilder.createQuery(root, session,
index.getContext().getItemStateManager(), index.getNamespaceMappings(),
- index.getTextAnalyzer(), propReg, index.getSynonymProvider());
+ index.getTextAnalyzer(), propReg, index.getSynonymProvider(), index.getIndexFormatVersion());
OrderQueryNode orderNode = root.getOrderNode();
Index: src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java (revision 569308)
+++ src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java (working copy)
@@ -96,6 +96,11 @@
protected boolean supportHighlighting = false;
/**
+ * Indicates if this index format is new or old
+ */
+ protected IndexFormatVersion indexFormatVersion;
+
+ /**
* Creates a new node indexer.
*
* @param node the node state to index.
@@ -132,6 +137,15 @@
}
/**
+ * Sets wether the index is of new format.
+ *
+ * @param indexFormatVersion when IndexFormatVersion.V2, index format is new.
+ */
+ public void setIndexFormatVersion(IndexFormatVersion indexFormatVersion) {
+ this.indexFormatVersion = indexFormatVersion;
+ }
+
+ /**
* Sets the indexing configuration for this node indexer.
*
* @param config the indexing configuration.
@@ -148,6 +162,7 @@
* values from the ItemStateProvider.
*/
protected Document createDoc() throws RepositoryException {
+ System.out.println("create doc");
Document doc = new Document();
doc.setBoost(getNodeBoost());
@@ -189,6 +204,14 @@
PropertyId id = new PropertyId(node.getNodeId(), propName);
try {
PropertyState propState = (PropertyState) stateProvider.getItemState(id);
+
+ // add each property to the _PROPERTIES_SET for searching
+ // if index format is new
+
+ if(indexFormatVersion == IndexFormatVersion.V2) {
+ addPropertyName(doc,propState.getName());
+ }
+
InternalValue[] values = propState.getValues();
for (int i = 0; i < values.length; i++) {
addValue(doc, values[i], propState.getName());
@@ -313,6 +336,22 @@
}
/**
+ * Adds the propertyname to the lucene _PROPERTIES_SET field.
+ *
+ * @param doc the document.
+ * @param name the name of the property.
+ */
+ private void addPropertyName(Document doc, QName name) {
+ String fieldName = name.getLocalName();
+ try {
+ fieldName = NameFormat.format(name, mappings);
+ } catch (NoPrefixDeclaredException e) {
+ // will never happen
+ }
+ doc.add(new Field(FieldNames.PROPERTIES_SET,fieldName,Field.Store.NO,Field.Index.NO_NORMS));
+ }
+
+ /**
* Adds the binary value to the document as the named field.
*
SearchIndex index format is new.
+ * If you have multiple workspaces, some indices might
+ * be in the old format, while others in the new.
+ */
+ private IndexFormatVersion indexFormatVersion;
+
+ /**
* Default constructor.
*/
public SearchIndex() {
@@ -316,6 +325,7 @@
* @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!");
@@ -375,6 +385,34 @@
log.warn("Failed to run consistency check on index: " + e);
}
}
+
+ /*
+ * The index is in the new format if either the index already contains
+ * the field FieldNames.PROPERTIES_SET in any document, or if the index
+ * is empty, or if index.getNewWorkSpaceIndex() is true.
+ * If the format is old, old style indexing and searching is used
+ */
+
+ IndexReader indexReader = index.getIndexReader();
+ Collection allFieldNames = indexReader.getFieldNames(FieldOption.ALL);
+ int numDocs = indexReader.numDocs();
+
+ if(allFieldNames.contains(FieldNames.PROPERTIES_SET)
+ || numDocs == 0
+ || index.getNewWorkSpaceIndex()) {
+ // new style index formant
+ setIndexFormatVersion(IndexFormatVersion.V2);
+ } else {
+ // old style index format
+ setIndexFormatVersion(IndexFormatVersion.V1);
+ }
+ indexReader.close();
+
+ if(!(indexFormatVersion == IndexFormatVersion.V2) ) {
+ log.warn("Index is in old format. This might imply slower queries. " +
+ "Re-index if possible");
+ }
+ System.out.println("indexFormatVersion " + indexFormatVersion.getVersion());
log.info("Index initialized: " + path);
}
@@ -703,6 +741,7 @@
getContext().getItemStateManager(), nsMappings, extractor);
indexer.setSupportHighlighting(supportHighlighting);
indexer.setIndexingConfiguration(indexingConfig);
+ indexer.setIndexFormatVersion(indexFormatVersion);
Document doc = indexer.createDoc();
mergeAggregatedNodeIndexes(node, doc);
return doc;
@@ -1470,6 +1509,25 @@
public boolean getEnableConsistencyCheck() {
return consistencyCheckEnabled;
}
+
+ /**
+ * Sets the index formant version used for this index
+ *
+ * @param indexFormatVersion which can be #IndexFormatVersion.V1 (old format) or
+ * #IndexFormatVersion.V2 (new format).
+ */
+ private void setIndexFormatVersion(IndexFormatVersion indexFormatVersion){
+ this.indexFormatVersion = indexFormatVersion;
+ }
+
+ /**
+ *
+ * @return the used index format version for this index, #IndexFormatVersion.V1
+ * or #IndexFormatVersion.V2
+ */
+ public IndexFormatVersion getIndexFormatVersion(){
+ return indexFormatVersion;
+ }
//----------------------------< internal >----------------------------------
Index: src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryBuilder.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryBuilder.java (revision 569328)
+++ src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryBuilder.java (working copy)
@@ -130,6 +130,11 @@
private SynonymProvider synonymProvider;
/**
+ * Wether the index format is new or old.
+ */
+ private IndexFormatVersion indexFormatVersion;
+
+ /**
* Exceptions thrown during tree translation
*/
private List exceptions = new ArrayList();
@@ -155,7 +160,8 @@
NamespaceMappings nsMappings,
Analyzer analyzer,
PropertyTypeRegistry propReg,
- SynonymProvider synonymProvider) {
+ SynonymProvider synonymProvider,
+ IndexFormatVersion indexFormatVersion) {
this.root = root;
this.session = session;
this.sharedItemMgr = sharedItemMgr;
@@ -164,6 +170,7 @@
this.analyzer = analyzer;
this.propRegistry = propReg;
this.synonymProvider = synonymProvider;
+ this.indexFormatVersion = indexFormatVersion;
}
/**
@@ -180,6 +187,7 @@
* information.
* @param synonymProvider the synonym provider or null if node
* is configured.
+ * @param indexFormatVersion the index format version to be used
* @return the lucene query tree.
* @throws RepositoryException if an error occurs during the translation.
*/
@@ -189,7 +197,8 @@
NamespaceMappings nsMappings,
Analyzer analyzer,
PropertyTypeRegistry propReg,
- SynonymProvider synonymProvider)
+ SynonymProvider synonymProvider,
+ IndexFormatVersion indexFormatVersion)
throws RepositoryException {
NodeId id = ((NodeImpl) session.getRootNode()).getNodeId();
@@ -197,7 +206,7 @@
id, sharedItemMgr, session);
LuceneQueryBuilder builder = new LuceneQueryBuilder(
root, session, sharedItemMgr, hmgr, nsMappings,
- analyzer, propReg, synonymProvider);
+ analyzer, propReg, synonymProvider, indexFormatVersion);
Query q = builder.createLuceneQuery();
if (builder.exceptions.size() > 0) {
@@ -543,7 +552,7 @@
// todo this will traverse the whole index, optimize!
Query subQuery = null;
try {
- subQuery = new MatchAllQuery(NameFormat.format(QName.JCR_PRIMARYTYPE, nsMappings));
+ subQuery = createMatchAllQuery(NameFormat.format(QName.JCR_PRIMARYTYPE, nsMappings));
} catch (NoPrefixDeclaredException e) {
// will never happen, prefixes are created when unknown
}
@@ -584,7 +593,7 @@
}
if (node.getIncludeDescendants()) {
- Query refPropQuery = new MatchAllQuery(refProperty);
+ Query refPropQuery = createMatchAllQuery(refProperty);
context = new DescendantSelfAxisQuery(context, refPropQuery, false);
}
@@ -789,7 +798,7 @@
// the like operation always has one string value.
// no coercing, see above
if (stringValues[0].equals("%")) {
- query = new MatchAllQuery(field);
+ query = createMatchAllQuery(field);
} else {
query = new WildcardQuery(FieldNames.PROPERTIES, field, stringValues[0], transform[0]);
}
@@ -810,7 +819,7 @@
case QueryConstants.OPERATION_NE_VALUE: // !=
// match nodes with property 'field' that includes svp and mvp
BooleanQuery notQuery = new BooleanQuery();
- notQuery.add(new MatchAllQuery(field), Occur.SHOULD);
+ notQuery.add(createMatchAllQuery(field), Occur.SHOULD);
// exclude all nodes where 'field' has the term in question
for (int i = 0; i < stringValues.length; i++) {
Term t = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, stringValues[i]));
@@ -836,7 +845,7 @@
// minus the nodes that have a multi-valued property 'field' and
// all values are equal to term in question
notQuery = new BooleanQuery();
- notQuery.add(new MatchAllQuery(field), Occur.SHOULD);
+ notQuery.add(createMatchAllQuery(field), Occur.SHOULD);
for (int i = 0; i < stringValues.length; i++) {
// exclude the nodes that have the term and are single valued
Term t = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, stringValues[i]));
@@ -859,7 +868,7 @@
query = notQuery;
break;
case QueryConstants.OPERATION_NULL:
- query = new NotQuery(new MatchAllQuery(field));
+ query = new NotQuery(createMatchAllQuery(field));
break;
case QueryConstants.OPERATION_SIMILAR:
String uuid = "x";
@@ -874,7 +883,7 @@
query = new SimilarityQuery(uuid, analyzer);
break;
case QueryConstants.OPERATION_NOT_NULL:
- query = new MatchAllQuery(field);
+ query = createMatchAllQuery(field);
break;
default:
throw new IllegalArgumentException("Unknown relation operation: "
@@ -1082,4 +1091,23 @@
}
return (String[]) values.toArray(new String[values.size()]);
}
+
+ /**
+ * Depeding wether the index is of the new index format this method
+ * returns a query that matches all nodes that have property 'field'
+ *
+ * @param field
+ * @return Query that matches all nodes that contain the property field
+ */
+ private final Query createMatchAllQuery(String field){
+ if(indexFormatVersion == indexFormatVersion.V2) {
+ // new index format style
+ return new TermQuery(new Term(FieldNames.PROPERTIES_SET,field));
+ } else {
+ // old index format style : might be slow
+ log.debug("You are using old index format style. If performance issues, " +
+ "re-index if possible");
+ return new MatchAllQuery(field);
+ }
+ }
}