private static final Map.Entry<Condition,Collection<Object>> getEqualityConditionValues(Condition<TitanElement> condition, RelationType type) { for (Condition c : condition.getChildren()) { if (c instanceof Or) { Map.Entry<RelationType,Collection> orEqual = QueryUtil.extractOrCondition((Or)c); if (orEqual!=null && orEqual.getKey().equals(type) && !orEqual.getValue().isEmpty()) { return new AbstractMap.SimpleImmutableEntry(c,orEqual.getValue()); } } else if (c instanceof PredicateCondition) { PredicateCondition<RelationType, TitanRelation> atom = (PredicateCondition)c; if (atom.getKey().equals(type) && atom.getPredicate()==Cmp.EQUAL && atom.getValue()!=null) { return new AbstractMap.SimpleImmutableEntry(c,ImmutableList.of(atom.getValue())); } } } return null; }
@Nullable @Override public Condition<TitanElement> apply(@Nullable Condition<TitanElement> condition) { Preconditions.checkArgument(condition instanceof PredicateCondition); PredicateCondition pc = (PredicateCondition) condition; PropertyKey key = (PropertyKey) pc.getKey(); return new PredicateCondition<String, TitanElement>(key2Field(index,key), pc.getPredicate(), pc.getValue()); } });
@Test public void largeTest() throws Exception { int numDoc = 30000; String store = "vertex"; initialize(store); for (int i = 1; i <= numDoc; i++) { add(store, "doc" + i, getRandomDocument(), true); } clopen(); // List<String> result = tx.query(new IndexQuery(store, And.of(PredicateCondition.of(WEIGHT, Cmp.INTERVAL, Interval.of(0.2,0.3))))); // List<String> result = tx.query(new IndexQuery(store, And.of(PredicateCondition.of(LOCATION, Geo.WITHIN,Geoshape.circle(48.5,0.5,1000.00))))); long time = System.currentTimeMillis(); List<String> result = tx.query(new IndexQuery(store, And.of(PredicateCondition.of(WEIGHT, Cmp.GREATER_THAN_EQUAL, 0.2), PredicateCondition.of(WEIGHT, Cmp.LESS_THAN, 0.6), PredicateCondition.of(LOCATION, Geo.WITHIN, Geoshape.circle(48.5, 0.5, 1000.00))))); int oldresultSize = result.size(); System.out.println(result.size() + " vs " + (numDoc / 1000 * 2.4622623015)); System.out.println("Query time on " + numDoc + " docs (ms): " + (System.currentTimeMillis() - time)); result = tx.query(new IndexQuery(store, And.of(PredicateCondition.of(WEIGHT, Cmp.GREATER_THAN_EQUAL, 0.2), PredicateCondition.of(WEIGHT, Cmp.LESS_THAN, 0.6), PredicateCondition.of(LOCATION, Geo.WITHIN, Geoshape.circle(48.5, 0.5, 1000.00))), numDoc / 1000)); assertEquals(numDoc / 1000, result.size()); result = tx.query(new IndexQuery(store, And.of(PredicateCondition.of(WEIGHT, Cmp.GREATER_THAN_EQUAL, 0.2), PredicateCondition.of(WEIGHT, Cmp.LESS_THAN, 0.6), PredicateCondition.of(LOCATION, Geo.WITHIN, Geoshape.circle(48.5, 0.5, 1000.00))), numDoc / 1000 * 100)); assertEquals(oldresultSize, result.size()); }
private PredicateCondition<PropertyKey, TitanElement> getEqualityCondition(Condition<TitanElement> condition) { if (condition instanceof PredicateCondition) { PredicateCondition<PropertyKey, TitanElement> pc = (PredicateCondition) condition; if (pc.getPredicate() == Cmp.EQUAL && TypeUtil.hasSimpleInternalVertexKeyIndex(pc.getKey())) return pc; } else if (condition instanceof And) { for (Condition<TitanElement> child : ((And<TitanElement>) condition).getChildren()) { PredicateCondition<PropertyKey, TitanElement> p = getEqualityCondition(child); if (p != null) return p; } } return null; }
private static final boolean isQNFLiteral(Condition<?> condition) { if (condition.getType() != Condition.Type.LITERAL) return false; if (condition instanceof PredicateCondition) { return ((PredicateCondition) condition).getPredicate().isQNF(); } else return true; }
public static <K, E extends TitanElement> PredicateCondition<K, E> of(K key, TitanPredicate titanPredicate, Object condition) { return new PredicateCondition<K, E>(key, titanPredicate, condition); }
@Override public boolean apply(@Nullable Condition<TitanElement> condition) { if (condition instanceof PredicateCondition) { RelationType type = ((PredicateCondition<RelationType,TitanElement>)condition).getKey(); Preconditions.checkArgument(type!=null && type.isPropertyKey()); Iterables.addAll(indexCandidates,Iterables.filter(((InternalRelationType) type).getKeyIndexes(), new Predicate<IndexType>() { @Override public boolean apply(@Nullable IndexType indexType) { return indexType.getElement()==resultType; } })); } return true; } });
@Override public int hashCode() { return new HashCodeBuilder().append(getType()).append(key).append(predicate).append(value).toHashCode(); }
@Override public boolean evaluate(E element) { RelationType type; if (key instanceof String) { type = ((InternalElement) element).tx().getRelationType((String) key); if (type == null) return satisfiesCondition(null); } else { type = (RelationType) key; } Preconditions.checkNotNull(type); if (type.isPropertyKey()) { Iterator<Object> iter = ElementHelper.getValues(element,(PropertyKey)type).iterator(); if (iter.hasNext()) { while (iter.hasNext()) { if (satisfiesCondition(iter.next())) return true; } return false; } return satisfiesCondition(null); } else { assert ((InternalRelationType)type).multiplicity().isUnique(Direction.OUT); return satisfiesCondition((TitanVertex)element.value(type.name())); } }
private PredicateCondition<PropertyKey, TitanElement> getEqualityCondition(Condition<TitanElement> condition) { if (condition instanceof PredicateCondition) { PredicateCondition<PropertyKey, TitanElement> pc = (PredicateCondition) condition; if (pc.getPredicate() == Cmp.EQUAL && TypeUtil.hasSimpleInternalVertexKeyIndex(pc.getKey())) return pc; } else if (condition instanceof And) { for (Condition<TitanElement> child : ((And<TitanElement>) condition).getChildren()) { PredicateCondition<PropertyKey, TitanElement> p = getEqualityCondition(child); if (p != null) return p; } } return null; }
private static final boolean isQNFLiteralOrNot(Condition<?> condition) { if (condition instanceof Not) { Condition child = ((Not) condition).getChild(); if (!isQNFLiteral(child)) return false; else if (child instanceof PredicateCondition) { return !((PredicateCondition) child).getPredicate().hasNegation(); } else return true; } else return isQNFLiteral(condition); }
@Override public GraphCentricQueryBuilder has(String key, TitanPredicate predicate, Object condition) { Preconditions.checkNotNull(key); Preconditions.checkNotNull(predicate); Preconditions.checkArgument(predicate.isValidCondition(condition), "Invalid condition: %s", condition); constraints.add(new PredicateCondition<String, TitanElement>(key, predicate, condition)); return this; }
@Override public boolean apply(@Nullable Condition<TitanElement> condition) { if (condition instanceof PredicateCondition) { RelationType type = ((PredicateCondition<RelationType,TitanElement>)condition).getKey(); Preconditions.checkArgument(type!=null && type.isPropertyKey()); Iterables.addAll(indexCandidates,Iterables.filter(((InternalRelationType) type).getKeyIndexes(), new Predicate<IndexType>() { @Override public boolean apply(@Nullable IndexType indexType) { return indexType.getElement()==resultType; } })); } return true; } });
@Override public int hashCode() { return new HashCodeBuilder().append(getType()).append(key).append(predicate).append(value).toHashCode(); }
@Override public boolean evaluate(E element) { RelationType type; if (key instanceof String) { type = ((InternalElement) element).tx().getRelationType((String) key); if (type == null) return satisfiesCondition(null); } else { type = (RelationType) key; } Preconditions.checkNotNull(type); if (type.isPropertyKey()) { Iterator<Object> iter = ElementHelper.getValues(element,(PropertyKey)type).iterator(); if (iter.hasNext()) { while (iter.hasNext()) { if (satisfiesCondition(iter.next())) return true; } return false; } return satisfiesCondition(null); } else { assert ((InternalRelationType)type).getMultiplicity().isUnique(Direction.OUT); return satisfiesCondition(((TitanRelation) element).getProperty((EdgeLabel) type)); } }
public static Map.Entry<RelationType,Collection> extractOrCondition(Or<TitanRelation> condition) { RelationType masterType = null; List<Object> values = new ArrayList<Object>(); for (Condition c : condition.getChildren()) { if (!(c instanceof PredicateCondition)) return null; PredicateCondition<RelationType, TitanRelation> atom = (PredicateCondition)c; if (atom.getPredicate()!=Cmp.EQUAL) return null; Object value = atom.getValue(); if (value==null) return null; RelationType type = atom.getKey(); if (masterType==null) masterType=type; else if (!masterType.equals(type)) return null; values.add(value); } if (masterType==null) return null; assert !values.isEmpty(); return new AbstractMap.SimpleImmutableEntry(masterType,values); }
@Nullable @Override public Condition<E> apply(@Nullable Condition<E> cond) { if (cond instanceof Not) { Condition<E> child = ((Not) cond).getChild(); Preconditions.checkArgument(child.getType() == Condition.Type.LITERAL); //verify QNF if (child instanceof PredicateCondition) { PredicateCondition<?, E> pc = (PredicateCondition) child; if (pc.getPredicate().hasNegation()) { return new PredicateCondition(pc.getKey(), pc.getPredicate().negate(), pc.getValue()); } } } return null; } });
private PredicateCondition<PropertyKey, TitanElement> getEqualityCondition(Condition<TitanElement> condition) { if (condition instanceof PredicateCondition) { PredicateCondition<PropertyKey, TitanElement> pc = (PredicateCondition) condition; if (pc.getPredicate() == Cmp.EQUAL && TypeUtil.hasSimpleInternalVertexKeyIndex(pc.getKey())) return pc; } else if (condition instanceof And) { for (Condition<TitanElement> child : ((And<TitanElement>) condition).getChildren()) { PredicateCondition<PropertyKey, TitanElement> p = getEqualityCondition(child); if (p != null) return p; } } return null; }