in oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java [1193:1355]
private static Query createQuery(String propertyName, PropertyRestriction pr,
PropertyDefinition defn) {
int propType = determinePropertyType(defn, pr);
if (pr.isNullRestriction()) {
return new TermQuery(new Term(FieldNames.NULL_PROPS, defn.name));
}
//If notNullCheckEnabled explicitly enabled use the simple TermQuery
//otherwise later fallback to range query
if (pr.isNotNullRestriction() && defn.notNullCheckEnabled) {
return new TermQuery(new Term(FieldNames.NOT_NULL_PROPS, defn.name));
}
switch (propType) {
case PropertyType.DATE: {
Long first = pr.first != null ? FieldFactory.dateToLong(pr.first.getValue(Type.DATE)) : null;
Long last = pr.last != null ? FieldFactory.dateToLong(pr.last.getValue(Type.DATE)) : null;
Long not = pr.not != null ? FieldFactory.dateToLong(pr.not.getValue(Type.DATE)) : null;
if (pr.first != null && pr.first.equals(pr.last) && pr.firstIncluding
&& pr.lastIncluding) {
// [property]=[value]
return NumericRangeQuery.newLongRange(propertyName, first, first, true, true);
} else if (pr.first != null && pr.last != null) {
return NumericRangeQuery.newLongRange(propertyName, first, last,
pr.firstIncluding, pr.lastIncluding);
} else if (pr.first != null && pr.last == null) {
// '>' & '>=' use cases
return NumericRangeQuery.newLongRange(propertyName, first, null, pr.firstIncluding, true);
} else if (pr.last != null && !pr.last.equals(pr.first)) {
// '<' & '<='
return NumericRangeQuery.newLongRange(propertyName, null, last, true, pr.lastIncluding);
} else if (pr.list != null) {
BooleanQuery in = new BooleanQuery();
for (PropertyValue value : pr.list) {
Long dateVal = FieldFactory.dateToLong(value.getValue(Type.DATE));
in.add(NumericRangeQuery.newLongRange(propertyName, dateVal, dateVal, true, true), BooleanClause.Occur.SHOULD);
}
return in;
} else if (pr.isNotNullRestriction()) {
// not null. As we are indexing generic dates which can be beyond epoch. So using complete numeric range
return NumericRangeQuery.newLongRange(propertyName, Long.MIN_VALUE, Long.MAX_VALUE, true, true);
} else if (pr.isNot && pr.not != null) {
// -[property]=[value]
BooleanQuery bool = new BooleanQuery();
// This will exclude entries with [property]=[value]
bool.add(NumericRangeQuery.newLongRange(propertyName, not, not, true, true), MUST_NOT);
return bool;
}
break;
}
case PropertyType.DOUBLE: {
Double first = pr.first != null ? pr.first.getValue(DOUBLE) : null;
Double last = pr.last != null ? pr.last.getValue(DOUBLE) : null;
if (pr.first != null && pr.first.equals(pr.last) && pr.firstIncluding
&& pr.lastIncluding) {
// [property]=[value]
return NumericRangeQuery.newDoubleRange(propertyName, first, first, true, true);
} else if (pr.first != null && pr.last != null) {
return NumericRangeQuery.newDoubleRange(propertyName, first, last,
pr.firstIncluding, pr.lastIncluding);
} else if (pr.first != null && pr.last == null) {
// '>' & '>=' use cases
return NumericRangeQuery.newDoubleRange(propertyName, first, null, pr.firstIncluding, true);
} else if (pr.last != null && !pr.last.equals(pr.first)) {
// '<' & '<='
return NumericRangeQuery.newDoubleRange(propertyName, null, last, true, pr.lastIncluding);
} else if (pr.list != null) {
BooleanQuery in = new BooleanQuery();
for (PropertyValue value : pr.list) {
Double doubleVal = value.getValue(DOUBLE);
in.add(NumericRangeQuery.newDoubleRange(propertyName, doubleVal, doubleVal, true, true), BooleanClause.Occur.SHOULD);
}
return in;
} else if (pr.isNotNullRestriction()) {
// not null.
return NumericRangeQuery.newDoubleRange(propertyName, Double.MIN_VALUE, Double.MAX_VALUE, true, true);
} else if (pr.isNot && pr.not != null) {
// -[property]=[value]
BooleanQuery bool = new BooleanQuery();
// This will exclude entries with [property]=[value]
bool.add(NumericRangeQuery.newDoubleRange(propertyName, pr.not.getValue(DOUBLE), pr.not.getValue(DOUBLE), true, true), MUST_NOT);
return bool;
}
break;
}
case PropertyType.LONG: {
Long first = pr.first != null ? pr.first.getValue(LONG) : null;
Long last = pr.last != null ? pr.last.getValue(LONG) : null;
if (pr.first != null && pr.first.equals(pr.last) && pr.firstIncluding
&& pr.lastIncluding) {
// [property]=[value]
return NumericRangeQuery.newLongRange(propertyName, first, first, true, true);
} else if (pr.first != null && pr.last != null) {
return NumericRangeQuery.newLongRange(propertyName, first, last,
pr.firstIncluding, pr.lastIncluding);
} else if (pr.first != null && pr.last == null) {
// '>' & '>=' use cases
return NumericRangeQuery.newLongRange(propertyName, first, null, pr.firstIncluding, true);
} else if (pr.last != null && !pr.last.equals(pr.first)) {
// '<' & '<='
return NumericRangeQuery.newLongRange(propertyName, null, last, true, pr.lastIncluding);
} else if (pr.list != null) {
BooleanQuery in = new BooleanQuery();
for (PropertyValue value : pr.list) {
Long longVal = value.getValue(LONG);
in.add(NumericRangeQuery.newLongRange(propertyName, longVal, longVal, true, true), BooleanClause.Occur.SHOULD);
}
return in;
} else if (pr.isNotNullRestriction()) {
// not null.
return NumericRangeQuery.newLongRange(propertyName, Long.MIN_VALUE, Long.MAX_VALUE, true, true);
} else if (pr.isNot && pr.not != null) {
// -[property]=[value]
BooleanQuery bool = new BooleanQuery();
// This will exclude entries with [property]=[value]
bool.add(NumericRangeQuery.newLongRange(propertyName, pr.not.getValue(LONG), pr.not.getValue(LONG), true, true), MUST_NOT);
return bool;
}
break;
}
default: {
if (pr.isLike) {
return createLikeQuery(propertyName, pr.first.getValue(STRING));
}
//TODO Confirm that all other types can be treated as string
String first = pr.first != null ? pr.first.getValue(STRING) : null;
String last = pr.last != null ? pr.last.getValue(STRING) : null;
if (pr.first != null && pr.first.equals(pr.last) && pr.firstIncluding
&& pr.lastIncluding) {
// [property]=[value]
return new TermQuery(new Term(propertyName, first));
} else if (pr.first != null && pr.last != null) {
return TermRangeQuery.newStringRange(propertyName, first, last,
pr.firstIncluding, pr.lastIncluding);
} else if (pr.first != null && pr.last == null) {
// '>' & '>=' use cases
return TermRangeQuery.newStringRange(propertyName, first, null, pr.firstIncluding, true);
} else if (pr.last != null && !pr.last.equals(pr.first)) {
// '<' & '<='
return TermRangeQuery.newStringRange(propertyName, null, last, true, pr.lastIncluding);
} else if (pr.list != null) {
BooleanQuery in = new BooleanQuery();
for (PropertyValue value : pr.list) {
String strVal = value.getValue(STRING);
in.add(new TermQuery(new Term(propertyName, strVal)), BooleanClause.Occur.SHOULD);
}
return in;
} else if (pr.isNotNullRestriction()) {
return new TermRangeQuery(propertyName, null, null, true, true);
} else if (pr.isNot && pr.not != null) {
// -[property]=[value]
BooleanQuery bool = new BooleanQuery();
// This will exclude entries with [property]=[value]
bool.add(new TermQuery(new Term(propertyName, pr.not.getValue(STRING))), MUST_NOT);
return bool;
}
}
}
throw new IllegalStateException("PropertyRestriction not handled " + pr + " for index " + defn);
}