use of org.apache.jackrabbit.oak.spi.query.fulltext.FullTextAnd in project jackrabbit-oak by apache.
the class AggregateIndex method flatten.
private Cursor flatten(FullTextExpression constraint, final AggregateIndexPlan plan, final Filter filter, final NodeState state, final String path) {
if (constraint == null) {
return null;
}
final AtomicReference<Cursor> result = new AtomicReference<Cursor>();
constraint.accept(new FullTextVisitor() {
@Override
public boolean visit(FullTextContains contains) {
return contains.getBase().accept(this);
}
@Override
public boolean visit(FullTextTerm term) {
IndexPlan p = plan.getPlan(path);
result.set(newAggregationCursor(p, state));
return true;
}
@Override
public boolean visit(FullTextAnd and) {
Iterator<FullTextExpression> iterator = and.list.iterator();
int index = 0;
Cursor c = flatten(iterator.next(), plan, filter, state, path + " and(" + index + ")");
while (iterator.hasNext()) {
index++;
FullTextExpression input = iterator.next();
Cursor newC = flatten(input, plan, filter, state, path + " and(" + index + ")");
c = Cursors.newIntersectionCursor(c, newC, filter.getQueryLimits());
}
result.set(c);
return true;
}
@Override
public boolean visit(FullTextOr or) {
final int[] index = new int[1];
List<Cursor> cursors = Lists.transform(or.list, new Function<FullTextExpression, Cursor>() {
@Override
public Cursor apply(FullTextExpression input) {
return flatten(input, plan, filter, state, path + " or(" + index[0]++ + ")");
}
});
result.set(Cursors.newConcatCursor(cursors, filter.getQueryLimits()));
return true;
}
});
return result.get();
}
use of org.apache.jackrabbit.oak.spi.query.fulltext.FullTextAnd in project jackrabbit-oak by apache.
the class LucenePropertyIndex method getFullTextQuery.
static Query getFullTextQuery(final IndexPlan plan, FullTextExpression ft, final Analyzer analyzer, final FulltextQueryTermsProvider augmentor) {
final PlanResult pr = getPlanResult(plan);
// 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) {
visitTerm(contains.getPropertyName(), contains.getRawText(), null, contains.isNot());
return true;
}
@Override
public boolean visit(FullTextOr or) {
BooleanQuery q = new BooleanQuery();
for (FullTextExpression e : or.list) {
Query x = getFullTextQuery(plan, e, analyzer, augmentor);
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(plan, e, analyzer, augmentor);
/* 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 = getLuceneFieldName(propertyName, pr);
Query q = tokenToQuery(text, p, pr, analyzer, augmentor);
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.spi.query.fulltext.FullTextAnd in project jackrabbit-oak by apache.
the class IndexPlannerTest method fullTextQuery_RelativePropertyPaths.
@Test
public void fullTextQuery_RelativePropertyPaths() throws Exception {
NodeBuilder defn = newLucenePropertyIndexDefinition(builder, "test", of("foo", "bar"), "async");
// Index all props and then perform fulltext
defn = IndexDefinition.updateDefinition(defn.getNodeState().builder());
NodeBuilder foob = getNode(defn, "indexRules/nt:base/properties/foo");
foob.setProperty(LuceneIndexConstants.PROP_NAME, "foo");
foob.setProperty(LuceneIndexConstants.PROP_ANALYZED, true);
NodeBuilder barb = getNode(defn, "indexRules/nt:base/properties/bar");
barb.setProperty(LuceneIndexConstants.PROP_NAME, "bar");
barb.setProperty(LuceneIndexConstants.PROP_ANALYZED, true);
// where contains('jcr:content/bar', 'mountain OR valley') and contains('jcr:content/foo', 'mountain OR valley')
// above query can be evaluated by index which indexes foo and bar with restriction that both belong to same node
// by displacing the query path to evaluate on contains('bar', ...) and filter out those parents which do not
// have jcr:content as parent
FullTextExpression fooExp = FullTextParser.parse("jcr:content/bar", "mountain OR valley");
FullTextExpression barExp = FullTextParser.parse("jcr:content/foo", "mountain OR valley");
FullTextExpression exp = new FullTextAnd(Arrays.asList(fooExp, barExp));
IndexPlanner planner = createPlannerForFulltext(defn.getNodeState(), exp);
// No plan for unindex property
assertNotNull(planner.getPlan());
}
use of org.apache.jackrabbit.oak.spi.query.fulltext.FullTextAnd in project jackrabbit-oak by apache.
the class IndexPlannerTest method fullTextQuery_DisjointPropertyPaths.
@Test
public void fullTextQuery_DisjointPropertyPaths() throws Exception {
NodeBuilder defn = newLucenePropertyIndexDefinition(builder, "test", of("foo", "bar"), "async");
// Index all props and then perform fulltext
defn = IndexDefinition.updateDefinition(defn.getNodeState().builder());
NodeBuilder foob = getNode(defn, "indexRules/nt:base/properties/foo");
foob.setProperty(LuceneIndexConstants.PROP_NAME, "foo");
foob.setProperty(LuceneIndexConstants.PROP_ANALYZED, true);
NodeBuilder barb = getNode(defn, "indexRules/nt:base/properties/bar");
barb.setProperty(LuceneIndexConstants.PROP_NAME, "bar");
barb.setProperty(LuceneIndexConstants.PROP_ANALYZED, true);
FullTextExpression fooExp = FullTextParser.parse("metadata/bar", "mountain OR valley");
FullTextExpression barExp = FullTextParser.parse("jcr:content/foo", "mountain OR valley");
FullTextExpression exp = new FullTextAnd(Arrays.asList(fooExp, barExp));
IndexPlanner planner = createPlannerForFulltext(defn.getNodeState(), exp);
// No plan for unindex property
assertNull(planner.getPlan());
}
use of org.apache.jackrabbit.oak.spi.query.fulltext.FullTextAnd 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++) {
FullTextExpression e = or.list.get(i);
if (e.toString().contains("\"OR\"")) {
continue;
}
if (i > 0 && i < or.list.size()) {
fullTextString.append(" OR ");
}
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++) {
FullTextExpression e = and.list.get(i);
if (e.toString().contains("\"AND\"")) {
continue;
}
if (i > 0 && i < and.list.size()) {
fullTextString.append(" AND ");
}
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