eu.mondo.driver.mongo.MongoGraphDriver.java Source code

Java tutorial

Introduction

Here is the source code for eu.mondo.driver.mongo.MongoGraphDriver.java

Source

/*******************************************************************************
 * Copyright (c) 2010-2014, Daniel Stein, Gabor Szarnyas, Istvan Rath and Daniel Varro
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Gabor Szarnyas - initial API and implementation for 4store
 *   Daniel Stein - implementation for Mongo
 *******************************************************************************/

package eu.mondo.driver.mongo;

import java.io.IOException;
import java.math.BigInteger;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.bson.types.ObjectId;
import org.jongo.MongoCursor;
import org.openrdf.query.parser.sparql.ast.ParseException;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import com.mongodb.WriteResult;

import eu.mondo.driver.mongo.util.MStatement;
import eu.mondo.driver.mongo.util.Node;

/**
 * 
 * @author Dniel Stein
 * @author Gbor Szrnyas
 * 
 */
public class MongoGraphDriver extends MongoGraphClient implements GraphDriver {

    protected static final String RDF_PREFIX = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";

    public MongoGraphDriver(String connectionString) throws UnknownHostException, ParseException {
        super(connectionString);
    }

    protected String saveNode(String URI) {
        return nodes.findAndModify("{ \"URI\": # }", URI).with("{ $set: { \"URI\": # } }", URI)
                .sort("{ \"URI\": 1 }").upsert().returnNew().as(Node.class).get_id();
    }

    protected BigInteger saveNodeBI(String URI) {
        return nodes.findAndModify("{ \"URI\": # }", URI).with("{ $set: { \"URI\": # } }", URI)
                .sort("{ \"URI\": 1 }").upsert().returnNew().as(Node.class).get_id_bigint();
    }

    // ================================================================================================================
    //
    // ___________________________________________________________________________________________________________ CRUD
    //
    // ================================================================================================================

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [ C ]

    /*
     * (non-Javadoc)
     * 
     * @see hu.bme.mit.bigmodel.mongo.GraphDriver#insertVertex(java.lang.String, java.lang.String)
     */
    @Override
    public void insertVertex(final String vertexType, final String vertexURI) throws IOException {
        String rdfType = RDF_PREFIX + "type";

        WriteResult insert = collection.insert(
                "{ \"subject\": #, \"predicate\": #, \"object\": #, \"subjectBI\": #, \"predicateBI\": #, \"objectBI\": # }",
                vertexURI, rdfType, vertexType, saveNode(vertexURI), saveNode(rdfType), saveNode(vertexType));

        if (isShowCommandOutput()) {
            System.out.println("INSERTED vertex " + vertexURI + " type: " + vertexType + " with " + insert.getN()
                    + " modifications.");
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see hu.bme.mit.bigmodel.mongo.GraphDriver#insertEdge(java.lang.String, java.lang.String, java.lang.String)
     */
    @Override
    public void insertEdge(final String sourceVertexURI, final String destinationVertexURI, final String edgeURI)
            throws IOException {
        WriteResult insert = collection.insert(
                "{ \"subject\": #, \"predicate\": #, \"object\": #, \"subjectBI\": #, \"predicateBI\": #, \"objectBI\": # }",
                sourceVertexURI, edgeURI, destinationVertexURI, saveNode(sourceVertexURI), saveNode(edgeURI),
                saveNode(destinationVertexURI));

        if (isShowCommandOutput()) {
            System.out.println("INSERTED edge between " + sourceVertexURI + " and " + destinationVertexURI
                    + ", type: " + edgeURI + " with " + insert.getN() + " modifications.");
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see hu.bme.mit.bigmodel.mongo.GraphDriver#insertEdges(com.google.common.collect.Multimap, java.lang.String)
     */
    @Override
    public void insertEdges(final Multimap<String, String> edges, final String edgeURI) throws IOException {
        if (edges.isEmpty()) {
            return;
        }

        for (String sourceVertexURI : edges.keySet()) {
            for (String destinationVertexURI : edges.get(sourceVertexURI)) {
                insertEdge(sourceVertexURI, destinationVertexURI, edgeURI);
            }
        }

    }

    /*
     * (non-Javadoc)
     * 
     * @see hu.bme.mit.bigmodel.mongo.GraphDriver#insertEdgesWithVertex(com.google.common.collect.Multimap,
     * java.lang.String, java.lang.String)
     */
    @Override
    public void insertEdgesWithVertex(final Multimap<String, String> edges, final String edgeURI,
            final String vertexTypeURI) throws IOException {
        if (edges.isEmpty()) {
            return;
        }

        for (final String targetVertexURI : edges.values()) {
            insertVertex(vertexTypeURI, targetVertexURI);
        }

        insertEdges(edges, edgeURI);
    }

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [ R ]

    /*
     * (non-Javadoc)
     * 
     * @see hu.bme.mit.bigmodel.mongo.GraphDriver#collectVertices(java.lang.String)
     */
    @Override
    public List<BigInteger> collectVertices(final String typeURI) throws IOException {
        List<BigInteger> result = new ArrayList<>();

        MongoCursor<MStatement> cursor = collection
                .find("{ \"predicate\": #, \"object\": # }", RDF_PREFIX + "type", typeURI).as(MStatement.class);

        while (cursor.hasNext()) {
            MStatement next = cursor.next();
            result.add(next.getSubjectBI());
        }
        cursor.close();

        return result;
    }

    /*
     * (non-Javadoc)
     * 
     * @see hu.bme.mit.bigmodel.mongo.GraphDriver#collectVerticesWithProperty(java.lang.String)
     */
    @Override
    public Map<BigInteger, String> collectVerticesWithProperty(final String propertyURI) throws IOException {
        Map<BigInteger, String> result = new HashMap<>();

        MongoCursor<MStatement> cursor = collection.find("{ \"predicate\": # }", propertyURI).as(MStatement.class);

        while (cursor.hasNext()) {
            MStatement next = cursor.next();
            result.put(next.getSubjectBI(), next.getObject().toString());
        }
        cursor.close();

        return result;
    }

    /*
     * (non-Javadoc)
     * 
     * @see hu.bme.mit.bigmodel.mongo.GraphDriver#collectEdges(java.lang.String)
     */
    @Override
    public Multimap<BigInteger, BigInteger> collectEdges(final String edgeURI) throws IOException {
        final Multimap<BigInteger, BigInteger> result = ArrayListMultimap.create();

        MongoCursor<MStatement> cursor = collection.find("{ \"predicate\": # }", edgeURI).as(MStatement.class);

        while (cursor.hasNext()) {
            MStatement next = cursor.next();
            result.get(next.getSubjectBI()).add(next.getObjectBI());
        }
        cursor.close();

        return result;
    }

    /*
     * (non-Javadoc)
     * 
     * @see hu.bme.mit.bigmodel.mongo.GraphDriver#collectOutgoingEdges(java.lang.String, java.lang.String)
     */
    @Override
    public Multimap<BigInteger, BigInteger> collectOutgoingEdges(final String vertexTypeURI, final String edgeURI)
            throws IOException {
        final Multimap<BigInteger, BigInteger> result = ArrayListMultimap.create();

        MongoCursor<MStatement> cursor = collection
                .find("{ \"predicate\": #, \"object\": # }", RDF_PREFIX + "type", vertexTypeURI)
                .as(MStatement.class);

        while (cursor.hasNext()) {
            MStatement next = cursor.next();
            String subject = next.getSubject().toString();

            MongoCursor<MStatement> outgoingEdges = collection
                    .find("{ \"subject\": #, \"predicate\": # }", subject, edgeURI).as(MStatement.class);

            while (outgoingEdges.hasNext()) {
                MStatement nextEdge = outgoingEdges.next();
                result.get(next.getSubjectBI()).add(nextEdge.getObjectBI());
            }

            outgoingEdges.close();
        }

        return result;
    }

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [ U ]

    /*
     * (non-Javadoc)
     * 
     * @see hu.bme.mit.bigmodel.mongo.GraphDriver#updateProperty(java.lang.String, java.lang.String, java.lang.String)
     */
    @Override
    public void updateProperty(final String vertexURI, final String propertyURI, final String value)
            throws IOException {

        collection.update("{ \"subject\": #, \"predicate\": # }", vertexURI, propertyURI).upsert().multi()
                .with("{ $set: { \"object\": # } }", value);

    }

    /*
     * (non-Javadoc)
     * 
     * @see hu.bme.mit.bigmodel.mongo.GraphDriver#updateProperties(java.util.Map, java.lang.String)
     */
    @Override
    public void updateProperties(final Map<String, String> vertexURIAndPropertyValues, final String propertyURI)
            throws IOException {
        if (vertexURIAndPropertyValues.isEmpty()) {
            return;
        }

        for (String vertexURI : vertexURIAndPropertyValues.keySet()) {
            updateProperty(vertexURI, propertyURI, vertexURIAndPropertyValues.get(vertexURI));
        }
    }

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [ D ]

    /*
     * (non-Javadoc)
     * 
     * @see hu.bme.mit.bigmodel.mongo.GraphDriver#deleteVertices(java.util.Collection)
     */
    @Override
    public void deleteVertices(final Collection<String> vertexURIs) throws IOException {
        if (vertexURIs.isEmpty()) {
            return;
        }

        for (final String vertexURI : vertexURIs) {
            deleteVertex(vertexURI);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see hu.bme.mit.bigmodel.mongo.GraphDriver#deleteVertex(java.lang.String)
     */
    @Override
    public void deleteVertex(final String vertexURI) throws IOException {
        // delete "properties", "outgoing edges" and the vertex itself
        WriteResult remove1 = collection.remove("{ \"subject\": # }", vertexURI);

        // "delete incoming edges"
        WriteResult remove2 = collection.remove("{ \"object\": # }", vertexURI);

        if (isShowCommandOutput()) {
            System.out.println("REMOVED " + vertexURI + " with " + remove1.getN() + remove2.getN() + " tuples.");
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see hu.bme.mit.bigmodel.mongo.GraphDriver#deleteEdges(com.google.common.collect.Multimap, java.lang.String)
     */
    @Override
    public void deleteEdges(final Multimap<String, String> vertexURIs, final String edgeURI) throws IOException {
        if (vertexURIs.isEmpty()) {
            return;
        }

        for (String sourceVertexURI : vertexURIs.keySet()) {
            for (String destinationVertexURI : vertexURIs.get(sourceVertexURI)) {
                deleteEdge(sourceVertexURI, destinationVertexURI, edgeURI);
            }
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see hu.bme.mit.bigmodel.mongo.GraphDriver#deleteEdge(java.lang.String, java.lang.String, java.lang.String)
     */
    @Override
    public void deleteEdge(final String sourceVertexURI, final String destinationVertexURI, final String edgeURI)
            throws IOException {

        WriteResult remove = collection.remove("{ \"subject\": #, \"predicate\": #, \"object\": # }",
                sourceVertexURI, edgeURI, destinationVertexURI);

        if (isShowCommandOutput()) {
            System.out.println("DELETED " + sourceVertexURI + " -- " + edgeURI + " -> " + destinationVertexURI
                    + " with " + remove.getN() + " removals.");
        }

    }

    @Override
    public String getURIForBI(BigInteger id) {
        return getURIForId(id.toString(16));
    }

    @Override
    public String getURIForId(String id) {
        return nodes.findOne(new ObjectId(id)).as(Node.class).getURI();
    }

    @Override
    public BigInteger getBIForURI(String URI) {
        return nodes.findOne("{ \"URI\": # }", URI).as(Node.class).get_id_bigint();
    }
}