通过Java的OrientDB边缘索引

时间:2015-10-05 16:28:29

标签: orientdb tinkergraph

是否有办法使用Java API访问OrientDB中的边缘索引,以确定具有给定标签的边是否存在于两个已知顶点之间?

Afaik tinkergraph没有公开任何方法吗?

我相信Neo4j正在提供这样的API:

graphDatabaseService.index().forRelationships("HAS_USER").get(key, valueOrNull, startNodeOrNull, endNodeOrNull)

2 个答案:

答案 0 :(得分:2)

您可以从顶点调用getEdges()。例如:

v1.getEdges(v2, Direction.BOTH, "HAS_USER");

这是JavaDoc:

/**
   * (Blueprints Extension) Returns all the edges from the current Vertex to another one.
   *
   * @param iDestination
   *          The target vertex
   * @param iDirection
   *          The direction between OUT, IN or BOTH
   * @param iLabels
   *          Optional labels as Strings to consider
   * @return
   */
  public Iterable<Edge> getEdges(final OrientVertex iDestination, final Direction iDirection, final String... iLabels)

答案 1 :(得分:1)

另一种方法是使用OrientGraph.getEdges()

首先通过以下方式创建索引非常重要:

cmd.setText("create index edge.HAS_ITEM on E (out,in) unique");
g.command(cmd).execute();

或通过纯Java:

OrientEdgeType e = g.getEdgeType("E");
e.createProperty("in", OType.LINK);
e.createProperty("out", OType.LINK);
e.createIndex("edge.has_item", OClass.INDEX_TYPE.UNIQUE_HASH_INDEX, "out", "in");

在此之后,可以使用以下方法查询索引:

Iterable<Edge> edges = g.getEdges("edge.has_item", new OCompositeKey(root.getId(), randomDocument.getId()));

小pittfall:在getEdges方法中引用它时,小写索引类型很重要。否则orientdb将无法检索它。

下面列出了一个完整的示例,其中显示了在两个顶点之间找到特定边的四种方法。

在示例中,创建了14k顶点(项),它们连接到单个根节点。

Creating {14000} items.
[graph.getEdges] Duration: 38
[graph.getEdges] Duration per lookup: 0.0095

[root.getEdges] Duration: 59439
[root.getEdges] Duration per lookup: 14.85975

[root.getEdges - iterating] Duration: 56710
[root.getEdges - iterating] Duration per lookup: 14.1775

[query] Duration: 817
[query] Duration per lookup: 0.20425

示例:

package de.jotschi.orientdb;

import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.List;

import org.junit.BeforeClass;
import org.junit.Test;

import com.orientechnologies.orient.core.index.OCompositeKey;
import com.orientechnologies.orient.core.metadata.schema.OType;
import com.orientechnologies.orient.core.sql.OCommandSQL;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.orient.OrientEdgeType;
import com.tinkerpop.blueprints.impls.orient.OrientGraphFactory;
import com.tinkerpop.blueprints.impls.orient.OrientGraphNoTx;
import com.tinkerpop.blueprints.impls.orient.OrientVertex;
import com.tinkerpop.blueprints.impls.orient.OrientVertexType;

public class EdgeIndexPerformanceTest {

    private static OrientGraphFactory factory = new OrientGraphFactory("memory:tinkerpop");

    private final static int nDocuments = 14000;
    private final static int nChecks = 4000;

    private static List<OrientVertex> items;
    private static OrientVertex root;

    @BeforeClass
    public static void setupDatabase() {
        setupTypesAndIndices(factory);

        root = createRoot(factory);
        items = createData(root, factory, nDocuments);
    }

    private static void setupTypesAndIndices(OrientGraphFactory factory2) {
        OrientGraphNoTx g = factory.getNoTx();
        try {
            OCommandSQL cmd = new OCommandSQL();

            cmd.setText("alter database custom useLightweightEdges=false");
            g.command(cmd).execute();

            cmd.setText("alter database custom useVertexFieldsForEdgeLabels=false");
            g.command(cmd).execute();

            OrientEdgeType e = g.getEdgeType("E");
            e.createProperty("in", OType.LINK);
            e.createProperty("out", OType.LINK);

            OrientVertexType v = g.createVertexType("root", "V");
            v.createProperty("name", OType.STRING);

            v = g.createVertexType("item", "V");
            v.createProperty("name", OType.STRING);

            cmd.setText("create index edge.HAS_ITEM on E (out,in) unique");
            g.command(cmd).execute();

        } finally {
            g.shutdown();
        }

    }

    private static List<OrientVertex> createData(OrientVertex root, OrientGraphFactory factory, int count) {
        OrientGraphNoTx g = factory.getNoTx();
        try {
            System.out.println("Creating {" + count + "} items.");
            List<OrientVertex> items = new ArrayList<>();
            for (int i = 0; i < count; i++) {
                OrientVertex item = g.addVertex("class:item");
                item.setProperty("name", "item_" + i);
                items.add(item);
                root.addEdge("HAS_ITEM", item, "class:E");
            }
            return items;
        } finally {
            g.shutdown();
        }
    }

    private static OrientVertex createRoot(OrientGraphFactory factory) {
        OrientGraphNoTx g = factory.getNoTx();
        try {
            OrientVertex root = g.addVertex("class:root");
            root.setProperty("name", "root vertex");
            return root;
        } finally {
            g.shutdown();
        }
    }

    @Test
    public void testEdgeIndexViaRootGetEdgesWithoutTarget() throws Exception {
        OrientGraphNoTx g = factory.getNoTx();
        try {
            long start = System.currentTimeMillis();
            for (int i = 0; i < nChecks; i++) {
                OrientVertex randomDocument = items.get((int) (Math.random() * items.size()));
                Iterable<Edge> edges = root.getEdges(Direction.OUT, "HAS_ITEM");
                boolean found = false;
                for (Edge edge : edges) {
                    if (edge.getVertex(Direction.IN).equals(randomDocument)) {
                        found = true;
                        break;
                    }
                }
                assertTrue(found);
            }
            long dur = System.currentTimeMillis() - start;
            System.out.println("[root.getEdges - iterating] Duration: " + dur);
            System.out.println("[root.getEdges - iterating] Duration per lookup: " + ((double) dur / (double) nChecks));
        } finally {
            g.shutdown();
        }
    }

    @Test
    public void testEdgeIndexViaRootGetEdges() throws Exception {
        OrientGraphNoTx g = factory.getNoTx();
        try {
            long start = System.currentTimeMillis();
            for (int i = 0; i < nChecks; i++) {
                OrientVertex randomDocument = items.get((int) (Math.random() * items.size()));
                Iterable<Edge> edges = root.getEdges(randomDocument, Direction.OUT, "HAS_ITEM");
                assertTrue(edges.iterator().hasNext());
            }
            long dur = System.currentTimeMillis() - start;
            System.out.println("[root.getEdges] Duration: " + dur);
            System.out.println("[root.getEdges] Duration per lookup: " + ((double) dur / (double) nChecks));
        } finally {
            g.shutdown();
        }
    }

    @Test
    public void testEdgeIndexViaGraphGetEdges() throws Exception {
        OrientGraphNoTx g = factory.getNoTx();
        try {
            long start = System.currentTimeMillis();
            for (int i = 0; i < nChecks; i++) {
                OrientVertex randomDocument = items.get((int) (Math.random() * items.size()));
                Iterable<Edge> edges = g.getEdges("edge.has_item", new OCompositeKey(root.getId(), randomDocument.getId()));
                assertTrue(edges.iterator().hasNext());
            }
            long dur = System.currentTimeMillis() - start;
            System.out.println("[graph.getEdges] Duration: " + dur);
            System.out.println("[graph.getEdges] Duration per lookup: " + ((double) dur / (double) nChecks));
        } finally {
            g.shutdown();
        }
    }

    @Test
    public void testEdgeIndexViaQuery() throws Exception {
        OrientGraphNoTx g = factory.getNoTx();
        try {
            System.out.println("Checking edge");
            long start = System.currentTimeMillis();
            for (int i = 0; i < nChecks; i++) {
                OrientVertex randomDocument = items.get((int) (Math.random() * items.size()));

                OCommandSQL cmd = new OCommandSQL("select from index:edge.has_item where key=?");
                OCompositeKey key = new OCompositeKey(root.getId(), randomDocument.getId());

                assertTrue(((Iterable<Vertex>) g.command(cmd).execute(key)).iterator().hasNext());
            }
            long dur = System.currentTimeMillis() - start;
            System.out.println("[query] Duration: " + dur);
            System.out.println("[query] Duration per lookup: " + ((double) dur / (double) nChecks));
        } finally {
            g.shutdown();
        }
    }

}