use of com.thinkaurelius.titan.graphdb.query.TitanPredicate in project titan by thinkaurelius.
the class LuceneIndex method convertQuery.
private final SearchParams convertQuery(Condition<?> condition, KeyInformation.StoreRetriever informations) {
SearchParams params = new SearchParams();
if (condition instanceof PredicateCondition) {
PredicateCondition<String, ?> atom = (PredicateCondition) condition;
Object value = atom.getValue();
String key = atom.getKey();
TitanPredicate titanPredicate = atom.getPredicate();
if (value instanceof Number) {
Preconditions.checkArgument(titanPredicate instanceof Cmp, "Relation not supported on numeric types: " + titanPredicate);
Preconditions.checkArgument(value instanceof Number);
params.addFilter(numericFilter(key, (Cmp) titanPredicate, (Number) value));
} else if (value instanceof String) {
Mapping map = Mapping.getMapping(informations.get(key));
if ((map == Mapping.DEFAULT || map == Mapping.TEXT) && !titanPredicate.toString().startsWith("CONTAINS"))
throw new IllegalArgumentException("Text mapped string values only support CONTAINS queries and not: " + titanPredicate);
if (map == Mapping.STRING && titanPredicate.toString().startsWith("CONTAINS"))
throw new IllegalArgumentException("String mapped string values do not support CONTAINS queries: " + titanPredicate);
if (titanPredicate == Text.CONTAINS) {
value = ((String) value).toLowerCase();
BooleanFilter b = new BooleanFilter();
for (String term : Text.tokenize((String) value)) {
b.add(new TermsFilter(new Term(key, term)), BooleanClause.Occur.MUST);
}
params.addFilter(b);
} else if (titanPredicate == Text.CONTAINS_PREFIX) {
value = ((String) value).toLowerCase();
params.addFilter(new PrefixFilter(new Term(key, (String) value)));
} else if (titanPredicate == Text.PREFIX) {
params.addFilter(new PrefixFilter(new Term(key, (String) value)));
} else if (titanPredicate == Text.REGEX) {
RegexpQuery rq = new RegexpQuery(new Term(key, (String) value));
params.addQuery(rq);
} else if (titanPredicate == Text.CONTAINS_REGEX) {
// This is terrible -- there is probably a better way
RegexpQuery rq = new RegexpQuery(new Term(key, ".*" + (value) + ".*"));
params.addQuery(rq);
} else if (titanPredicate == Cmp.EQUAL) {
params.addFilter(new TermsFilter(new Term(key, (String) value)));
} else if (titanPredicate == Cmp.NOT_EQUAL) {
BooleanFilter q = new BooleanFilter();
q.add(new TermsFilter(new Term(key, (String) value)), BooleanClause.Occur.MUST_NOT);
params.addFilter(q);
} else
throw new IllegalArgumentException("Relation is not supported for string value: " + titanPredicate);
} else if (value instanceof Geoshape) {
Preconditions.checkArgument(titanPredicate == Geo.WITHIN, "Relation is not supported for geo value: " + titanPredicate);
Shape shape = ((Geoshape) value).convert2Spatial4j();
SpatialArgs args = new SpatialArgs(SpatialOperation.IsWithin, shape);
params.addFilter(getSpatialStrategy(key).makeFilter(args));
} else if (value instanceof Date) {
Preconditions.checkArgument(titanPredicate instanceof Cmp, "Relation not supported on date types: " + titanPredicate);
params.addFilter(numericFilter(key, (Cmp) titanPredicate, ((Date) value).getTime()));
} else if (value instanceof Instant) {
Preconditions.checkArgument(titanPredicate instanceof Cmp, "Relation not supported on instant types: " + titanPredicate);
params.addFilter(numericFilter(key, (Cmp) titanPredicate, ((Instant) value).toEpochMilli()));
} else if (value instanceof Boolean) {
Preconditions.checkArgument(titanPredicate instanceof Cmp, "Relation not supported on boolean types: " + titanPredicate);
int intValue;
switch((Cmp) titanPredicate) {
case EQUAL:
intValue = ((Boolean) value) ? 1 : 0;
params.addFilter(NumericRangeFilter.newIntRange(key, intValue, intValue, true, true));
break;
case NOT_EQUAL:
intValue = ((Boolean) value) ? 0 : 1;
params.addFilter(NumericRangeFilter.newIntRange(key, intValue, intValue, true, true));
break;
default:
throw new IllegalArgumentException("Boolean types only support EQUAL or NOT_EQUAL");
}
} else if (value instanceof UUID) {
Preconditions.checkArgument(titanPredicate instanceof Cmp, "Relation not supported on UUID types: " + titanPredicate);
if (titanPredicate == Cmp.EQUAL) {
params.addFilter(new TermsFilter(new Term(key, value.toString())));
} else if (titanPredicate == Cmp.NOT_EQUAL) {
BooleanFilter q = new BooleanFilter();
q.add(new TermsFilter(new Term(key, value.toString())), BooleanClause.Occur.MUST_NOT);
params.addFilter(q);
} else {
throw new IllegalArgumentException("Relation is not supported for UUID type: " + titanPredicate);
}
} else {
throw new IllegalArgumentException("Unsupported type: " + value);
}
} else if (condition instanceof Not) {
SearchParams childParams = convertQuery(((Not) condition).getChild(), informations);
params.addParams(childParams, BooleanClause.Occur.MUST_NOT);
} else if (condition instanceof And) {
for (Condition c : condition.getChildren()) {
SearchParams childParams = convertQuery(c, informations);
params.addParams(childParams, BooleanClause.Occur.MUST);
}
} else if (condition instanceof Or) {
for (Condition c : condition.getChildren()) {
SearchParams childParams = convertQuery(c, informations);
params.addParams(childParams, BooleanClause.Occur.SHOULD);
}
} else
throw new IllegalArgumentException("Invalid condition: " + condition);
return params;
}
use of com.thinkaurelius.titan.graphdb.query.TitanPredicate in project titan by thinkaurelius.
the class SolrIndex method buildQueryFilter.
public String buildQueryFilter(Condition<TitanElement> condition, KeyInformation.StoreRetriever informations) {
if (condition instanceof PredicateCondition) {
PredicateCondition<String, TitanElement> atom = (PredicateCondition<String, TitanElement>) condition;
Object value = atom.getValue();
String key = atom.getKey();
TitanPredicate titanPredicate = atom.getPredicate();
if (value instanceof Number) {
String queryValue = escapeValue(value);
Preconditions.checkArgument(titanPredicate instanceof Cmp, "Relation not supported on numeric types: " + titanPredicate);
Cmp numRel = (Cmp) titanPredicate;
switch(numRel) {
case EQUAL:
return (key + ":" + queryValue);
case NOT_EQUAL:
return ("-" + key + ":" + queryValue);
case LESS_THAN:
//use right curly to mean up to but not including value
return (key + ":[* TO " + queryValue + "}");
case LESS_THAN_EQUAL:
return (key + ":[* TO " + queryValue + "]");
case GREATER_THAN:
//use left curly to mean greater than but not including value
return (key + ":{" + queryValue + " TO *]");
case GREATER_THAN_EQUAL:
return (key + ":[" + queryValue + " TO *]");
default:
throw new IllegalArgumentException("Unexpected relation: " + numRel);
}
} else if (value instanceof String) {
Mapping map = getStringMapping(informations.get(key));
assert map == Mapping.TEXT || map == Mapping.STRING;
if (map == Mapping.TEXT && !titanPredicate.toString().startsWith("CONTAINS"))
throw new IllegalArgumentException("Text mapped string values only support CONTAINS queries and not: " + titanPredicate);
if (map == Mapping.STRING && titanPredicate.toString().startsWith("CONTAINS"))
throw new IllegalArgumentException("String mapped string values do not support CONTAINS queries: " + titanPredicate);
//Special case
if (titanPredicate == Text.CONTAINS) {
//e.g. - if terms tomorrow and world were supplied, and fq=text:(tomorrow world)
//sample data set would return 2 documents: one where text = Tomorrow is the World,
//and the second where text = Hello World. Hence, we are decomposing the query string
//and building an AND query explicitly because we need AND semantics
value = ((String) value).toLowerCase();
List<String> terms = Text.tokenize((String) value);
if (terms.isEmpty()) {
return "";
} else if (terms.size() == 1) {
return (key + ":(" + escapeValue(terms.get(0)) + ")");
} else {
And<TitanElement> andTerms = new And<TitanElement>();
for (String term : terms) {
andTerms.add(new PredicateCondition<String, TitanElement>(key, titanPredicate, term));
}
return buildQueryFilter(andTerms, informations);
}
}
if (titanPredicate == Text.PREFIX || titanPredicate == Text.CONTAINS_PREFIX) {
return (key + ":" + escapeValue(value) + "*");
} else if (titanPredicate == Text.REGEX || titanPredicate == Text.CONTAINS_REGEX) {
return (key + ":/" + value + "/");
} else if (titanPredicate == Cmp.EQUAL) {
return (key + ":\"" + escapeValue(value) + "\"");
} else if (titanPredicate == Cmp.NOT_EQUAL) {
return ("-" + key + ":\"" + escapeValue(value) + "\"");
} else {
throw new IllegalArgumentException("Relation is not supported for string value: " + titanPredicate);
}
} else if (value instanceof Geoshape) {
Geoshape geo = (Geoshape) value;
if (geo.getType() == Geoshape.Type.CIRCLE) {
Geoshape.Point center = geo.getPoint();
return ("{!geofilt sfield=" + key + " pt=" + center.getLatitude() + "," + center.getLongitude() + " d=" + geo.getRadius() + //distance in kilometers
"} distErrPct=0");
} else if (geo.getType() == Geoshape.Type.BOX) {
Geoshape.Point southwest = geo.getPoint(0);
Geoshape.Point northeast = geo.getPoint(1);
return (key + ":[" + southwest.getLatitude() + "," + southwest.getLongitude() + " TO " + northeast.getLatitude() + "," + northeast.getLongitude() + "]");
} else if (geo.getType() == Geoshape.Type.POLYGON) {
List<Geoshape.Point> coordinates = getPolygonPoints(geo);
StringBuilder poly = new StringBuilder(key + ":\"IsWithin(POLYGON((");
for (Geoshape.Point coordinate : coordinates) {
poly.append(coordinate.getLongitude()).append(" ").append(coordinate.getLatitude()).append(", ");
}
//close the polygon with the first coordinate
poly.append(coordinates.get(0).getLongitude()).append(" ").append(coordinates.get(0).getLatitude());
poly.append(")))\" distErrPct=0");
return (poly.toString());
}
} else if (value instanceof Date || value instanceof Instant) {
String s = value.toString();
String queryValue = escapeValue(value instanceof Date ? toIsoDate((Date) value) : value.toString());
Preconditions.checkArgument(titanPredicate instanceof Cmp, "Relation not supported on date types: " + titanPredicate);
Cmp numRel = (Cmp) titanPredicate;
switch(numRel) {
case EQUAL:
return (key + ":" + queryValue);
case NOT_EQUAL:
return ("-" + key + ":" + queryValue);
case LESS_THAN:
//use right curly to mean up to but not including value
return (key + ":[* TO " + queryValue + "}");
case LESS_THAN_EQUAL:
return (key + ":[* TO " + queryValue + "]");
case GREATER_THAN:
//use left curly to mean greater than but not including value
return (key + ":{" + queryValue + " TO *]");
case GREATER_THAN_EQUAL:
return (key + ":[" + queryValue + " TO *]");
default:
throw new IllegalArgumentException("Unexpected relation: " + numRel);
}
} else if (value instanceof Boolean) {
Cmp numRel = (Cmp) titanPredicate;
String queryValue = escapeValue(value);
switch(numRel) {
case EQUAL:
return (key + ":" + queryValue);
case NOT_EQUAL:
return ("-" + key + ":" + queryValue);
default:
throw new IllegalArgumentException("Boolean types only support EQUAL or NOT_EQUAL");
}
} else if (value instanceof UUID) {
if (titanPredicate == Cmp.EQUAL) {
return (key + ":\"" + escapeValue(value) + "\"");
} else if (titanPredicate == Cmp.NOT_EQUAL) {
return ("-" + key + ":\"" + escapeValue(value) + "\"");
} else {
throw new IllegalArgumentException("Relation is not supported for uuid value: " + titanPredicate);
}
} else
throw new IllegalArgumentException("Unsupported type: " + value);
} else if (condition instanceof Not) {
String sub = buildQueryFilter(((Not) condition).getChild(), informations);
if (StringUtils.isNotBlank(sub))
return "-(" + sub + ")";
else
return "";
} else if (condition instanceof And) {
int numChildren = ((And) condition).size();
StringBuilder sb = new StringBuilder();
for (Condition<TitanElement> c : condition.getChildren()) {
String sub = buildQueryFilter(c, informations);
if (StringUtils.isBlank(sub))
continue;
// b. expression is a single statement in the AND.
if (!sub.startsWith("-") && numChildren > 1)
sb.append("+");
sb.append(sub).append(" ");
}
return sb.toString();
} else if (condition instanceof Or) {
StringBuilder sb = new StringBuilder();
int element = 0;
for (Condition<TitanElement> c : condition.getChildren()) {
String sub = buildQueryFilter(c, informations);
if (StringUtils.isBlank(sub))
continue;
if (element == 0)
sb.append("(");
else
sb.append(" OR ");
sb.append(sub);
element++;
}
if (element > 0)
sb.append(")");
return sb.toString();
} else {
throw new IllegalArgumentException("Invalid condition: " + condition);
}
return null;
}
use of com.thinkaurelius.titan.graphdb.query.TitanPredicate in project titan by thinkaurelius.
the class IndexProviderTest method storeTest.
private void storeTest(String... stores) throws Exception {
Multimap<String, Object> doc1 = getDocument("Hello world", 1001, 5.2, Geoshape.point(48.0, 0.0), Arrays.asList("1", "2", "3"), Sets.newHashSet("1", "2"), Instant.ofEpochSecond(1));
Multimap<String, Object> doc2 = getDocument("Tomorrow is the world", 1010, 8.5, Geoshape.point(49.0, 1.0), Arrays.asList("4", "5", "6"), Sets.newHashSet("4", "5"), Instant.ofEpochSecond(2));
Multimap<String, Object> doc3 = getDocument("Hello Bob, are you there?", -500, 10.1, Geoshape.point(47.0, 10.0), Arrays.asList("7", "8", "9"), Sets.newHashSet("7", "8"), Instant.ofEpochSecond(3));
for (String store : stores) {
initialize(store);
add(store, "doc1", doc1, true);
add(store, "doc2", doc2, true);
add(store, "doc3", doc3, false);
}
ImmutableList<IndexQuery.OrderEntry> orderTimeAsc = ImmutableList.of(new IndexQuery.OrderEntry(TIME, Order.ASC, Integer.class));
ImmutableList<IndexQuery.OrderEntry> orderWeightAsc = ImmutableList.of(new IndexQuery.OrderEntry(WEIGHT, Order.ASC, Double.class));
ImmutableList<IndexQuery.OrderEntry> orderTimeDesc = ImmutableList.of(new IndexQuery.OrderEntry(TIME, Order.DESC, Integer.class));
ImmutableList<IndexQuery.OrderEntry> orderWeightDesc = ImmutableList.of(new IndexQuery.OrderEntry(WEIGHT, Order.DESC, Double.class));
ImmutableList<IndexQuery.OrderEntry> jointOrder = ImmutableList.of(new IndexQuery.OrderEntry(WEIGHT, Order.DESC, Double.class), new IndexQuery.OrderEntry(TIME, Order.DESC, Integer.class));
clopen();
for (String store : stores) {
//Token
List<String> result = tx.query(new IndexQuery(store, PredicateCondition.of(TEXT, Text.CONTAINS, "world")));
assertEquals(ImmutableSet.of("doc1", "doc2"), ImmutableSet.copyOf(result));
assertEquals(ImmutableSet.copyOf(result), ImmutableSet.copyOf(tx.query(new IndexQuery(store, PredicateCondition.of(TEXT, Text.CONTAINS, "wOrLD")))));
assertEquals(1, tx.query(new IndexQuery(store, PredicateCondition.of(TEXT, Text.CONTAINS, "bob"))).size());
assertEquals(0, tx.query(new IndexQuery(store, PredicateCondition.of(TEXT, Text.CONTAINS, "worl"))).size());
assertEquals(1, tx.query(new IndexQuery(store, PredicateCondition.of(TEXT, Text.CONTAINS, "Tomorrow world"))).size());
assertEquals(1, tx.query(new IndexQuery(store, PredicateCondition.of(TEXT, Text.CONTAINS, "WorLD HELLO"))).size());
//Ordering
result = tx.query(new IndexQuery(store, PredicateCondition.of(TEXT, Text.CONTAINS, "world"), orderTimeDesc));
assertEquals(ImmutableList.of("doc2", "doc1"), result);
result = tx.query(new IndexQuery(store, PredicateCondition.of(TEXT, Text.CONTAINS, "world"), orderWeightDesc));
assertEquals(ImmutableList.of("doc2", "doc1"), result);
result = tx.query(new IndexQuery(store, PredicateCondition.of(TEXT, Text.CONTAINS, "world"), orderTimeAsc));
assertEquals(ImmutableList.of("doc1", "doc2"), result);
result = tx.query(new IndexQuery(store, PredicateCondition.of(TEXT, Text.CONTAINS, "world"), orderWeightAsc));
assertEquals(ImmutableList.of("doc1", "doc2"), result);
result = tx.query(new IndexQuery(store, PredicateCondition.of(TEXT, Text.CONTAINS, "world"), jointOrder));
assertEquals(ImmutableList.of("doc2", "doc1"), result);
result = tx.query(new IndexQuery(store, PredicateCondition.of(TEXT, Text.CONTAINS_PREFIX, "w")));
assertEquals(ImmutableSet.of("doc1", "doc2"), ImmutableSet.copyOf(result));
result = tx.query(new IndexQuery(store, PredicateCondition.of(TEXT, Text.CONTAINS_PREFIX, "wOr")));
assertEquals(ImmutableSet.of("doc1", "doc2"), ImmutableSet.copyOf(result));
assertEquals(0, tx.query(new IndexQuery(store, PredicateCondition.of(TEXT, Text.CONTAINS_PREFIX, "bobi"))).size());
if (index.supports(new StandardKeyInformation(String.class, Cardinality.SINGLE), Text.CONTAINS_REGEX)) {
result = tx.query(new IndexQuery(store, PredicateCondition.of(TEXT, Text.CONTAINS_REGEX, "he[l]+(.*)")));
assertEquals(ImmutableSet.of("doc1", "doc3"), ImmutableSet.copyOf(result));
result = tx.query(new IndexQuery(store, PredicateCondition.of(TEXT, Text.CONTAINS_REGEX, "[h]+e[l]+(.*)")));
assertEquals(ImmutableSet.of("doc1", "doc3"), ImmutableSet.copyOf(result));
result = tx.query(new IndexQuery(store, PredicateCondition.of(TEXT, Text.CONTAINS_REGEX, "he[l]+")));
assertTrue(result.isEmpty());
result = tx.query(new IndexQuery(store, PredicateCondition.of(TEXT, Text.CONTAINS_REGEX, "e[l]+(.*)")));
assertTrue(result.isEmpty());
}
for (TitanPredicate tp : new Text[] { Text.PREFIX, Text.REGEX }) {
try {
assertEquals(0, tx.query(new IndexQuery(store, PredicateCondition.of(TEXT, tp, "tzubull"))).size());
if (indexFeatures.supportsStringMapping(Mapping.TEXT))
fail();
} catch (IllegalArgumentException e) {
}
}
//String
assertEquals(1, tx.query(new IndexQuery(store, PredicateCondition.of(NAME, Cmp.EQUAL, "Tomorrow is the world"))).size());
assertEquals(0, tx.query(new IndexQuery(store, PredicateCondition.of(NAME, Cmp.EQUAL, "world"))).size());
assertEquals(3, tx.query(new IndexQuery(store, PredicateCondition.of(NAME, Cmp.NOT_EQUAL, "bob"))).size());
assertEquals(1, tx.query(new IndexQuery(store, PredicateCondition.of(NAME, Text.PREFIX, "Tomorrow"))).size());
assertEquals(0, tx.query(new IndexQuery(store, PredicateCondition.of(NAME, Text.PREFIX, "wor"))).size());
for (TitanPredicate tp : new Text[] { Text.CONTAINS, Text.CONTAINS_PREFIX, Text.CONTAINS_REGEX }) {
try {
assertEquals(0, tx.query(new IndexQuery(store, PredicateCondition.of(NAME, tp, "tzubull"))).size());
if (indexFeatures.supportsStringMapping(Mapping.STRING))
fail();
} catch (IllegalArgumentException e) {
}
}
if (index.supports(new StandardKeyInformation(String.class, Cardinality.SINGLE), Text.REGEX)) {
assertEquals(1, tx.query(new IndexQuery(store, PredicateCondition.of(NAME, Text.REGEX, "Tomo[r]+ow is.*world"))).size());
assertEquals(0, tx.query(new IndexQuery(store, PredicateCondition.of(NAME, Text.REGEX, "Tomorrow"))).size());
}
if (index.supports(new StandardKeyInformation(String.class, Cardinality.SINGLE, new Parameter("mapping", Mapping.STRING)), Text.REGEX)) {
assertEquals(1, tx.query(new IndexQuery(store, PredicateCondition.of(NAME, Text.REGEX, "Tomo[r]+ow is.*world"))).size());
assertEquals(0, tx.query(new IndexQuery(store, PredicateCondition.of(NAME, Text.REGEX, "Tomorrow"))).size());
}
result = tx.query(new IndexQuery(store, And.of(PredicateCondition.of(TEXT, Text.CONTAINS, "world"), PredicateCondition.of(TEXT, Text.CONTAINS, "hello"))));
assertEquals(1, result.size());
assertEquals("doc1", result.get(0));
result = tx.query(new IndexQuery(store, PredicateCondition.of(TIME, Cmp.EQUAL, -500)));
assertEquals(1, result.size());
assertEquals("doc3", result.get(0));
result = tx.query(new IndexQuery(store, And.of(Or.of(PredicateCondition.of(TIME, Cmp.EQUAL, 1001), PredicateCondition.of(TIME, Cmp.EQUAL, -500)))));
assertEquals(2, result.size());
result = tx.query(new IndexQuery(store, Not.of(PredicateCondition.of(TEXT, Text.CONTAINS, "world"))));
assertEquals(1, result.size());
assertEquals("doc3", result.get(0));
result = tx.query(new IndexQuery(store, And.of(PredicateCondition.of(TIME, Cmp.EQUAL, -500), Not.of(PredicateCondition.of(TEXT, Text.CONTAINS, "world")))));
assertEquals(1, result.size());
assertEquals("doc3", result.get(0));
result = tx.query(new IndexQuery(store, And.of(Or.of(PredicateCondition.of(TIME, Cmp.EQUAL, 1001), PredicateCondition.of(TIME, Cmp.EQUAL, -500)), PredicateCondition.of(TEXT, Text.CONTAINS, "world"))));
assertEquals(1, result.size());
assertEquals("doc1", result.get(0));
result = tx.query(new IndexQuery(store, PredicateCondition.of(TEXT, Text.CONTAINS, "Bob")));
assertEquals(1, result.size());
assertEquals("doc3", result.get(0));
result = tx.query(new IndexQuery(store, And.of(PredicateCondition.of(TEXT, Text.CONTAINS, "Bob"))));
assertEquals(1, result.size());
assertEquals("doc3", result.get(0));
result = tx.query(new IndexQuery(store, PredicateCondition.of(TEXT, Text.CONTAINS, "bob")));
assertEquals(1, result.size());
assertEquals("doc3", result.get(0));
result = tx.query(new IndexQuery(store, And.of(PredicateCondition.of(TEXT, Text.CONTAINS, "world"), PredicateCondition.of(WEIGHT, Cmp.GREATER_THAN, 6.0))));
assertEquals(1, result.size());
assertEquals("doc2", result.get(0));
result = tx.query(new IndexQuery(store, PredicateCondition.of(LOCATION, Geo.WITHIN, Geoshape.circle(48.5, 0.5, 200.00))));
assertEquals(2, result.size());
assertEquals(ImmutableSet.of("doc1", "doc2"), ImmutableSet.copyOf(result));
result = tx.query(new IndexQuery(store, And.of(PredicateCondition.of(TEXT, Text.CONTAINS, "tomorrow"), PredicateCondition.of(LOCATION, Geo.WITHIN, Geoshape.circle(48.5, 0.5, 200.00)))));
assertEquals(ImmutableSet.of("doc2"), ImmutableSet.copyOf(result));
result = tx.query(new IndexQuery(store, PredicateCondition.of("location", Geo.WITHIN, Geoshape.box(46.5, -0.5, 50.5, 10.5))));
assertEquals(3, result.size());
assertEquals(ImmutableSet.of("doc1", "doc2", "doc3"), ImmutableSet.copyOf(result));
result = tx.query(new IndexQuery(store, And.of(PredicateCondition.of(TIME, Cmp.GREATER_THAN_EQUAL, -1000), PredicateCondition.of(TIME, Cmp.LESS_THAN, 1010), PredicateCondition.of(LOCATION, Geo.WITHIN, Geoshape.circle(48.5, 0.5, 1000.00)))));
assertEquals(ImmutableSet.of("doc1", "doc3"), ImmutableSet.copyOf(result));
result = tx.query(new IndexQuery(store, And.of(PredicateCondition.of(WEIGHT, Cmp.GREATER_THAN, 10.0))));
assertEquals(ImmutableSet.of("doc3"), ImmutableSet.copyOf(result));
result = tx.query(new IndexQuery(store, And.of(PredicateCondition.of("blah", Cmp.GREATER_THAN, 10.0))));
assertEquals(0, result.size());
if (supportsLuceneStyleQueries()) {
assertEquals(1, Iterables.size(tx.query(new RawQuery(store, "text:\"Hello Bob\"", NO_PARAS))));
assertEquals(0, Iterables.size(tx.query(new RawQuery(store, "text:\"Hello Bob\"", NO_PARAS).setOffset(1))));
assertEquals(1, Iterables.size(tx.query(new RawQuery(store, "text:(world AND tomorrow)", NO_PARAS))));
// printResult(tx.query(new RawQuery(store,"text:(you there Hello Bob)",NO_PARAS)));
assertEquals(2, Iterables.size(tx.query(new RawQuery(store, "text:(you there Hello Bob)", NO_PARAS))));
assertEquals(1, Iterables.size(tx.query(new RawQuery(store, "text:(you there Hello Bob)", NO_PARAS).setLimit(1))));
assertEquals(1, Iterables.size(tx.query(new RawQuery(store, "text:(you there Hello Bob)", NO_PARAS).setLimit(1).setOffset(1))));
assertEquals(0, Iterables.size(tx.query(new RawQuery(store, "text:(you there Hello Bob)", NO_PARAS).setLimit(1).setOffset(2))));
assertEquals(2, Iterables.size(tx.query(new RawQuery(store, "text:\"world\"", NO_PARAS))));
assertEquals(2, Iterables.size(tx.query(new RawQuery(store, "time:[1000 TO 1020]", NO_PARAS))));
assertEquals(1, Iterables.size(tx.query(new RawQuery(store, "text:world AND time:1001", NO_PARAS))));
assertEquals(1, Iterables.size(tx.query(new RawQuery(store, "name:\"Hello world\"", NO_PARAS))));
}
if (index.supports(new StandardKeyInformation(String.class, Cardinality.LIST, new Parameter("mapping", Mapping.STRING)), Cmp.EQUAL)) {
assertEquals("doc1", tx.query(new IndexQuery(store, PredicateCondition.of(PHONE_LIST, Cmp.EQUAL, "1"))).get(0));
assertEquals("doc1", tx.query(new IndexQuery(store, PredicateCondition.of(PHONE_LIST, Cmp.EQUAL, "2"))).get(0));
assertEquals("doc2", tx.query(new IndexQuery(store, PredicateCondition.of(PHONE_LIST, Cmp.EQUAL, "4"))).get(0));
assertEquals("doc2", tx.query(new IndexQuery(store, PredicateCondition.of(PHONE_LIST, Cmp.EQUAL, "5"))).get(0));
assertEquals("doc3", tx.query(new IndexQuery(store, PredicateCondition.of(PHONE_LIST, Cmp.EQUAL, "7"))).get(0));
assertEquals("doc3", tx.query(new IndexQuery(store, PredicateCondition.of(PHONE_LIST, Cmp.EQUAL, "8"))).get(0));
assertEquals("doc1", tx.query(new IndexQuery(store, PredicateCondition.of(PHONE_SET, Cmp.EQUAL, "1"))).get(0));
assertEquals("doc1", tx.query(new IndexQuery(store, PredicateCondition.of(PHONE_SET, Cmp.EQUAL, "2"))).get(0));
assertEquals("doc2", tx.query(new IndexQuery(store, PredicateCondition.of(PHONE_SET, Cmp.EQUAL, "4"))).get(0));
assertEquals("doc2", tx.query(new IndexQuery(store, PredicateCondition.of(PHONE_SET, Cmp.EQUAL, "5"))).get(0));
assertEquals("doc3", tx.query(new IndexQuery(store, PredicateCondition.of(PHONE_SET, Cmp.EQUAL, "7"))).get(0));
assertEquals("doc3", tx.query(new IndexQuery(store, PredicateCondition.of(PHONE_SET, Cmp.EQUAL, "8"))).get(0));
}
assertEquals("doc1", tx.query(new IndexQuery(store, PredicateCondition.of(DATE, Cmp.EQUAL, Instant.ofEpochSecond(1)))).get(0));
assertEquals("doc2", tx.query(new IndexQuery(store, PredicateCondition.of(DATE, Cmp.EQUAL, Instant.ofEpochSecond(2)))).get(0));
assertEquals("doc3", tx.query(new IndexQuery(store, PredicateCondition.of(DATE, Cmp.EQUAL, Instant.ofEpochSecond(3)))).get(0));
assertEquals("doc3", tx.query(new IndexQuery(store, PredicateCondition.of(DATE, Cmp.GREATER_THAN, Instant.ofEpochSecond(2)))).get(0));
assertEquals(ImmutableSet.of("doc2", "doc3"), ImmutableSet.copyOf(tx.query(new IndexQuery(store, PredicateCondition.of(DATE, Cmp.GREATER_THAN_EQUAL, Instant.ofEpochSecond(2))))));
assertEquals(ImmutableSet.of("doc1"), ImmutableSet.copyOf(tx.query(new IndexQuery(store, PredicateCondition.of(DATE, Cmp.LESS_THAN, Instant.ofEpochSecond(2))))));
assertEquals(ImmutableSet.of("doc1", "doc2"), ImmutableSet.copyOf(tx.query(new IndexQuery(store, PredicateCondition.of(DATE, Cmp.LESS_THAN_EQUAL, Instant.ofEpochSecond(2))))));
assertEquals(ImmutableSet.of("doc1", "doc3"), ImmutableSet.copyOf(tx.query(new IndexQuery(store, PredicateCondition.of(DATE, Cmp.NOT_EQUAL, Instant.ofEpochSecond(2))))));
//Update some data
add(store, "doc4", getDocument("I'ts all a big Bob", -100, 11.2, Geoshape.point(48.0, 8.0), Arrays.asList("10", "11", "12"), Sets.newHashSet("10", "11"), Instant.ofEpochSecond(4)), true);
remove(store, "doc2", doc2, true);
remove(store, "doc3", ImmutableMultimap.of(WEIGHT, (Object) 10.1), false);
add(store, "doc3", ImmutableMultimap.of(TIME, (Object) 2000, TEXT, "Bob owns the world"), false);
remove(store, "doc1", ImmutableMultimap.of(TIME, (Object) 1001), false);
add(store, "doc1", ImmutableMultimap.of(TIME, (Object) 1005, WEIGHT, 11.1), false);
}
clopen();
for (String store : stores) {
List<String> result = tx.query(new IndexQuery(store, PredicateCondition.of(TEXT, Text.CONTAINS, "world")));
assertEquals(ImmutableSet.of("doc1", "doc3"), ImmutableSet.copyOf(result));
result = tx.query(new IndexQuery(store, And.of(PredicateCondition.of(TEXT, Text.CONTAINS, "world"), PredicateCondition.of(WEIGHT, Cmp.GREATER_THAN, 6.0))));
assertEquals(1, result.size());
assertEquals("doc1", result.get(0));
result = tx.query(new IndexQuery(store, PredicateCondition.of(LOCATION, Geo.WITHIN, Geoshape.circle(48.5, 0.5, 200.00))));
assertEquals(ImmutableSet.of("doc1"), ImmutableSet.copyOf(result));
result = tx.query(new IndexQuery(store, And.of(PredicateCondition.of(TEXT, Text.CONTAINS, "tomorrow"), PredicateCondition.of(LOCATION, Geo.WITHIN, Geoshape.circle(48.5, 0.5, 200.00)))));
assertEquals(ImmutableSet.of(), ImmutableSet.copyOf(result));
result = tx.query(new IndexQuery(store, And.of(PredicateCondition.of(TIME, Cmp.GREATER_THAN_EQUAL, -1000), PredicateCondition.of(TIME, Cmp.LESS_THAN, 1010), PredicateCondition.of(LOCATION, Geo.WITHIN, Geoshape.circle(48.5, 0.5, 1000.00)))));
assertEquals(ImmutableSet.of("doc1", "doc4"), ImmutableSet.copyOf(result));
result = tx.query(new IndexQuery(store, And.of(PredicateCondition.of(WEIGHT, Cmp.GREATER_THAN, 10.0))));
assertEquals(ImmutableSet.of("doc1", "doc4"), ImmutableSet.copyOf(result));
result = tx.query(new IndexQuery(store, And.of(PredicateCondition.of("blah", Cmp.GREATER_THAN, 10.0))));
assertEquals(0, result.size());
if (index.supports(new StandardKeyInformation(String.class, Cardinality.LIST, new Parameter("mapping", Mapping.STRING)), Cmp.EQUAL)) {
assertEquals("doc4", tx.query(new IndexQuery(store, PredicateCondition.of(PHONE_LIST, Cmp.EQUAL, "10"))).get(0));
assertEquals("doc4", tx.query(new IndexQuery(store, PredicateCondition.of(PHONE_LIST, Cmp.EQUAL, "11"))).get(0));
assertEquals("doc4", tx.query(new IndexQuery(store, PredicateCondition.of(PHONE_SET, Cmp.EQUAL, "10"))).get(0));
assertEquals("doc4", tx.query(new IndexQuery(store, PredicateCondition.of(PHONE_SET, Cmp.EQUAL, "11"))).get(0));
assertEquals(0, tx.query(new IndexQuery(store, PredicateCondition.of(PHONE_LIST, Cmp.EQUAL, "4"))).size());
assertEquals(0, tx.query(new IndexQuery(store, PredicateCondition.of(PHONE_LIST, Cmp.EQUAL, "5"))).size());
}
assertTrue(tx.query(new IndexQuery(store, PredicateCondition.of(DATE, Cmp.EQUAL, Instant.ofEpochSecond(2)))).isEmpty());
assertEquals("doc4", tx.query(new IndexQuery(store, PredicateCondition.of(DATE, Cmp.EQUAL, Instant.ofEpochSecond(4)))).get(0));
}
}
use of com.thinkaurelius.titan.graphdb.query.TitanPredicate in project titan by thinkaurelius.
the class ElasticSearchIndex method getFilter.
public FilterBuilder getFilter(Condition<?> condition, KeyInformation.StoreRetriever informations) {
if (condition instanceof PredicateCondition) {
PredicateCondition<String, ?> atom = (PredicateCondition) condition;
Object value = atom.getValue();
String key = atom.getKey();
TitanPredicate titanPredicate = atom.getPredicate();
if (value instanceof Number) {
Preconditions.checkArgument(titanPredicate instanceof Cmp, "Relation not supported on numeric types: " + titanPredicate);
Cmp numRel = (Cmp) titanPredicate;
Preconditions.checkArgument(value instanceof Number);
switch(numRel) {
case EQUAL:
return FilterBuilders.inFilter(key, value);
case NOT_EQUAL:
return FilterBuilders.notFilter(FilterBuilders.inFilter(key, value));
case LESS_THAN:
return FilterBuilders.rangeFilter(key).lt(value);
case LESS_THAN_EQUAL:
return FilterBuilders.rangeFilter(key).lte(value);
case GREATER_THAN:
return FilterBuilders.rangeFilter(key).gt(value);
case GREATER_THAN_EQUAL:
return FilterBuilders.rangeFilter(key).gte(value);
default:
throw new IllegalArgumentException("Unexpected relation: " + numRel);
}
} else if (value instanceof String) {
Mapping map = getStringMapping(informations.get(key));
String fieldName = key;
if (map == Mapping.TEXT && !titanPredicate.toString().startsWith("CONTAINS"))
throw new IllegalArgumentException("Text mapped string values only support CONTAINS queries and not: " + titanPredicate);
if (map == Mapping.STRING && titanPredicate.toString().startsWith("CONTAINS"))
throw new IllegalArgumentException("String mapped string values do not support CONTAINS queries: " + titanPredicate);
if (map == Mapping.TEXTSTRING && !titanPredicate.toString().startsWith("CONTAINS"))
fieldName = getDualMappingName(key);
if (titanPredicate == Text.CONTAINS) {
value = ((String) value).toLowerCase();
AndFilterBuilder b = FilterBuilders.andFilter();
for (String term : Text.tokenize((String) value)) {
b.add(FilterBuilders.termFilter(fieldName, term));
}
return b;
} else if (titanPredicate == Text.CONTAINS_PREFIX) {
value = ((String) value).toLowerCase();
return FilterBuilders.prefixFilter(fieldName, (String) value);
} else if (titanPredicate == Text.CONTAINS_REGEX) {
value = ((String) value).toLowerCase();
return FilterBuilders.regexpFilter(fieldName, (String) value);
} else if (titanPredicate == Text.PREFIX) {
return FilterBuilders.prefixFilter(fieldName, (String) value);
} else if (titanPredicate == Text.REGEX) {
return FilterBuilders.regexpFilter(fieldName, (String) value);
} else if (titanPredicate == Cmp.EQUAL) {
return FilterBuilders.termFilter(fieldName, (String) value);
} else if (titanPredicate == Cmp.NOT_EQUAL) {
return FilterBuilders.notFilter(FilterBuilders.termFilter(fieldName, (String) value));
} else
throw new IllegalArgumentException("Predicate is not supported for string value: " + titanPredicate);
} else if (value instanceof Geoshape) {
Preconditions.checkArgument(titanPredicate == Geo.WITHIN, "Relation is not supported for geo value: " + titanPredicate);
Geoshape shape = (Geoshape) value;
if (shape.getType() == Geoshape.Type.CIRCLE) {
Geoshape.Point center = shape.getPoint();
return FilterBuilders.geoDistanceFilter(key).lat(center.getLatitude()).lon(center.getLongitude()).distance(shape.getRadius(), DistanceUnit.KILOMETERS);
} else if (shape.getType() == Geoshape.Type.BOX) {
Geoshape.Point southwest = shape.getPoint(0);
Geoshape.Point northeast = shape.getPoint(1);
return FilterBuilders.geoBoundingBoxFilter(key).bottomRight(southwest.getLatitude(), northeast.getLongitude()).topLeft(northeast.getLatitude(), southwest.getLongitude());
} else
throw new IllegalArgumentException("Unsupported or invalid search shape type: " + shape.getType());
} else if (value instanceof Date || value instanceof Instant) {
Preconditions.checkArgument(titanPredicate instanceof Cmp, "Relation not supported on date types: " + titanPredicate);
Cmp numRel = (Cmp) titanPredicate;
switch(numRel) {
case EQUAL:
return FilterBuilders.inFilter(key, value);
case NOT_EQUAL:
return FilterBuilders.notFilter(FilterBuilders.inFilter(key, value));
case LESS_THAN:
return FilterBuilders.rangeFilter(key).lt(value);
case LESS_THAN_EQUAL:
return FilterBuilders.rangeFilter(key).lte(value);
case GREATER_THAN:
return FilterBuilders.rangeFilter(key).gt(value);
case GREATER_THAN_EQUAL:
return FilterBuilders.rangeFilter(key).gte(value);
default:
throw new IllegalArgumentException("Unexpected relation: " + numRel);
}
} else if (value instanceof Boolean) {
Cmp numRel = (Cmp) titanPredicate;
switch(numRel) {
case EQUAL:
return FilterBuilders.inFilter(key, value);
case NOT_EQUAL:
return FilterBuilders.notFilter(FilterBuilders.inFilter(key, value));
default:
throw new IllegalArgumentException("Boolean types only support EQUAL or NOT_EQUAL");
}
} else if (value instanceof UUID) {
if (titanPredicate == Cmp.EQUAL) {
return FilterBuilders.termFilter(key, value);
} else if (titanPredicate == Cmp.NOT_EQUAL) {
return FilterBuilders.notFilter(FilterBuilders.termFilter(key, value));
} else {
throw new IllegalArgumentException("Only equal or not equal is supported for UUIDs: " + titanPredicate);
}
} else
throw new IllegalArgumentException("Unsupported type: " + value);
} else if (condition instanceof Not) {
return FilterBuilders.notFilter(getFilter(((Not) condition).getChild(), informations));
} else if (condition instanceof And) {
AndFilterBuilder b = FilterBuilders.andFilter();
for (Condition c : condition.getChildren()) {
b.add(getFilter(c, informations));
}
return b;
} else if (condition instanceof Or) {
OrFilterBuilder b = FilterBuilders.orFilter();
for (Condition c : condition.getChildren()) {
b.add(getFilter(c, informations));
}
return b;
} else
throw new IllegalArgumentException("Invalid condition: " + condition);
}
use of com.thinkaurelius.titan.graphdb.query.TitanPredicate in project incubator-atlas by apache.
the class Solr5Index method buildQueryFilter.
public String buildQueryFilter(Condition<TitanElement> condition, KeyInformation.StoreRetriever informations) {
if (condition instanceof PredicateCondition) {
PredicateCondition<String, TitanElement> atom = (PredicateCondition<String, TitanElement>) condition;
Object value = atom.getValue();
String key = atom.getKey();
TitanPredicate titanPredicate = atom.getPredicate();
if (value instanceof Number) {
String queryValue = escapeValue(value);
Preconditions.checkArgument(titanPredicate instanceof Cmp, "Relation not supported on numeric types: " + titanPredicate);
Cmp numRel = (Cmp) titanPredicate;
switch(numRel) {
case EQUAL:
return (key + ":" + queryValue);
case NOT_EQUAL:
return ("-" + key + ":" + queryValue);
case LESS_THAN:
//use right curly to mean up to but not including value
return (key + ":[* TO " + queryValue + "}");
case LESS_THAN_EQUAL:
return (key + ":[* TO " + queryValue + "]");
case GREATER_THAN:
//use left curly to mean greater than but not including value
return (key + ":{" + queryValue + " TO *]");
case GREATER_THAN_EQUAL:
return (key + ":[" + queryValue + " TO *]");
default:
throw new IllegalArgumentException("Unexpected relation: " + numRel);
}
} else if (value instanceof String) {
Mapping map = getStringMapping(informations.get(key));
assert map == TEXT || map == STRING;
if (map == TEXT && !titanPredicate.toString().startsWith("CONTAINS"))
throw new IllegalArgumentException("Text mapped string values only support CONTAINS queries and not: " + titanPredicate);
if (map == STRING && titanPredicate.toString().startsWith("CONTAINS"))
throw new IllegalArgumentException("String mapped string values do not support CONTAINS queries: " + titanPredicate);
//Special case
if (titanPredicate == Text.CONTAINS) {
//e.g. - if terms tomorrow and world were supplied, and fq=text:(tomorrow world)
//sample data set would return 2 documents: one where text = Tomorrow is the World,
//and the second where text = Hello World. Hence, we are decomposing the query string
//and building an AND query explicitly because we need AND semantics
value = ((String) value).toLowerCase();
List<String> terms = Text.tokenize((String) value);
if (terms.isEmpty()) {
return "";
} else if (terms.size() == 1) {
return (key + ":(" + escapeValue(terms.get(0)) + ")");
} else {
And<TitanElement> andTerms = new And<>();
for (String term : terms) {
andTerms.add(new PredicateCondition<>(key, titanPredicate, term));
}
return buildQueryFilter(andTerms, informations);
}
}
if (titanPredicate == Text.PREFIX || titanPredicate == Text.CONTAINS_PREFIX) {
return (key + ":" + escapeValue(value) + "*");
} else if (titanPredicate == Text.REGEX || titanPredicate == Text.CONTAINS_REGEX) {
return (key + ":/" + value + "/");
} else if (titanPredicate == EQUAL) {
return (key + ":\"" + escapeValue(value) + "\"");
} else if (titanPredicate == NOT_EQUAL) {
return ("-" + key + ":\"" + escapeValue(value) + "\"");
} else {
throw new IllegalArgumentException("Relation is not supported for string value: " + titanPredicate);
}
} else if (value instanceof Geoshape) {
Geoshape geo = (Geoshape) value;
if (geo.getType() == Geoshape.Type.CIRCLE) {
Geoshape.Point center = geo.getPoint();
return ("{!geofilt sfield=" + key + " pt=" + center.getLatitude() + "," + center.getLongitude() + " d=" + geo.getRadius() + //distance in kilometers
"} distErrPct=0");
} else if (geo.getType() == Geoshape.Type.BOX) {
Geoshape.Point southwest = geo.getPoint(0);
Geoshape.Point northeast = geo.getPoint(1);
return (key + ":[" + southwest.getLatitude() + "," + southwest.getLongitude() + " TO " + northeast.getLatitude() + "," + northeast.getLongitude() + "]");
} else if (geo.getType() == Geoshape.Type.POLYGON) {
List<Geoshape.Point> coordinates = getPolygonPoints(geo);
StringBuilder poly = new StringBuilder(key + ":\"IsWithin(POLYGON((");
for (Geoshape.Point coordinate : coordinates) {
poly.append(coordinate.getLongitude()).append(" ").append(coordinate.getLatitude()).append(", ");
}
//close the polygon with the first coordinate
poly.append(coordinates.get(0).getLongitude()).append(" ").append(coordinates.get(0).getLatitude());
poly.append(")))\" distErrPct=0");
return (poly.toString());
}
} else if (value instanceof Date) {
String queryValue = escapeValue(toIsoDate((Date) value));
Preconditions.checkArgument(titanPredicate instanceof Cmp, "Relation not supported on date types: " + titanPredicate);
Cmp numRel = (Cmp) titanPredicate;
switch(numRel) {
case EQUAL:
return (key + ":" + queryValue);
case NOT_EQUAL:
return ("-" + key + ":" + queryValue);
case LESS_THAN:
//use right curly to mean up to but not including value
return (key + ":[* TO " + queryValue + "}");
case LESS_THAN_EQUAL:
return (key + ":[* TO " + queryValue + "]");
case GREATER_THAN:
//use left curly to mean greater than but not including value
return (key + ":{" + queryValue + " TO *]");
case GREATER_THAN_EQUAL:
return (key + ":[" + queryValue + " TO *]");
default:
throw new IllegalArgumentException("Unexpected relation: " + numRel);
}
} else if (value instanceof Boolean) {
Cmp numRel = (Cmp) titanPredicate;
String queryValue = escapeValue(value);
switch(numRel) {
case EQUAL:
return (key + ":" + queryValue);
case NOT_EQUAL:
return ("-" + key + ":" + queryValue);
default:
throw new IllegalArgumentException("Boolean types only support EQUAL or NOT_EQUAL");
}
} else if (value instanceof UUID) {
if (titanPredicate == EQUAL) {
return (key + ":\"" + escapeValue(value) + "\"");
} else if (titanPredicate == NOT_EQUAL) {
return ("-" + key + ":\"" + escapeValue(value) + "\"");
} else {
throw new IllegalArgumentException("Relation is not supported for uuid value: " + titanPredicate);
}
} else
throw new IllegalArgumentException("Unsupported type: " + value);
} else if (condition instanceof Not) {
String sub = buildQueryFilter(((Not) condition).getChild(), informations);
if (StringUtils.isNotBlank(sub))
return "-(" + sub + ")";
else
return "";
} else if (condition instanceof And) {
int numChildren = ((And) condition).size();
StringBuilder sb = new StringBuilder();
for (Condition<TitanElement> c : condition.getChildren()) {
String sub = buildQueryFilter(c, informations);
if (StringUtils.isBlank(sub))
continue;
// b. expression is a single statement in the AND.
if (!sub.startsWith("-") && numChildren > 1)
sb.append("+");
sb.append(sub).append(" ");
}
return sb.toString();
} else if (condition instanceof Or) {
StringBuilder sb = new StringBuilder();
int element = 0;
for (Condition<TitanElement> c : condition.getChildren()) {
String sub = buildQueryFilter(c, informations);
if (StringUtils.isBlank(sub))
continue;
if (element == 0)
sb.append("(");
else
sb.append(" OR ");
sb.append(sub);
element++;
}
if (element > 0)
sb.append(")");
return sb.toString();
} else {
throw new IllegalArgumentException("Invalid condition: " + condition);
}
return null;
}
Aggregations