The Web Graph Database


Examples: FirstStep

Simulates a very simple URL tagging application a la, which allows users to tag any URL on the internet with one or more tags/labels.

See also FirstStepWithMySQL, which persists the data using MySQL as a key-value store.

Obtain, compile and run

  1. Download FirstStep from the downloads page, and uncompress (instructions)
  2. Run ant to compile and run, e.g. ant build run
  3. The app will instantiate some objects representing bookmarks and tags in a graph, and then traverses the graph to print out the data in different ways

Annotated source code


public class FirstStep {

    public static void main( String[] args ) throws Throwable {

        MeshBase mb = MMeshBase.create();

We are creating a MeshBase that stores the MeshObjectGraph in memory only. In this trivial example, there is no persistence. If we wanted persistence, we would instantiate class StoreMeshBase instead of class MMeshBase.

        Transaction tx = mb.createTransactionNow();

To create, change or delete MeshObjects, we need a Transaction. As you will see below, we won't need a Transaction to read the MeshObjectGraph.

        MeshObject tagLibrary = mb.getMeshBaseLifecycleManager().createMeshObject();
        tagLibrary.bless( TaggingSubjectArea.TAGLIBRARY );

We create a new MeshObject, and bless it with type TAGLIBRARY. This particular object type is defined in a Model that is part of InfoGrid. This Model can be used simply by referring to the corresponding Java declarations generated from the Model. We could have created our own type instead. We could also have decided not to bless this object. We can unbless it and re-bless it with another type any time.

        MeshObject tag_funny = mb.getMeshBaseLifecycleManager().createMeshObject( TaggingSubjectArea.TAG );
        MeshObject tag_good  = mb.getMeshBaseLifecycleManager().createMeshObject( TaggingSubjectArea.TAG );

We create two more MeshObjects that represent tags. Again we use types defined in the Model. We assign them the following labels:

        tag_funny.setPropertyValue( TaggingSubjectArea.TAG_LABEL, StringValue.create( "funny" ));
        tag_good.setPropertyValue(  TaggingSubjectArea.TAG_LABEL, StringValue.create( "good"  ));

The Model that we use for this example states that Tags can have Labels, and that is what we use. InfoGrid makes sure that we are not accidentally assigning values to properties that don't exist on the object. The Java class for the value is StringValue, which represents a String.

        tagLibrary.relateAndBless( TaggingSubjectArea.TAGLIBRARY_COLLECTS_TAG.getSource(), tag_funny );
        tagLibrary.relateAndBless( TaggingSubjectArea.TAGLIBRARY_COLLECTS_TAG.getSource(), tag_good );

Here the graph springs into action: we relate the two tags to the tag library in which they are found. We also bless the relationship with the right RelationshipType from the Model, to express the semantics of the relationship.

Next, we create a few MeshObjects that represent websites that we tag:

        MeshObject cnn = mb.getMeshBaseLifecycleManager().createMeshObject(
                mb.getMeshObjectIdentifierFactory().fromExternalForm( "" ),
                WebSubjectArea.WEBRESOURCE );
        MeshObject onion = mb.getMeshBaseLifecycleManager().createMeshObject(
                mb.getMeshObjectIdentifierFactory().fromExternalForm( "" ),
                WebSubjectArea.WEBRESOURCE );
        MeshObject xkcd = mb.getMeshBaseLifecycleManager().createMeshObject(
                mb.getMeshObjectIdentifierFactory().fromExternalForm( "" ),
                WebSubjectArea.WEBRESOURCE );

Here, we do not set the URL of the website as a property, as we had done for the label of the tag. Instead, we use the URL of the website as the permanent identifier of the MeshObject. This makes a lot of semantic sense: while we could conceivably rename the label of a tag, without changing the meaning of the tag (from "funny", to "amusing", for example), the URL of the website constitutes its identity. Note that identifiers of MeshObjects? are long-lived and remain the same even if the MeshObject is used by a different process or a different host.

        tag_good.relateAndBless( TaggingSubjectArea.TAG_TAGS_MESHOBJECT.getSource(),  cnn );
        tag_good.relateAndBless( TaggingSubjectArea.TAG_TAGS_MESHOBJECT.getSource(),  xkcd );
        tag_funny.relateAndBless( TaggingSubjectArea.TAG_TAGS_MESHOBJECT.getSource(), onion );
        tag_funny.relateAndBless( TaggingSubjectArea.TAG_TAGS_MESHOBJECT.getSource(), xkcd );

This is the actually tagging: we relate the websites to the tags and bless the relationships with the right semantics.


We are done with instantiating the example MeshObjectGraph, so we commit the transaction.

Now, let's traverse the MeshObjectGraph:

        // Here are some example traversals:

        System.err.println( "All tags in the tag library, and the sites they tag:" );
        for( MeshObject tag : tagLibrary.traverse( TaggingSubjectArea.TAGLIBRARY_COLLECTS_TAG.getSource() )) {

Starting with object tagLibrary, we find the set of its neighbor MeshObjects that is related to it with the semantics of the TaggingSubjectArea.TAGLIBRARY_COLLECTS_TAG relationship. In other words, we look for the tags in the tag library.

            System.err.println( "    " + tag.getPropertyValue( TaggingSubjectArea.TAG_LABEL ));

Then, we print the label of each tag. Note that InfoGrid is type-safe: if we find a MeshObject that is not blessed with the TAG type, and we attempt this operation, InfoGrid will throw an exception. We are not allowed to read a tag's label if the tag isn't a tag.

We do the same again for all the sites tagged by the tag and print their identifier:

            for( MeshObject site : tag.traverse( TaggingSubjectArea.TAG_TAGS_MESHOBJECT.getSource() )) {
                System.err.println( "        " + site.getIdentifier().toExternalForm() );

In the opposite direction, let's find out the tags with which the xkcd website is tagged:

        System.err.println( "Xkcd is tagged by:" );
        for( MeshObject tag : xkcd.traverse( TaggingSubjectArea.TAG_TAGS_MESHOBJECT.getDestination() )) {
            System.err.println( "    " + tag.getPropertyValue( TaggingSubjectArea.TAG_LABEL ));

And finally, let's find the set of all sites that have been tagged with any tag:

        System.err.println( "All tagged sites (note there are no duplicates: set semantics)" );
        for( MeshObject site : tagLibrary.traverse( TaggingSubjectArea.TAGLIBRARY_COLLECTS_TAG.getSource() )
                               .traverse( TaggingSubjectArea.TAG_TAGS_MESHOBJECT.getSource() )) {
            System.err.println( "    " + site.getIdentifier().toExternalForm() );

Easy? Take the 1-minute survey. Feel free to ask questions on the MailingLists ...

Last modified 9 years ago Last modified on 02/17/10 06:25:52