Skip to content

Commit

Permalink
MODE-668 Updated the IndexRules to have a flag describing whether ful…
Browse files Browse the repository at this point in the history
…l-text search is enabled on a field, then set this correctly based upon the PropertyDefinition.isFullTextSearchable() value. Then changed the LuceneSearchEngine implementation to use this new flag to dictate how property values are indexed.

All tests pass.

git-svn-id: https://svn.jboss.org/repos/modeshape/trunk@1663 76366958-4244-0410-ad5e-bbfabb93f86b
  • Loading branch information
Randall Hauch committed Feb 26, 2010
1 parent 44dddcd commit 237caaa
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ public static interface Rule {

boolean canBeReference();

boolean isFullTextSearchable();

FieldType getType();

Field.Store getStoreOption();
Expand Down Expand Up @@ -102,6 +104,16 @@ public boolean isSkipped() {
return true;
}

/**
* {@inheritDoc}
*
* @see org.modeshape.search.lucene.IndexRules.Rule#isFullTextSearchable()
*/
@Override
public boolean isFullTextSearchable() {
return false;
}

/**
* {@inheritDoc}
*
Expand Down Expand Up @@ -134,18 +146,21 @@ public Store getStoreOption() {
@Immutable
protected static class TypedRule implements Rule {
protected final boolean canBeReference;
protected final boolean fullTextSearchable;
protected final FieldType type;
protected final Field.Store store;
protected final Field.Index index;

protected TypedRule( FieldType type,
Field.Store store,
Field.Index index,
boolean canBeReference ) {
boolean canBeReference,
boolean fullTextSearchable ) {
this.type = type;
this.index = index;
this.store = store;
this.canBeReference = canBeReference;
this.fullTextSearchable = fullTextSearchable;
assert this.type != null;
assert this.index != null;
assert this.store != null;
Expand All @@ -169,6 +184,16 @@ public boolean isSkipped() {
return false;
}

/**
* {@inheritDoc}
*
* @see org.modeshape.search.lucene.IndexRules.Rule#isFullTextSearchable()
*/
@Override
public boolean isFullTextSearchable() {
return fullTextSearchable;
}

/**
* {@inheritDoc}
*
Expand Down Expand Up @@ -218,7 +243,7 @@ protected NumericTypedRule( FieldType type,
Field.Index index,
T minValue,
T maxValue ) {
super(type, store, index, false);
super(type, store, index, false, false);
this.minValue = minValue;
this.maxValue = maxValue;
assert this.minValue != null;
Expand Down Expand Up @@ -332,14 +357,16 @@ public Builder skip( Name... namesToIndex ) {
* @param store the storage setting, or null if the field should be {@link Store#YES stored}
* @param index the index setting, or null if the field should be indexed but {@link Index#NOT_ANALYZED not analyzed}
* @param canBeReference true if this field can contain references; or false if it cannot
* @param fullTextSearchable true if this field is full-text searchable, or false otherwise
* @return this builder for convenience and method chaining; never null
*/
public Builder defaultTo( Field.Store store,
Field.Index index,
boolean canBeReference ) {
boolean canBeReference,
boolean fullTextSearchable ) {
if (store == null) store = Field.Store.YES;
if (index == null) index = Field.Index.NOT_ANALYZED;
defaultRule = new TypedRule(FieldType.STRING, store, index, canBeReference);
defaultRule = new TypedRule(FieldType.STRING, store, index, canBeReference, fullTextSearchable);
return this;
}

Expand All @@ -350,15 +377,17 @@ public Builder defaultTo( Field.Store store,
* @param store the storage setting, or null if the field should be {@link Store#YES stored}
* @param index the index setting, or null if the field should be indexed but {@link Index#NOT_ANALYZED not analyzed}
* @param canBeReference true if this field can contain references; or false if it cannot
* @param fullTextSearchable true if this field is full-text searchable, or false otherwise
* @return this builder for convenience and method chaining; never null
*/
public Builder stringField( Name name,
Field.Store store,
Field.Index index,
boolean canBeReference ) {
boolean canBeReference,
boolean fullTextSearchable ) {
if (store == null) store = Field.Store.YES;
if (index == null) index = Field.Index.NOT_ANALYZED;
Rule rule = new TypedRule(FieldType.STRING, store, index, canBeReference);
Rule rule = new TypedRule(FieldType.STRING, store, index, canBeReference, fullTextSearchable);
rulesByName.put(name, rule);
return this;
}
Expand All @@ -369,14 +398,16 @@ public Builder stringField( Name name,
* @param name the name of the field
* @param store the storage setting, or null if the field should be {@link Store#YES stored}
* @param index the index setting, or null if the field should be indexed but {@link Index#NOT_ANALYZED not analyzed}
* @param fullTextSearchable true if this field is full-text searchable, or false otherwise
* @return this builder for convenience and method chaining; never null
*/
public Builder binaryField( Name name,
Field.Store store,
Field.Index index ) {
Field.Index index,
boolean fullTextSearchable ) {
if (store == null) store = Field.Store.YES;
if (index == null) index = Field.Index.NOT_ANALYZED;
Rule rule = new TypedRule(FieldType.BINARY, store, index, false);
Rule rule = new TypedRule(FieldType.BINARY, store, index, false, fullTextSearchable);
rulesByName.put(name, rule);
return this;
}
Expand All @@ -394,7 +425,7 @@ public Builder referenceField( Name name,
Field.Index index ) {
if (store == null) store = Field.Store.YES;
if (index == null) index = Field.Index.NOT_ANALYZED;
Rule rule = new TypedRule(FieldType.REFERENCE, store, index, true);
Rule rule = new TypedRule(FieldType.REFERENCE, store, index, true, false);
rulesByName.put(name, rule);
return this;
}
Expand All @@ -405,14 +436,16 @@ public Builder referenceField( Name name,
* @param name the name of the field
* @param store the storage setting, or null if the field should be {@link Store#YES stored}
* @param index the index setting, or null if the field should be indexed but {@link Index#NOT_ANALYZED not analyzed}
* @param fullTextSearchable true if this field is full-text searchable, or false otherwise
* @return this builder for convenience and method chaining; never null
*/
public Builder weakReferenceField( Name name,
Field.Store store,
Field.Index index ) {
Field.Index index,
boolean fullTextSearchable ) {
if (store == null) store = Field.Store.YES;
if (index == null) index = Field.Index.NOT_ANALYZED;
Rule rule = new TypedRule(FieldType.WEAK_REFERENCE, store, index, false);
Rule rule = new TypedRule(FieldType.WEAK_REFERENCE, store, index, false, fullTextSearchable);
rulesByName.put(name, rule);
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,10 @@ public class LuceneSearchEngine extends AbstractLuceneSearchEngine<LuceneSearchW

IndexRules.Builder builder = IndexRules.createBuilder();
// Configure the default behavior ...
builder.defaultTo(Field.Store.YES, Field.Index.ANALYZED, true);
builder.defaultTo(Field.Store.YES, Field.Index.ANALYZED, true, true);
// Configure the UUID properties to be just indexed and stored (not analyzed, not included in full-text) ...
builder.stringField(JcrLexicon.UUID, Field.Store.YES, Field.Index.NOT_ANALYZED, false);
builder.stringField(ModeShapeLexicon.UUID, Field.Store.YES, Field.Index.NOT_ANALYZED, false);
builder.stringField(JcrLexicon.UUID, Field.Store.YES, Field.Index.NOT_ANALYZED, false, false);
builder.stringField(ModeShapeLexicon.UUID, Field.Store.YES, Field.Index.NOT_ANALYZED, false, false);
// Configure the properties that we'll treat as dates ...
builder.dateField(JcrLexicon.CREATED, Field.Store.YES, Field.Index.NOT_ANALYZED, earliestChangeDate);
builder.dateField(JcrLexicon.LAST_MODIFIED, Field.Store.YES, Field.Index.NOT_ANALYZED, earliestChangeDate);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,8 @@ protected void setOrReplaceProperties( Location location,
}
}
}
if (!treatedAsReference && rule.getIndexOption() != Field.Index.NO && !NON_SEARCHABLE_NAMES.contains(name)) {
if (!treatedAsReference && rule.getIndexOption() != Field.Index.NO && rule.isFullTextSearchable()
&& !NON_SEARCHABLE_NAMES.contains(name)) {
// This field is to be full-text searchable ...
fullTextSearchValue.append(' ').append(stringValue);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void shouldBuildValidRulesFromBuilderThatIsNotInvoked() {

@Test
public void shouldBuildValidRulesFromBuilderAfterJustSettingDefaultRules() {
builder.defaultTo(Field.Store.NO, Field.Index.ANALYZED_NO_NORMS, false);
builder.defaultTo(Field.Store.NO, Field.Index.ANALYZED_NO_NORMS, false, false);
rules = builder.build();
assertThat(rules.getRule(null).getIndexOption(), is(Field.Index.ANALYZED_NO_NORMS));
assertThat(rules.getRule(null).getStoreOption(), is(Field.Store.NO));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ public RepositoryConnection createConnection( String name ) throws RepositorySou

// Set up the provider and the search engine ...
IndexRules.Builder rulesBuilder = IndexRules.createBuilder(LuceneSearchEngine.DEFAULT_RULES);
rulesBuilder.defaultTo(Field.Store.YES, Field.Index.NOT_ANALYZED, false);
rulesBuilder.stringField(name("model"), Field.Store.YES, Field.Index.ANALYZED, false);
rulesBuilder.defaultTo(Field.Store.YES, Field.Index.NOT_ANALYZED, false, true);
rulesBuilder.stringField(name("model"), Field.Store.YES, Field.Index.ANALYZED, false, true);
rulesBuilder.integerField(name("year"), Field.Store.YES, Field.Index.NOT_ANALYZED, 1990, 2020);
rulesBuilder.floatField(name("userRating"), Field.Store.YES, Field.Index.NOT_ANALYZED, 0.0f, 10.0f);
rulesBuilder.integerField(name("mpgCity"), Field.Store.YES, Field.Index.NOT_ANALYZED, 0, 50);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ public RepositoryConnection createConnection( String sourceName ) throws Reposit

// Set up the provider and the search engine ...
IndexRules.Builder rulesBuilder = IndexRules.createBuilder(LuceneSearchEngine.DEFAULT_RULES);
rulesBuilder.defaultTo(Field.Store.YES, Field.Index.NOT_ANALYZED, false);
rulesBuilder.stringField(name("model"), Field.Store.YES, Field.Index.ANALYZED, false);
rulesBuilder.defaultTo(Field.Store.YES, Field.Index.NOT_ANALYZED, false, true);
rulesBuilder.stringField(name("model"), Field.Store.YES, Field.Index.ANALYZED, false, true);
rulesBuilder.integerField(name("year"), Field.Store.YES, Field.Index.NOT_ANALYZED);
rulesBuilder.floatField(name("userRating"), Field.Store.YES, Field.Index.NOT_ANALYZED, 0.0f, 10.0f);
rulesBuilder.integerField(name("mpgCity"), Field.Store.YES, Field.Index.NOT_ANALYZED, 0, 50);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@
@Immutable
class NodeTypeSchemata implements Schemata {

protected static final boolean DEFAULT_CAN_CONTAIN_REFERENCES = true;
protected static final boolean DEFAULT_FULL_TEXT_SEARCHABLE = true;

private final Schemata schemata;
private final Map<Integer, String> types;
private final Map<String, String> prefixesByUris = new HashMap<String, String>();
Expand Down Expand Up @@ -104,7 +107,10 @@ class NodeTypeSchemata implements Schemata {

// Create the "ALLNODES" table, which will contain all possible properties ...
IndexRules.Builder indexRulesBuilder = IndexRules.createBuilder(LuceneSearchEngine.DEFAULT_RULES);
indexRulesBuilder.defaultTo(Field.Store.YES, Field.Index.ANALYZED, true);
indexRulesBuilder.defaultTo(Field.Store.YES,
Field.Index.ANALYZED,
DEFAULT_CAN_CONTAIN_REFERENCES,
DEFAULT_FULL_TEXT_SEARCHABLE);
addAllNodesTable(builder, indexRulesBuilder, context);

// Define a view for each node type ...
Expand Down Expand Up @@ -194,7 +200,7 @@ protected final void addIndexRule( IndexRules.Builder builder,
Store store = Store.YES;
Index index = defn.isFullTextSearchable() ? Index.ANALYZED : Index.NO;
if (typeSystem.getStringFactory().getTypeName().equals(type)) {
builder.stringField(defn.getInternalName(), store, index, canBeReference);
builder.stringField(defn.getInternalName(), store, index, canBeReference, defn.isFullTextSearchable());
} else if (typeSystem.getDateTimeFactory().getTypeName().equals(type)) {
Long minimum = typeSystem.getLongFactory().create(defn.getMinimumValue());
Long maximum = typeSystem.getLongFactory().create(defn.getMaximumValue());
Expand All @@ -211,16 +217,16 @@ protected final void addIndexRule( IndexRules.Builder builder,
builder.booleanField(defn.getInternalName(), store, index);
} else if (typeSystem.getBinaryFactory().getTypeName().equals(type)) {
store = Store.NO;
builder.binaryField(defn.getInternalName(), store, index);
builder.binaryField(defn.getInternalName(), store, index, defn.isFullTextSearchable());
} else if (typeSystem.getReferenceFactory().getTypeName().equals(type)) {
store = Store.NO;
builder.referenceField(defn.getInternalName(), store, index);
} else if (typeSystem.getPathFactory().getTypeName().equals(type)) {
store = Store.NO;
builder.weakReferenceField(defn.getInternalName(), store, index);
builder.weakReferenceField(defn.getInternalName(), store, index, defn.isFullTextSearchable());
} else {
// Everything else gets stored as a string ...
builder.stringField(defn.getInternalName(), store, index, canBeReference);
builder.stringField(defn.getInternalName(), store, index, canBeReference, defn.isFullTextSearchable());
}

}
Expand Down

0 comments on commit 237caaa

Please sign in to comment.