};
}
if (constraint instanceof FullTextSearch) {
final TypeFactory<String> strings = context.getTypeSystem().getStringFactory();
final StaticOperand ftsExpression = ((FullTextSearch)constraint).getFullTextSearchExpression();
final FullTextSearch fts;
if (ftsExpression instanceof BindVariableName) {
Object searchExpression = literalValue(ftsExpression, context, strings);
if (searchExpression != null) {
fts = ((FullTextSearch)constraint).withFullTextExpression(searchExpression.toString());
} else {
fts = (FullTextSearch)constraint;
}
} else {
fts = (FullTextSearch)constraint;
}
final NodeCache cache = context.getNodeCache(sources.getWorkspaceName());
final BinaryStore binaries = context.getExecutionContext().getBinaryStore();
String selectorName = fts.getSelectorName();
String propertyName = fts.getPropertyName();
final int index = columns.getSelectorIndex(selectorName);
ExtractFromRow fullTextExtractor = null;
if (propertyName != null) {
// This is to search just the designated property of the node (name, all property values) ...
final ExtractFromRow propertyValueExtractor = createExtractFromRow(selectorName, propertyName, context, columns,
sources, strings, true);
fullTextExtractor = new ExtractFromRow() {
@Override
public TypeFactory<?> getType() {
return strings;
}
@Override
public Object getValueInRow( RowAccessor row ) {
Object result = propertyValueExtractor.getValueInRow(row);
if (result == null) return null;
StringBuilder fullTextString = new StringBuilder();
RowExtractors.extractFullTextFrom(result, strings, binaries, fullTextString);
return fullTextString.toString();
}
};
} else {
// This is to search all aspects of the node (name, all property values) ...
fullTextExtractor = RowExtractors.extractFullText(index, cache, context.getTypeSystem(), binaries);
}
// Return a filter that processes all of the text ...
final ExtractFromRow extractor = fullTextExtractor;
return new DynamicOperandFilter(extractor) {
@Override
protected boolean evaluate( Object leftHandValue ) {
/**
* The term will match the extracted value "as-is" via regex, without any stemming or punctuation removal.
* This means that the matching is done in a much more strict way than what Lucene did in 3.x If we were to
* implement stemming or hyphen removal, we would need to do it *both* in the row extractor
* (RowExtractors.extractFullText) and in the term where the regex is built
*/
return fts.getTerm().matches(leftHandValue.toString());
}
};
}
if (constraint instanceof Relike) {
Relike relike = (Relike)constraint;