use of org.apache.jackrabbit.oak.query.fulltext.FullTextTerm in project jackrabbit-oak by apache.
the class IndexPlanner method canEvalAllFullText.
private boolean canEvalAllFullText(final IndexingRule indexingRule, FullTextExpression ft) {
if (ft == null) {
return false;
}
final HashSet<String> relPaths = new HashSet<String>();
final HashSet<String> nonIndexedPaths = new HashSet<String>();
final AtomicBoolean relativeParentsFound = new AtomicBoolean();
final AtomicBoolean nodeScopedCondition = new AtomicBoolean();
ft.accept(new FullTextVisitor.FullTextVisitorBase() {
@Override
public boolean visit(FullTextContains contains) {
visitTerm(contains.getPropertyName());
return true;
}
@Override
public boolean visit(FullTextTerm term) {
visitTerm(term.getPropertyName());
return true;
}
private void visitTerm(String propertyName) {
String p = propertyName;
String propertyPath = null;
String nodePath = null;
if (p == null) {
relPaths.add("");
} else if (p.startsWith("../") || p.startsWith("./")) {
relPaths.add(p);
relativeParentsFound.set(true);
} else if (getDepth(p) > 1) {
String parent = getParentPath(p);
if (LucenePropertyIndex.isNodePath(p)) {
nodePath = parent;
} else {
propertyPath = p;
}
relPaths.add(parent);
} else {
propertyPath = p;
relPaths.add("");
}
if (nodePath != null && !indexingRule.isAggregated(nodePath)) {
nonIndexedPaths.add(p);
} else if (propertyPath != null) {
PropertyDefinition pd = indexingRule.getConfig(propertyPath);
//not indexed
if (pd == null) {
nonIndexedPaths.add(p);
} else if (!pd.analyzed) {
nonIndexedPaths.add(p);
}
}
if (nodeScopedTerm(propertyName)) {
nodeScopedCondition.set(true);
}
}
});
if (nodeScopedCondition.get() && !indexingRule.isNodeFullTextIndexed()) {
return false;
}
if (relativeParentsFound.get()) {
log.debug("Relative parents found {} which are not supported", relPaths);
return false;
}
//have jcr:content as parent. So ensure that relPaths size is 1 or 0
if (!nonIndexedPaths.isEmpty()) {
if (relPaths.size() > 1) {
log.debug("Following relative property paths are not index", relPaths);
return false;
}
result.setParentPath(Iterables.getOnlyElement(relPaths, ""));
//Such non indexed path can possibly be evaluated via any rule on nt:base
//which can possibly index everything
IndexingRule rule = definition.getApplicableIndexingRule(NT_BASE);
if (rule == null) {
return false;
}
for (String p : nonIndexedPaths) {
//if it indexes node scope indexing is enabled
if (LucenePropertyIndex.isNodePath(p)) {
if (!rule.isNodeFullTextIndexed()) {
return false;
}
} else {
//Index can only evaluate a property like jcr:content/type
//if it indexes 'type' and that too analyzed
String propertyName = PathUtils.getName(p);
PropertyDefinition pd = rule.getConfig(propertyName);
if (pd == null) {
return false;
}
if (!pd.analyzed) {
return false;
}
}
}
} else {
result.setParentPath("");
}
return true;
}
use of org.apache.jackrabbit.oak.query.fulltext.FullTextTerm in project jackrabbit-oak by apache.
the class LuceneIndex method getFullTextQuery.
static Query getFullTextQuery(FullTextExpression ft, final Analyzer analyzer, final IndexReader reader) {
// a reference to the query, so it can be set in the visitor
// (a "non-local return")
final AtomicReference<Query> result = new AtomicReference<Query>();
ft.accept(new FullTextVisitor() {
@Override
public boolean visit(FullTextContains contains) {
return contains.getBase().accept(this);
}
@Override
public boolean visit(FullTextOr or) {
BooleanQuery q = new BooleanQuery();
for (FullTextExpression e : or.list) {
Query x = getFullTextQuery(e, analyzer, reader);
q.add(x, SHOULD);
}
result.set(q);
return true;
}
@Override
public boolean visit(FullTextAnd and) {
BooleanQuery q = new BooleanQuery();
for (FullTextExpression e : and.list) {
Query x = getFullTextQuery(e, analyzer, reader);
/* Only unwrap the clause if MUST_NOT(x) */
boolean hasMustNot = false;
if (x instanceof BooleanQuery) {
BooleanQuery bq = (BooleanQuery) x;
if ((bq.getClauses().length == 1) && (bq.getClauses()[0].getOccur() == BooleanClause.Occur.MUST_NOT)) {
hasMustNot = true;
q.add(bq.getClauses()[0]);
}
}
if (!hasMustNot) {
q.add(x, MUST);
}
}
result.set(q);
return true;
}
@Override
public boolean visit(FullTextTerm term) {
return visitTerm(term.getPropertyName(), term.getText(), term.getBoost(), term.isNot());
}
private boolean visitTerm(String propertyName, String text, String boost, boolean not) {
String p = propertyName;
if (p != null && p.indexOf('/') >= 0) {
p = getName(p);
}
Query q = tokenToQuery(text, p, analyzer, reader);
if (q == null) {
return false;
}
if (boost != null) {
q.setBoost(Float.parseFloat(boost));
}
if (not) {
BooleanQuery bq = new BooleanQuery();
bq.add(q, MUST_NOT);
result.set(bq);
} else {
result.set(q);
}
return true;
}
});
return result.get();
}
use of org.apache.jackrabbit.oak.query.fulltext.FullTextTerm in project jackrabbit-oak by apache.
the class LuceneIndexTest method customScoreQuery.
@Test
public void customScoreQuery() throws Exception {
NodeBuilder nb = newLuceneIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME), "lucene", of(TYPENAME_STRING));
TestUtil.useV2(nb);
nb.setProperty(LuceneIndexConstants.PROP_SCORER_PROVIDER, "testScorer");
NodeState before = builder.getNodeState();
builder.child("a").setProperty("jcr:createdBy", "bar bar");
builder.child("b").setProperty("jcr:createdBy", "foo bar");
NodeState after = builder.getNodeState();
NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);
tracker = new IndexTracker();
tracker.update(indexed);
SimpleScorerFactory factory = new SimpleScorerFactory();
ScorerProvider provider = new ScorerProvider() {
String scorerName = "testScorer";
@Override
public String getName() {
return scorerName;
}
@Override
public CustomScoreQuery createCustomScoreQuery(Query query) {
return new ModifiedCustomScoreQuery(query);
}
class ModifiedCustomScoreQuery extends CustomScoreQuery {
private Query query;
public ModifiedCustomScoreQuery(Query query) {
super(query);
this.query = query;
}
@Override
public CustomScoreProvider getCustomScoreProvider(AtomicReaderContext context) {
return new CustomScoreProvider(context) {
public float customScore(int doc, float subQueryScore, float valSrcScore) {
AtomicReader atomicReader = context.reader();
try {
Document document = atomicReader.document(doc);
// boosting docs created by foo
String fieldValue = document.get("full:jcr:createdBy");
if (fieldValue != null && fieldValue.contains("foo")) {
valSrcScore *= 2.0;
}
} catch (IOException e) {
return subQueryScore * valSrcScore;
}
return subQueryScore * valSrcScore;
}
};
}
}
};
factory.providers.put(provider.getName(), provider);
AdvancedQueryIndex queryIndex = new LucenePropertyIndex(tracker, factory);
FilterImpl filter = createFilter(NT_BASE);
filter.setFullTextConstraint(new FullTextTerm(null, "bar", false, false, null));
assertFilter(filter, queryIndex, indexed, asList("/b", "/a"), true);
}
use of org.apache.jackrabbit.oak.query.fulltext.FullTextTerm in project jackrabbit-oak by apache.
the class FilterQueryParser method parseFullTextExpression.
private static String parseFullTextExpression(FullTextExpression ft, final OakSolrConfiguration configuration) {
final StringBuilder fullTextString = new StringBuilder();
ft.accept(new FullTextVisitor() {
@Override
public boolean visit(FullTextOr or) {
fullTextString.append('(');
for (int i = 0; i < or.list.size(); i++) {
if (i > 0 && i < or.list.size()) {
fullTextString.append(" OR ");
}
FullTextExpression e = or.list.get(i);
String orTerm = parseFullTextExpression(e, configuration);
fullTextString.append(orTerm);
}
fullTextString.append(')');
fullTextString.append(' ');
return true;
}
@Override
public boolean visit(FullTextContains contains) {
return contains.getBase().accept(this);
}
@Override
public boolean visit(FullTextAnd and) {
fullTextString.append('(');
for (int i = 0; i < and.list.size(); i++) {
if (i > 0 && i < and.list.size()) {
fullTextString.append(" AND ");
}
FullTextExpression e = and.list.get(i);
String andTerm = parseFullTextExpression(e, configuration);
fullTextString.append(andTerm);
}
fullTextString.append(')');
fullTextString.append(' ');
return true;
}
@Override
public boolean visit(FullTextTerm term) {
if (term.isNot()) {
fullTextString.append('-');
}
String p = term.getPropertyName();
if (p != null && p.indexOf('/') >= 0) {
p = getName(p);
}
if (p == null || "*".equals(p)) {
p = configuration.getCatchAllField();
}
fullTextString.append(partialEscape(p));
fullTextString.append(':');
String termText = term.getText();
if (termText.indexOf(' ') > 0) {
fullTextString.append('"');
}
fullTextString.append(termText.replace("/", "\\/").replace(":", "\\:"));
if (termText.indexOf(' ') > 0) {
fullTextString.append('"');
}
String boost = term.getBoost();
if (boost != null) {
fullTextString.append('^');
fullTextString.append(boost);
}
fullTextString.append(' ');
return true;
}
});
return fullTextString.toString();
}
Aggregations