Search in sources :

Example 11 with Direction

use of org.apache.tinkerpop.gremlin.structure.Direction in project janusgraph by JanusGraph.

the class RelationIdentifierUtils method findEdgeRelations.

public static Iterable<? extends JanusGraphRelation> findEdgeRelations(JanusGraphVertex v, RelationType type, RelationIdentifier rId, JanusGraphTransaction tx) {
    Direction dir = Direction.OUT;
    JanusGraphVertex other = ((StandardJanusGraphTx) tx).getInternalVertex(rId.getInVertexId());
    if (other == null || other.isRemoved())
        return null;
    if (((StandardJanusGraphTx) tx).isPartitionedVertex(v) && !((StandardJanusGraphTx) tx).isPartitionedVertex(other)) {
        // Swap for likely better performance
        JanusGraphVertex tmp = other;
        other = v;
        v = tmp;
        dir = Direction.IN;
    }
    VertexCentricQueryBuilder query = ((VertexCentricQueryBuilder) v.query()).noPartitionRestriction().types(type).direction(dir).adjacent(other);
    RelationType internalVertex = ((StandardJanusGraphTx) tx).getExistingRelationType(type.longId());
    if (((InternalRelationType) internalVertex).getConsistencyModifier() != ConsistencyModifier.FORK) {
        query.has(ImplicitKey.JANUSGRAPHID.name(), rId.getRelationId());
    }
    return query.edges();
}
Also used : JanusGraphVertex(org.janusgraph.core.JanusGraphVertex) StandardJanusGraphTx(org.janusgraph.graphdb.transaction.StandardJanusGraphTx) RelationType(org.janusgraph.core.RelationType) InternalRelationType(org.janusgraph.graphdb.internal.InternalRelationType) VertexCentricQueryBuilder(org.janusgraph.graphdb.query.vertex.VertexCentricQueryBuilder) Direction(org.apache.tinkerpop.gremlin.structure.Direction)

Example 12 with Direction

use of org.apache.tinkerpop.gremlin.structure.Direction in project janusgraph by JanusGraph.

the class RelationComparator method compare.

@Override
public int compare(final InternalRelation r1, final InternalRelation r2) {
    if (r1.equals(r2))
        return 0;
    // 1) Based on orders (if any)
    if (!orders.isEmpty()) {
        for (OrderList.OrderEntry order : orders) {
            int orderCompare = compareOnKey(r1, r2, order.getKey(), order.getOrder());
            if (orderCompare != 0)
                return orderCompare;
        }
    }
    // 2) RelationType (determine if property or edge - properties come first)
    int relationTypeCompare = (r1.isProperty() ? 1 : 2) - (r2.isProperty() ? 1 : 2);
    if (relationTypeCompare != 0)
        return relationTypeCompare;
    // 3) JanusGraphType
    InternalRelationType t1 = (InternalRelationType) r1.getType(), t2 = (InternalRelationType) r2.getType();
    int typeCompare = AbstractElement.compare(t1, t2);
    if (typeCompare != 0)
        return typeCompare;
    assert t1.equals(t2);
    // 4) Direction
    Direction dir1 = null, dir2 = null;
    for (int i = 0; i < r1.getLen(); i++) if (r1.getVertex(i).equals(vertex)) {
        dir1 = EdgeDirection.fromPosition(i);
        break;
    }
    for (int i = 0; i < r2.getLen(); i++) if (r2.getVertex(i).equals(vertex)) {
        dir2 = EdgeDirection.fromPosition(i);
        break;
    }
    // ("Either relation is not incident on vertex [%s]", vertex);
    assert dir1 != null && dir2 != null;
    int dirCompare = EdgeDirection.position(dir1) - EdgeDirection.position(dir2);
    if (dirCompare != 0)
        return dirCompare;
    // Breakout: If type&direction are the same and the type is unique in the direction it follows that the relations are the same
    if (t1.multiplicity().isUnique(dir1))
        return 0;
    // 5) Compare sort key values (this is empty and hence skipped if the type multiplicity is constrained)
    for (long typeId : t1.getSortKey()) {
        int keyCompare = compareOnKey(r1, r2, typeId, t1.getSortOrder());
        if (keyCompare != 0)
            return keyCompare;
    }
    // 6) Compare property objects or other vertices
    if (r1.isProperty()) {
        Object o1 = ((JanusGraphVertexProperty) r1).value();
        Object o2 = ((JanusGraphVertexProperty) r2).value();
        Preconditions.checkArgument(o1 != null && o2 != null);
        if (!o1.equals(o2)) {
            final int objectCompare;
            if (Comparable.class.isAssignableFrom(((PropertyKey) t1).dataType())) {
                objectCompare = ((Comparable) o1).compareTo(o2);
            } else {
                objectCompare = System.identityHashCode(o1) - System.identityHashCode(o2);
            }
            if (objectCompare != 0)
                return objectCompare;
        }
    } else {
        Preconditions.checkArgument(r1.isEdge() && r2.isEdge());
        int vertexCompare = AbstractElement.compare(r1.getVertex(EdgeDirection.position(dir1.opposite())), r2.getVertex(EdgeDirection.position(dir1.opposite())));
        if (vertexCompare != 0)
            return vertexCompare;
    }
    // Breakout: if type&direction are the same, and the end points of the relation are the same and the type is constrained, the relations must be the same
    if (t1.multiplicity().isConstrained())
        return 0;
    // 7)compare relation ids
    return AbstractElement.compare(r1, r2);
}
Also used : InternalRelationType(org.janusgraph.graphdb.internal.InternalRelationType) OrderList(org.janusgraph.graphdb.internal.OrderList) Direction(org.apache.tinkerpop.gremlin.structure.Direction) JanusGraphVertexProperty(org.janusgraph.core.JanusGraphVertexProperty)

Example 13 with Direction

use of org.apache.tinkerpop.gremlin.structure.Direction in project titan by thinkaurelius.

the class TitanGraphTest method testVertexCentricQuery.

/* ==================================================================================
                            VERTEX CENTRIC QUERIES
     ==================================================================================*/
@Test
@SuppressWarnings("deprecation")
public void testVertexCentricQuery() {
    makeVertexIndexedUniqueKey("name", String.class);
    PropertyKey time = makeKey("time", Integer.class);
    PropertyKey weight = makeKey("weight", Double.class);
    PropertyKey number = makeKey("number", Long.class);
    ((StandardEdgeLabelMaker) mgmt.makeEdgeLabel("connect")).sortKey(time).make();
    ((StandardEdgeLabelMaker) mgmt.makeEdgeLabel("connectDesc")).sortKey(time).sortOrder(Order.DESC).make();
    ((StandardEdgeLabelMaker) mgmt.makeEdgeLabel("friend")).sortKey(weight, time).sortOrder(Order.ASC).signature(number).make();
    ((StandardEdgeLabelMaker) mgmt.makeEdgeLabel("friendDesc")).sortKey(weight, time).sortOrder(Order.DESC).signature(number).make();
    ((StandardEdgeLabelMaker) mgmt.makeEdgeLabel("knows")).sortKey(number, weight).make();
    mgmt.makeEdgeLabel("follows").make();
    finishSchema();
    TitanVertex v = tx.addVertex("name", "v");
    TitanVertex u = tx.addVertex("name", "u");
    int noVertices = 10000;
    assertEquals(0, (noVertices - 1) % 3);
    TitanVertex[] vs = new TitanVertex[noVertices];
    for (int i = 1; i < noVertices; i++) {
        vs[i] = tx.addVertex("name", "v" + i);
    }
    EdgeLabel[] labelsV = { tx.getEdgeLabel("connect"), tx.getEdgeLabel("friend"), tx.getEdgeLabel("knows") };
    EdgeLabel[] labelsU = { tx.getEdgeLabel("connectDesc"), tx.getEdgeLabel("friendDesc"), tx.getEdgeLabel("knows") };
    for (int i = 1; i < noVertices; i++) {
        for (TitanVertex vertex : new TitanVertex[] { v, u }) {
            for (Direction d : new Direction[] { OUT, IN }) {
                EdgeLabel label = vertex == v ? labelsV[i % 3] : labelsU[i % 3];
                TitanEdge e = d == OUT ? vertex.addEdge(n(label), vs[i]) : vs[i].addEdge(n(label), vertex);
                e.property("time", i);
                e.property("weight", i % 4 + 0.5);
                e.property("name", "e" + i);
                e.property("number", i % 5);
            }
        }
    }
    int edgesPerLabel = noVertices / 3;
    VertexList vl;
    Map<TitanVertex, Iterable<TitanEdge>> results;
    Map<TitanVertex, Iterable<TitanVertexProperty>> results2;
    TitanVertex[] qvs;
    int lastTime;
    Iterator<? extends Edge> outer;
    clopen();
    long[] vidsubset = new long[31 - 3];
    for (int i = 0; i < vidsubset.length; i++) vidsubset[i] = vs[i + 3].longId();
    Arrays.sort(vidsubset);
    //##################################################
    //Queries from Cache
    //##################################################
    clopen();
    for (int i = 1; i < noVertices; i++) vs[i] = getV(tx, vs[i].longId());
    v = getV(tx, v.longId());
    u = getV(tx, u.longId());
    qvs = new TitanVertex[] { vs[6], vs[9], vs[12], vs[15], vs[60] };
    //To trigger queries from cache (don't copy!!!)
    assertCount(2 * (noVertices - 1), v.query().direction(Direction.BOTH).edges());
    assertEquals(1, v.query().propertyCount());
    assertEquals(10, size(v.query().labels("connect").limit(10).vertices()));
    assertEquals(10, size(u.query().labels("connectDesc").limit(10).vertices()));
    assertEquals(10, size(v.query().labels("connect").has("time", Cmp.GREATER_THAN, 30).limit(10).vertices()));
    assertEquals(10, size(u.query().labels("connectDesc").has("time", Cmp.GREATER_THAN, 30).limit(10).vertices()));
    lastTime = 0;
    for (TitanEdge e : (Iterable<TitanEdge>) v.query().labels("connect").direction(OUT).limit(20).edges()) {
        int nowTime = e.value("time");
        assertTrue(lastTime + " vs. " + nowTime, lastTime <= nowTime);
        lastTime = nowTime;
    }
    lastTime = Integer.MAX_VALUE;
    for (Edge e : (Iterable<TitanEdge>) u.query().labels("connectDesc").direction(OUT).limit(20).edges()) {
        int nowTime = e.value("time");
        assertTrue(lastTime + " vs. " + nowTime, lastTime >= nowTime);
        lastTime = nowTime;
    }
    assertEquals(10, size(v.query().labels("connect").direction(OUT).has("time", Cmp.GREATER_THAN, 60).limit(10).vertices()));
    assertEquals(10, size(u.query().labels("connectDesc").direction(OUT).has("time", Cmp.GREATER_THAN, 60).limit(10).vertices()));
    outer = v.query().labels("connect").direction(OUT).limit(20).edges().iterator();
    for (Edge e : (Iterable<TitanEdge>) v.query().labels("connect").direction(OUT).limit(10).edges()) {
        assertEquals(e, outer.next());
    }
    evaluateQuery(v.query().labels("connect").direction(OUT).interval("time", 3, 31), EDGE, 10, 1, new boolean[] { true, true });
    evaluateQuery(v.query().labels("connect").direction(OUT).has("time", 15).has("weight", 3.5), EDGE, 1, 1, new boolean[] { false, true });
    evaluateQuery(u.query().labels("connectDesc").direction(OUT).interval("time", 3, 31), EDGE, 10, 1, new boolean[] { true, true });
    assertEquals(10, v.query().labels("connect").direction(IN).interval("time", 3, 31).edgeCount());
    assertEquals(10, u.query().labels("connectDesc").direction(IN).interval("time", 3, 31).edgeCount());
    assertEquals(0, v.query().labels("connect").direction(OUT).has("time", null).edgeCount());
    assertEquals(10, v.query().labels("connect").direction(OUT).interval("time", 3, 31).vertexIds().size());
    assertEquals(edgesPerLabel - 10, v.query().labels("connect").direction(OUT).has("time", Cmp.GREATER_THAN, 31).count());
    assertEquals(10, size(v.query().labels("connect").direction(OUT).interval("time", 3, 31).vertices()));
    assertEquals(3, v.query().labels("friend").direction(OUT).limit(3).count());
    evaluateQuery(v.query().labels("friend").direction(OUT).has("weight", 0.5).limit(3), EDGE, 3, 1, new boolean[] { true, true });
    evaluateQuery(v.query().labels("friend").direction(OUT).interval("time", 3, 33).has("weight", 0.5), EDGE, 3, 1, new boolean[] { true, true });
    evaluateQuery(v.query().labels("friend").direction(OUT).interval("time", 3, 33).has("weight", Contain.IN, ImmutableList.of(0.5)), EDGE, 3, 1, new boolean[] { true, true });
    evaluateQuery(v.query().labels("friend").direction(OUT).has("weight", Contain.IN, ImmutableList.of(0.5, 1.5, 2.5)).interval("time", 3, 33), EDGE, 7, 3, new boolean[] { true, true });
    evaluateQuery(v.query().labels("friend").direction(OUT).has("weight", Contain.IN, ImmutableList.of(0.5, 1.5)), EDGE, 1667, 2, new boolean[] { true, true });
    assertEquals(3, u.query().labels("friendDesc").direction(OUT).interval("time", 3, 33).has("weight", 0.5).edgeCount());
    assertEquals(1, v.query().labels("friend").direction(OUT).has("weight", 0.5).interval("time", 4, 10).edgeCount());
    assertEquals(1, u.query().labels("friendDesc").direction(OUT).has("weight", 0.5).interval("time", 4, 10).edgeCount());
    assertEquals(3, v.query().labels("friend").direction(OUT).interval("time", 3, 33).has("weight", 0.5).edgeCount());
    assertEquals(4, v.query().labels("friend").direction(OUT).has("time", Cmp.LESS_THAN_EQUAL, 10).edgeCount());
    assertEquals(edgesPerLabel - 4, v.query().labels("friend").direction(OUT).has("time", Cmp.GREATER_THAN, 10).edgeCount());
    assertEquals(20, v.query().labels("friend", "connect").direction(OUT).interval("time", 3, 33).edgeCount());
    assertEquals((int) Math.ceil(edgesPerLabel / 5.0), v.query().labels("knows").direction(OUT).has("number", 0).edgeCount());
    assertEquals((int) Math.ceil(edgesPerLabel / 5.0), v.query().labels("knows").direction(OUT).has("number", 0).interval("weight", 0.0, 4.0).edgeCount());
    assertEquals((int) Math.ceil(edgesPerLabel / (5.0 * 2)), v.query().labels("knows").direction(OUT).has("number", 0).interval("weight", 0.0, 2.0).edgeCount());
    assertEquals((int) Math.floor(edgesPerLabel / (5.0 * 2)), v.query().labels("knows").direction(OUT).has("number", 0).interval("weight", 2.1, 4.0).edgeCount());
    assertEquals(20, size(v.query().labels("connect", "friend").direction(OUT).interval("time", 3, 33).vertices()));
    assertEquals(20, size(v.query().labels("connect", "friend").direction(OUT).interval("time", 3, 33).vertexIds()));
    assertEquals(30, v.query().labels("friend", "connect", "knows").direction(OUT).interval("time", 3, 33).edgeCount());
    assertEquals(noVertices - 2, v.query().labels("friend", "connect", "knows").direction(OUT).has("time", Cmp.NOT_EQUAL, 10).edgeCount());
    assertEquals(0, v.query().has("age", null).labels("undefined").direction(OUT).edgeCount());
    assertEquals(1, v.query().labels("connect").direction(OUT).adjacent(vs[6]).has("time", 6).edgeCount());
    assertEquals(1, v.query().labels("knows").direction(OUT).adjacent(vs[11]).edgeCount());
    assertEquals(1, v.query().labels("knows").direction(IN).adjacent(vs[11]).edgeCount());
    assertEquals(2, v.query().labels("knows").direction(BOTH).adjacent(vs[11]).edgeCount());
    assertEquals(1, v.query().labels("knows").direction(OUT).adjacent(vs[11]).has("weight", 3.5).edgeCount());
    assertEquals(2, v.query().labels("connect").adjacent(vs[6]).has("time", 6).edgeCount());
    assertEquals(0, v.query().labels("connect").adjacent(vs[8]).has("time", 8).edgeCount());
    assertEquals(edgesPerLabel, v.query().labels("connect").direction(OUT).edgeCount());
    assertEquals(edgesPerLabel, v.query().labels("connect").direction(IN).edgeCount());
    assertEquals(2 * edgesPerLabel, v.query().labels("connect").direction(BOTH).edgeCount());
    assertEquals(edgesPerLabel, v.query().labels("connect").has("undefined", null).direction(OUT).edgeCount());
    assertEquals(2 * (int) Math.ceil((noVertices - 1) / 4.0), size(v.query().labels("connect", "friend", "knows").has("weight", 1.5).vertexIds()));
    assertEquals(1, v.query().direction(IN).has("time", 1).edgeCount());
    assertEquals(10, v.query().direction(OUT).interval("time", 4, 14).edgeCount());
    assertEquals(9, v.query().direction(IN).interval("time", 4, 14).has("time", Cmp.NOT_EQUAL, 10).edgeCount());
    assertEquals(9, v.query().direction(OUT).interval("time", 4, 14).has("time", Cmp.NOT_EQUAL, 10).edgeCount());
    assertEquals(noVertices - 1, size(v.query().direction(OUT).vertices()));
    assertEquals(noVertices - 1, size(v.query().direction(IN).vertices()));
    for (Direction dir : new Direction[] { IN, OUT }) {
        vl = v.query().labels().direction(dir).interval("time", 3, 31).vertexIds();
        vl.sort();
        for (int i = 0; i < vl.size(); i++) assertEquals(vidsubset[i], vl.getID(i));
    }
    assertCount(2 * (noVertices - 1), v.query().direction(Direction.BOTH).edges());
    //Property queries
    assertEquals(1, size(v.query().properties()));
    assertEquals(1, size(v.query().keys("name").properties()));
    //MultiQueries
    results = tx.multiQuery(qvs).direction(IN).labels("connect").edges();
    for (Iterable<TitanEdge> result : results.values()) assertEquals(1, size(result));
    results = tx.multiQuery(Sets.newHashSet(qvs)).labels("connect").edges();
    for (Iterable<TitanEdge> result : results.values()) assertEquals(2, size(result));
    results = tx.multiQuery(qvs).labels("knows").edges();
    for (Iterable<TitanEdge> result : results.values()) assertEquals(0, size(result));
    results = tx.multiQuery(qvs).edges();
    for (Iterable<TitanEdge> result : results.values()) assertEquals(4, size(result));
    results2 = tx.multiQuery(qvs).properties();
    for (Iterable<TitanVertexProperty> result : results2.values()) assertEquals(1, size(result));
    results2 = tx.multiQuery(qvs).keys("name").properties();
    for (Iterable<TitanVertexProperty> result : results2.values()) assertEquals(1, size(result));
    //##################################################
    //Same queries as above but without memory loading (i.e. omitting the first query)
    //##################################################
    clopen();
    for (int i = 1; i < noVertices; i++) vs[i] = getV(tx, vs[i].longId());
    v = getV(tx, v.longId());
    u = getV(tx, u.longId());
    qvs = new TitanVertex[] { vs[6], vs[9], vs[12], vs[15], vs[60] };
    assertEquals(10, size(v.query().labels("connect").limit(10).vertices()));
    assertEquals(10, size(u.query().labels("connectDesc").limit(10).vertices()));
    assertEquals(10, size(v.query().labels("connect").has("time", Cmp.GREATER_THAN, 30).limit(10).vertices()));
    assertEquals(10, size(u.query().labels("connectDesc").has("time", Cmp.GREATER_THAN, 30).limit(10).vertices()));
    lastTime = 0;
    for (Edge e : (Iterable<TitanEdge>) v.query().labels("connect").direction(OUT).limit(20).edges()) {
        int nowTime = e.value("time");
        assertTrue(lastTime + " vs. " + nowTime, lastTime <= nowTime);
        lastTime = nowTime;
    }
    lastTime = Integer.MAX_VALUE;
    for (Edge e : (Iterable<TitanEdge>) u.query().labels("connectDesc").direction(OUT).limit(20).edges()) {
        int nowTime = e.value("time");
        assertTrue(lastTime + " vs. " + nowTime, lastTime >= nowTime);
        lastTime = nowTime;
    }
    assertEquals(10, size(v.query().labels("connect").direction(OUT).has("time", Cmp.GREATER_THAN, 60).limit(10).vertices()));
    assertEquals(10, size(u.query().labels("connectDesc").direction(OUT).has("time", Cmp.GREATER_THAN, 60).limit(10).vertices()));
    outer = v.query().labels("connect").direction(OUT).limit(20).edges().iterator();
    for (Edge e : (Iterable<TitanEdge>) v.query().labels("connect").direction(OUT).limit(10).edges()) {
        assertEquals(e, outer.next());
    }
    evaluateQuery(v.query().labels("connect").direction(OUT).interval("time", 3, 31), EDGE, 10, 1, new boolean[] { true, true });
    evaluateQuery(v.query().labels("connect").direction(OUT).has("time", 15).has("weight", 3.5), EDGE, 1, 1, new boolean[] { false, true });
    evaluateQuery(u.query().labels("connectDesc").direction(OUT).interval("time", 3, 31), EDGE, 10, 1, new boolean[] { true, true });
    assertEquals(10, v.query().labels("connect").direction(IN).interval("time", 3, 31).edgeCount());
    assertEquals(10, u.query().labels("connectDesc").direction(IN).interval("time", 3, 31).edgeCount());
    assertEquals(0, v.query().labels("connect").direction(OUT).has("time", null).edgeCount());
    assertEquals(10, v.query().labels("connect").direction(OUT).interval("time", 3, 31).vertexIds().size());
    assertEquals(edgesPerLabel - 10, v.query().labels("connect").direction(OUT).has("time", Cmp.GREATER_THAN, 31).count());
    assertEquals(10, size(v.query().labels("connect").direction(OUT).interval("time", 3, 31).vertices()));
    assertEquals(3, v.query().labels("friend").direction(OUT).limit(3).count());
    evaluateQuery(v.query().labels("friend").direction(OUT).has("weight", 0.5).limit(3), EDGE, 3, 1, new boolean[] { true, true });
    evaluateQuery(v.query().labels("friend").direction(OUT).interval("time", 3, 33).has("weight", 0.5), EDGE, 3, 1, new boolean[] { true, true });
    evaluateQuery(v.query().labels("friend").direction(OUT).interval("time", 3, 33).has("weight", Contain.IN, ImmutableList.of(0.5)), EDGE, 3, 1, new boolean[] { true, true });
    evaluateQuery(v.query().labels("friend").direction(OUT).has("weight", Contain.IN, ImmutableList.of(0.5, 1.5, 2.5)).interval("time", 3, 33), EDGE, 7, 3, new boolean[] { true, true });
    evaluateQuery(v.query().labels("friend").direction(OUT).has("weight", Contain.IN, ImmutableList.of(0.5, 1.5)), EDGE, 1667, 2, new boolean[] { true, true });
    assertEquals(3, u.query().labels("friendDesc").direction(OUT).interval("time", 3, 33).has("weight", 0.5).edgeCount());
    assertEquals(1, v.query().labels("friend").direction(OUT).has("weight", 0.5).interval("time", 4, 10).edgeCount());
    assertEquals(1, u.query().labels("friendDesc").direction(OUT).has("weight", 0.5).interval("time", 4, 10).edgeCount());
    assertEquals(3, v.query().labels("friend").direction(OUT).interval("time", 3, 33).has("weight", 0.5).edgeCount());
    assertEquals(4, v.query().labels("friend").direction(OUT).has("time", Cmp.LESS_THAN_EQUAL, 10).edgeCount());
    assertEquals(edgesPerLabel - 4, v.query().labels("friend").direction(OUT).has("time", Cmp.GREATER_THAN, 10).edgeCount());
    assertEquals(20, v.query().labels("friend", "connect").direction(OUT).interval("time", 3, 33).edgeCount());
    assertEquals((int) Math.ceil(edgesPerLabel / 5.0), v.query().labels("knows").direction(OUT).has("number", 0).edgeCount());
    assertEquals((int) Math.ceil(edgesPerLabel / 5.0), v.query().labels("knows").direction(OUT).has("number", 0).interval("weight", 0.0, 4.0).edgeCount());
    assertEquals((int) Math.ceil(edgesPerLabel / (5.0 * 2)), v.query().labels("knows").direction(OUT).has("number", 0).interval("weight", 0.0, 2.0).edgeCount());
    assertEquals((int) Math.floor(edgesPerLabel / (5.0 * 2)), v.query().labels("knows").direction(OUT).has("number", 0).interval("weight", 2.1, 4.0).edgeCount());
    assertEquals(20, size(v.query().labels("connect", "friend").direction(OUT).interval("time", 3, 33).vertices()));
    assertEquals(20, size(v.query().labels("connect", "friend").direction(OUT).interval("time", 3, 33).vertexIds()));
    assertEquals(30, v.query().labels("friend", "connect", "knows").direction(OUT).interval("time", 3, 33).edgeCount());
    assertEquals(noVertices - 2, v.query().labels("friend", "connect", "knows").direction(OUT).has("time", Cmp.NOT_EQUAL, 10).edgeCount());
    assertEquals(0, v.query().has("age", null).labels("undefined").direction(OUT).edgeCount());
    assertEquals(1, v.query().labels("connect").direction(OUT).adjacent(vs[6]).has("time", 6).edgeCount());
    assertEquals(1, v.query().labels("knows").direction(OUT).adjacent(vs[11]).edgeCount());
    assertEquals(1, v.query().labels("knows").direction(IN).adjacent(vs[11]).edgeCount());
    assertEquals(2, v.query().labels("knows").direction(BOTH).adjacent(vs[11]).edgeCount());
    assertEquals(1, v.query().labels("knows").direction(OUT).adjacent(vs[11]).has("weight", 3.5).edgeCount());
    assertEquals(2, v.query().labels("connect").adjacent(vs[6]).has("time", 6).edgeCount());
    assertEquals(0, v.query().labels("connect").adjacent(vs[8]).has("time", 8).edgeCount());
    assertEquals(edgesPerLabel, v.query().labels("connect").direction(OUT).edgeCount());
    assertEquals(edgesPerLabel, v.query().labels("connect").direction(IN).edgeCount());
    assertEquals(2 * edgesPerLabel, v.query().labels("connect").direction(BOTH).edgeCount());
    assertEquals(edgesPerLabel, v.query().labels("connect").has("undefined", null).direction(OUT).edgeCount());
    assertEquals(2 * (int) Math.ceil((noVertices - 1) / 4.0), size(v.query().labels("connect", "friend", "knows").has("weight", 1.5).vertexIds()));
    assertEquals(1, v.query().direction(IN).has("time", 1).edgeCount());
    assertEquals(10, v.query().direction(OUT).interval("time", 4, 14).edgeCount());
    assertEquals(9, v.query().direction(IN).interval("time", 4, 14).has("time", Cmp.NOT_EQUAL, 10).edgeCount());
    assertEquals(9, v.query().direction(OUT).interval("time", 4, 14).has("time", Cmp.NOT_EQUAL, 10).edgeCount());
    assertEquals(noVertices - 1, size(v.query().direction(OUT).vertices()));
    assertEquals(noVertices - 1, size(v.query().direction(IN).vertices()));
    for (Direction dir : new Direction[] { IN, OUT }) {
        vl = v.query().labels().direction(dir).interval("time", 3, 31).vertexIds();
        vl.sort();
        for (int i = 0; i < vl.size(); i++) assertEquals(vidsubset[i], vl.getID(i));
    }
    assertCount(2 * (noVertices - 1), v.query().direction(Direction.BOTH).edges());
    //Property queries
    assertEquals(1, size(v.query().properties()));
    assertEquals(1, size(v.query().keys("name").properties()));
    //MultiQueries
    results = tx.multiQuery(qvs).direction(IN).labels("connect").edges();
    for (Iterable<TitanEdge> result : results.values()) assertEquals(1, size(result));
    results = tx.multiQuery(Sets.newHashSet(qvs)).labels("connect").edges();
    for (Iterable<TitanEdge> result : results.values()) assertEquals(2, size(result));
    results = tx.multiQuery(qvs).labels("knows").edges();
    for (Iterable<TitanEdge> result : results.values()) assertEquals(0, size(result));
    results = tx.multiQuery(qvs).edges();
    for (Iterable<TitanEdge> result : results.values()) assertEquals(4, size(result));
    results2 = tx.multiQuery(qvs).properties();
    for (Iterable<TitanVertexProperty> result : results2.values()) assertEquals(1, size(result));
    results2 = tx.multiQuery(qvs).keys("name").properties();
    for (Iterable<TitanVertexProperty> result : results2.values()) assertEquals(1, size(result));
    //##################################################
    //End copied queries
    //##################################################
    newTx();
    v = getOnlyElement(tx.query().has("name", "v").vertices());
    assertNotNull(v);
    assertEquals(2, v.query().has("weight", 1.5).interval("time", 10, 30).limit(2).vertexIds().size());
    assertEquals(10, v.query().has("weight", 1.5).interval("time", 10, 30).vertexIds().size());
    newTx();
    v = getOnlyElement(tx.query().has("name", "v").vertices());
    assertNotNull(v);
    assertEquals(2, v.query().has("weight", 1.5).interval("time", 10, 30).limit(2).edgeCount());
    assertEquals(10, v.query().has("weight", 1.5).interval("time", 10, 30).edgeCount());
    newTx();
    //Test partially new vertex queries
    TitanVertex[] qvs2 = new TitanVertex[qvs.length + 2];
    qvs2[0] = tx.addVertex();
    for (int i = 0; i < qvs.length; i++) qvs2[i + 1] = getV(tx, qvs[i].longId());
    qvs2[qvs2.length - 1] = tx.addVertex();
    qvs2[0].addEdge("connect", qvs2[qvs2.length - 1]);
    qvs2[qvs2.length - 1].addEdge("connect", qvs2[0]);
    results = tx.multiQuery(qvs2).direction(IN).labels("connect").edges();
    for (Iterable<TitanEdge> result : results.values()) assertEquals(1, size(result));
}
Also used : TitanVertex(com.thinkaurelius.titan.core.TitanVertex) EdgeLabel(com.thinkaurelius.titan.core.EdgeLabel) Direction(org.apache.tinkerpop.gremlin.structure.Direction) TitanVertexProperty(com.thinkaurelius.titan.core.TitanVertexProperty) StandardEdgeLabelMaker(com.thinkaurelius.titan.graphdb.types.StandardEdgeLabelMaker) TitanEdge(com.thinkaurelius.titan.core.TitanEdge) Edge(org.apache.tinkerpop.gremlin.structure.Edge) PropertyKey(com.thinkaurelius.titan.core.PropertyKey) TitanEdge(com.thinkaurelius.titan.core.TitanEdge) VertexList(com.thinkaurelius.titan.core.VertexList) Test(org.junit.Test)

Example 14 with Direction

use of org.apache.tinkerpop.gremlin.structure.Direction in project titan by thinkaurelius.

the class BasicVertexCentricQueryBuilder method constructQueryWithoutProfile.

protected BaseVertexCentricQuery constructQueryWithoutProfile(RelationCategory returnType) {
    assert returnType != null;
    Preconditions.checkArgument(adjacentVertex == null || returnType == RelationCategory.EDGE, "Vertex constraints only apply to edges");
    if (limit <= 0)
        return BaseVertexCentricQuery.emptyQuery();
    //Prepare direction
    if (returnType == RelationCategory.PROPERTY) {
        if (dir == Direction.IN)
            return BaseVertexCentricQuery.emptyQuery();
        dir = Direction.OUT;
    }
    //Prepare order
    orders.makeImmutable();
    assert orders.hasCommonOrder();
    //Prepare constraints
    And<TitanRelation> conditions = QueryUtil.constraints2QNF(tx, constraints);
    if (conditions == null)
        return BaseVertexCentricQuery.emptyQuery();
    //Don't be smart with query limit adjustments - it just messes up the caching layer and penalizes when appropriate limits are set by the user!
    int sliceLimit = limit;
    //Construct (optimal) SliceQueries
    EdgeSerializer serializer = tx.getEdgeSerializer();
    List<BackendQueryHolder<SliceQuery>> queries;
    if (!hasTypes()) {
        BackendQueryHolder<SliceQuery> query = new BackendQueryHolder<SliceQuery>(serializer.getQuery(returnType, querySystem), ((dir == Direction.BOTH || (returnType == RelationCategory.PROPERTY && dir == Direction.OUT)) && !conditions.hasChildren()), orders.isEmpty());
        if (sliceLimit != Query.NO_LIMIT && sliceLimit < Integer.MAX_VALUE / 3) {
            //If only one direction is queried, ask for twice the limit from backend since approximately half will be filtered
            if (dir != Direction.BOTH && (returnType == RelationCategory.EDGE || returnType == RelationCategory.RELATION))
                sliceLimit *= 2;
        }
        query.getBackendQuery().setLimit(computeLimit(conditions.size(), sliceLimit));
        queries = ImmutableList.of(query);
        conditions.add(returnType);
        conditions.add(new //Need this to filter out newly created invisible relations in the transaction
        VisibilityFilterCondition<TitanRelation>(querySystem ? VisibilityFilterCondition.Visibility.SYSTEM : VisibilityFilterCondition.Visibility.NORMAL));
    } else {
        Set<RelationType> ts = new HashSet<RelationType>(types.length);
        queries = new ArrayList<BackendQueryHolder<SliceQuery>>(types.length + 2);
        Map<RelationType, Interval> intervalConstraints = new HashMap<RelationType, Interval>(conditions.size());
        final boolean isIntervalFittedConditions = compileConstraints(conditions, intervalConstraints);
        for (Interval pint : intervalConstraints.values()) {
            //Check if one of the constraints leads to an empty result set
            if (pint.isEmpty())
                return BaseVertexCentricQuery.emptyQuery();
        }
        for (String typeName : types) {
            InternalRelationType type = QueryUtil.getType(tx, typeName);
            if (type == null)
                continue;
            Preconditions.checkArgument(!querySystem || (type instanceof SystemRelationType), "Can only query for system types: %s", type);
            if (type instanceof ImplicitKey)
                throw new UnsupportedOperationException("Implicit types are not supported in complex queries: " + type);
            ts.add(type);
            Direction typeDir = dir;
            if (type.isPropertyKey()) {
                if (returnType == RelationCategory.EDGE)
                    throw new IllegalArgumentException("Querying for edges but including a property key: " + type.name());
                returnType = RelationCategory.PROPERTY;
                typeDir = Direction.OUT;
            }
            if (type.isEdgeLabel()) {
                if (returnType == RelationCategory.PROPERTY)
                    throw new IllegalArgumentException("Querying for properties but including an edge label: " + type.name());
                returnType = RelationCategory.EDGE;
                if (!type.isUnidirected(Direction.BOTH)) {
                    //Make sure unidirectionality lines up
                    if (typeDir == Direction.BOTH) {
                        if (type.isUnidirected(Direction.OUT))
                            typeDir = Direction.OUT;
                        else
                            typeDir = Direction.IN;
                    } else //Directions are incompatible
                    if (!type.isUnidirected(typeDir))
                        continue;
                }
            }
            if (type.isEdgeLabel() && typeDir == Direction.BOTH && intervalConstraints.isEmpty() && orders.isEmpty()) {
                //TODO: This if-condition is a little too restrictive - we also want to include those cases where there
                // ARE intervalConstraints or orders but those cannot be covered by any sort-keys
                SliceQuery q = serializer.getQuery(type, typeDir, null);
                q.setLimit(sliceLimit);
                queries.add(new BackendQueryHolder<SliceQuery>(q, isIntervalFittedConditions, true));
            } else {
                //Optimize for each direction independently
                Direction[] dirs = { typeDir };
                if (typeDir == Direction.BOTH) {
                    if (type.isEdgeLabel())
                        dirs = new Direction[] { Direction.OUT, Direction.IN };
                    else
                        //property key
                        dirs = new Direction[] { Direction.OUT };
                }
                for (Direction direction : dirs) {
                    /*
                        Find best scoring relation type to answer this query with. We score each candidate by the number
                        of conditions that each sort-keys satisfy. Equality conditions score higher than interval conditions
                        since they are more restrictive. We assign additional points if the sort key satisfies the order
                        of this query.
                        */
                    InternalRelationType bestCandidate = null;
                    double bestScore = Double.NEGATIVE_INFINITY;
                    boolean bestCandidateSupportsOrder = false;
                    for (InternalRelationType candidate : type.getRelationIndexes()) {
                        //Filter out those that don't apply
                        if (!candidate.isUnidirected(Direction.BOTH) && !candidate.isUnidirected(direction))
                            continue;
                        if (!candidate.equals(type) && candidate.getStatus() != SchemaStatus.ENABLED)
                            continue;
                        boolean supportsOrder = orders.isEmpty() ? true : orders.getCommonOrder() == candidate.getSortOrder();
                        int currentOrder = 0;
                        double score = 0.0;
                        PropertyKey[] extendedSortKey = getExtendedSortKey(candidate, direction, tx);
                        for (int i = 0; i < extendedSortKey.length; i++) {
                            PropertyKey keyType = extendedSortKey[i];
                            if (currentOrder < orders.size() && orders.getKey(currentOrder).equals(keyType))
                                currentOrder++;
                            Interval interval = intervalConstraints.get(keyType);
                            if (interval == null || !interval.isPoints()) {
                                if (interval != null)
                                    score += 1;
                                break;
                            } else {
                                assert interval.isPoints();
                                score += 5.0 / interval.getPoints().size();
                            }
                        }
                        if (supportsOrder && currentOrder == orders.size())
                            score += 3;
                        if (score > bestScore) {
                            bestScore = score;
                            bestCandidate = candidate;
                            bestCandidateSupportsOrder = supportsOrder && currentOrder == orders.size();
                        }
                    }
                    Preconditions.checkArgument(bestCandidate != null, "Current graph schema does not support the specified query constraints for type: %s", type.name());
                    //Construct sort key constraints for the best candidate and then serialize into a SliceQuery
                    //that is wrapped into a BackendQueryHolder
                    PropertyKey[] extendedSortKey = getExtendedSortKey(bestCandidate, direction, tx);
                    EdgeSerializer.TypedInterval[] sortKeyConstraints = new EdgeSerializer.TypedInterval[extendedSortKey.length];
                    constructSliceQueries(extendedSortKey, sortKeyConstraints, 0, bestCandidate, direction, intervalConstraints, sliceLimit, isIntervalFittedConditions, bestCandidateSupportsOrder, queries);
                }
            }
        }
        if (queries.isEmpty())
            return BaseVertexCentricQuery.emptyQuery();
        conditions.add(getTypeCondition(ts));
    }
    return new BaseVertexCentricQuery(QueryUtil.simplifyQNF(conditions), dir, queries, orders, limit);
}
Also used : Direction(org.apache.tinkerpop.gremlin.structure.Direction) SystemRelationType(com.thinkaurelius.titan.graphdb.types.system.SystemRelationType) EdgeSerializer(com.thinkaurelius.titan.graphdb.database.EdgeSerializer) ImplicitKey(com.thinkaurelius.titan.graphdb.types.system.ImplicitKey) SliceQuery(com.thinkaurelius.titan.diskstorage.keycolumnvalue.SliceQuery) SystemRelationType(com.thinkaurelius.titan.graphdb.types.system.SystemRelationType) Interval(com.thinkaurelius.titan.util.datastructures.Interval) PointInterval(com.thinkaurelius.titan.util.datastructures.PointInterval) RangeInterval(com.thinkaurelius.titan.util.datastructures.RangeInterval)

Example 15 with Direction

use of org.apache.tinkerpop.gremlin.structure.Direction in project titan by thinkaurelius.

the class RelationIdentifier method findRelation.

TitanRelation findRelation(TitanTransaction tx) {
    TitanVertex v = ((StandardTitanTx) tx).getInternalVertex(outVertexId);
    if (v == null || v.isRemoved())
        return null;
    TitanVertex typeVertex = tx.getVertex(typeId);
    if (typeVertex == null)
        return null;
    if (!(typeVertex instanceof RelationType))
        throw new IllegalArgumentException("Invalid RelationIdentifier: typeID does not reference a type");
    RelationType type = (RelationType) typeVertex;
    Iterable<? extends TitanRelation> rels;
    if (((RelationType) typeVertex).isEdgeLabel()) {
        Direction dir = Direction.OUT;
        TitanVertex other = ((StandardTitanTx) tx).getInternalVertex(inVertexId);
        if (other == null || other.isRemoved())
            return null;
        if (((StandardTitanTx) tx).isPartitionedVertex(v) && !((StandardTitanTx) tx).isPartitionedVertex(other)) {
            //Swap for likely better performance
            TitanVertex tmp = other;
            other = v;
            v = tmp;
            dir = Direction.IN;
        }
        rels = ((VertexCentricQueryBuilder) v.query()).noPartitionRestriction().types((EdgeLabel) type).direction(dir).adjacent(other).edges();
    } else {
        rels = ((VertexCentricQueryBuilder) v.query()).noPartitionRestriction().types((PropertyKey) type).properties();
    }
    for (TitanRelation r : rels) {
        //Find current or previous relation
        if (r.longId() == relationId || ((r instanceof StandardRelation) && ((StandardRelation) r).getPreviousID() == relationId))
            return r;
    }
    return null;
}
Also used : TitanVertex(com.thinkaurelius.titan.core.TitanVertex) RelationType(com.thinkaurelius.titan.core.RelationType) StandardTitanTx(com.thinkaurelius.titan.graphdb.transaction.StandardTitanTx) Direction(org.apache.tinkerpop.gremlin.structure.Direction) TitanRelation(com.thinkaurelius.titan.core.TitanRelation)

Aggregations

Direction (org.apache.tinkerpop.gremlin.structure.Direction)30 Edge (org.apache.tinkerpop.gremlin.structure.Edge)10 JanusGraphVertex (org.janusgraph.core.JanusGraphVertex)8 PropertyKey (org.janusgraph.core.PropertyKey)8 Vertex (org.apache.tinkerpop.gremlin.structure.Vertex)7 InternalRelationType (org.janusgraph.graphdb.internal.InternalRelationType)7 RelationType (org.janusgraph.core.RelationType)6 AtlasEdgeDirection (org.apache.atlas.repository.graphdb.AtlasEdgeDirection)5 Map (java.util.Map)4 AtlasEdge (org.apache.atlas.repository.graphdb.AtlasEdge)4 Traversal (org.apache.tinkerpop.gremlin.process.traversal.Traversal)4 JanusGraphVertexProperty (org.janusgraph.core.JanusGraphVertexProperty)4 StandardJanusGraphTx (org.janusgraph.graphdb.transaction.StandardJanusGraphTx)4 TitanVertex (com.thinkaurelius.titan.core.TitanVertex)3 ImplicitKey (com.thinkaurelius.titan.graphdb.types.system.ImplicitKey)3 HashMap (java.util.HashMap)3 P (org.apache.tinkerpop.gremlin.process.traversal.P)3 HasStep (org.apache.tinkerpop.gremlin.process.traversal.step.filter.HasStep)3 EdgeOtherVertexStep (org.apache.tinkerpop.gremlin.process.traversal.step.map.EdgeOtherVertexStep)3 EdgeVertexStep (org.apache.tinkerpop.gremlin.process.traversal.step.map.EdgeVertexStep)3