New detach() and attach() methods on Graph API

When you work with Web Applications, it’s very common to query elements and render them to the user to let him to apply some changes. Once the user updates some fields and press the “save” button, what happens?

Before now the developer had to track the changes in a separate structure, load the vertex/edge from the database and apply the changes to the element.

Starting from OrientDB v1.7 we added 2 new methods to the Graph API against OrientElement and OrientBaseGraph classes:

Detach

Detach methods fetch all the record content in RAM and reset the connection to the Graph instance. This allow to modify the element off-line and re-attach it once finished.

Attach

Once the detached element has been modified, to be saved back to the database you need to call the attach() method. It restore back the connection between the Graph Element and the Graph Instance.

Example

The first step is load some vertex and detach them.

 

OrientGraph g = OrientGraph(“plocal:/temp/db”);
try{
  Iterable<OrientVertex> results = g.query().has(“name”, EQUALS, ‘fast’);
  for( OrientVertex v : results )
    v.detach();
} finally {
  g.shutdown();
}

After a while the element is updated (from GUI or by application)

 

v.setProperty(“name”, “super fast!”);

On “save” button re-attach the element and save it to the database.

 

OrientGraph g = OrientGraph(“plocal:/temp/db”);
try{
  v.attach( g ); v.save();
} finally {
  g.shutdown();
}

FAQ

Does detach go recursively to detach all connected elements?

No, it works only at the current element level.

Can I add edge against detached elements?

No, you can only get/set/remove property while is detached. Any other operation that requires the database will throw an IllegalStateException.

 




London, June, 7th 2013

NuvolaBase is glad to announce the new release 1.4 of OrientDB: http://www.orientdb.org/download.htm!

What’s new with 1.4?
  • Graph: total rewrite of TinkerPop Blueprints API that now are the default Java interface, support for light-weight edges (no document), labeled relationships using separate classes and vertex fields
  • Storage: new Paged-Local compressed “plocal” engine  (not yet transactional)
  • SQL: INSERT and UPDATE supports JSON syntax, improved usage of indexes upon ORDER BY, supported timeout in query and global, new create function command, flatten() now is expand(), new OSQLMethod classes to handle methods even in chain, new encode() and decode() functions, support for new dictionary: as target in SELECT and TRAVERSE
  • new SCHEDULER component using CRON syntax
  • new OTriggered class to use JS as hook
  • MMap: auto flush of pages on regular basis
  • Fetch-plan: support for skip field using “-2”
  • Index: auto rebuild in background, usage of different data-segment
  • Export: supported partial export like schema, few clusters, etc.
  • Console: improved formatting of resultsets
  • HTTP: new /batch command supporting transaction too, faster connection through /connect command, /document returns a JSON
  • StudioUML display of class

Full list: https://github.com/nuvolabase/orientdb/issues?milestone=2&state=closed


Issues

To report an issue please follow the suggestions posted in the group, in particular attach the following information:
  • OrientDB version. Please don’t forget this! If it’s a SNAPSHOT please tell if it’s from SVN (revision number) or from MAVEN
  • Operative System
  • 32-bit or 64-bit
  • JVM version
  • RAM
  • Dump of configuration and profiler

Professional Services
All the professional services are provided by NuvolaBase.com Ltd, London UK.

Partnership
If your company is skilled on using OrientDB and want to be a partner as “reseller” or better a “services partner” please contact info@nuvolabase.com to have more information.

Roadmap
Release 2.0 can wait. We planned an intermediate version 1.5 to release in about one month (mid July 2013) with many things we have postponed.


Thanks to all the committers, the contributors and final users!

Enjoy with Graphs,
Orient Technologies & NuvolaBase Teams




London, April 30th 2013

Toyotaro Suzumura and Miyuru Dayarathna from the Department of Computer Science of the
Tokyo Institute of Technology and IBM Research published an interesting research about a benchmark between Graph Databases in the Clouds called:

XGDBench: A Benchmarking Platform for Graph Stores in Exascale Clouds”

This research conducts a performance evaluation of four famous graph data stores AllegroGraph, Fuseki, Neo4j, an OrientDB using XGDBench on Tsubame 2.0 HPC cloud environment. XGDBench is an extension of famous Yahoo! Cloud Serving Benchmark (YCSB).
OrientDB is the faster Graph Database among the 4 products tested. In particular OrientDB is about 10x faster (!) than Neo4j in all the tests.

Look at the Presentation (25 slides) and Research PDF.




London, April 4th 2013

After about one month spent on development and test the NuvolaBase team has released the new GraphDB Engine!

The new Engine uses some novel techniques based on the idea of a dynamic Graph that change shape at run-time based on the settings and content. The new Engine is much faster than before and needs less space in memory and disk. Below the main improvements:

  1. avoid creation of edges as document if haven’t properties. With Graphs wit no properties on edges this can save more than 50% of space on disk and therefore memory with more chances to have a big part of database in cache. Furthermore this speed up traversal too because requires one record load less. As soon as the first property is set the edge is converted transparently
  2. Vertex “in” and “out” fields aren’t defined in the schema anymore because can be of different types and change at run-time adapting to the content:
    1. no connection = null (no space taken)
    2. 1 connection = store as LINK (few bytes)
    3. >1 connections = use the Set of LINKS (using the MVRBTreeRIDSet class)
  3. binding of Blueprints “label” concept to OrientDB sub-classes. If you create an edge with label “friend”, then the edge sub-type “friend” will be used (created by the engine transparently). This means:
    1. 1 field less in document (the field “label”) and therefore less space and the ability to use the technique 1 (see above)
    2. edges are stored on different files at file system level because are used different clusters
    3. better partitioning against multiple disks (and in the future more parallelism)
    4. direct queries like “select from friend” rather than “select from E” and then filtering the result-set looking for the edge with the wanted label property
  4. multiple properties for edges of different labels. Not anymore a “in” and “out” in Vertex but “out_friend” to store all the outgoing edges of class “friend”. This means faster traversal of edges giving one or multiple labels avoiding to scan the entire Set of edges to find the right one
  5. with such dynamic Graph in future we could support also HyperGraph in a flash
Such new Engine needed new API or a radical change to the current Raw API breaking the compatibility with the past. Well, we decided to change strategy by re-implementing the Blueprints Graph layer as new GraphDB Engine. So the new GraphDB Engine IS the OrientDB’s Blueprints implementation.
Why? Mainly because:
  1. Blueprints is the de facto standard for Graph Databases made by TinkerPop team
  2. TinkerPop team is amazing with a lot of technologies built on top of Blueprints layer
  3. Latest release of Blueprints added some new features to allow the implementations to use the underlying engine in more powerful way
  4. Blueprints API and all the TinkerPop stack is very well documented with a lot of examples and a new Book that is coming
The new GraphDB engine depends on OrientDB 1.4.0-SNAPSHOT, so we can’t push it to TinkerPop repository because no SNAPSHOT are allowed as dependencies. As soon as we release OrientDB 1.4 we’re going to merge it with official TinkerPop Blueprint’s repository.
Starting from OrientDB 1.4 the GraphDB API to use are the Blueprints. Period. I’m sure this will make happy some users because Raw API are horrible and you’ve to work at document level using the OGraphDatabase class for any operations against vertices and edges (not really Object Oriented).
Waiting for the official release you can enjoy by cloning and start using the new GraphDB Engine from the master branch of NuvolaBase’s Blueprints fork: https://github.com/nuvolabase/blueprints. It passes all the Blueprints Test Cases.
To open databases created with previous releases uses:
OrientGraph graph = new OrientGraph(“local:/temp/mydb”);
graph.setUseLightweightEdges(false);
graph.setUseVertexFieldsForEdgeLabels(false);
graph.setUseCustomClassesForEdges(false);
In the next days will be released a new tool to convert the databases to the new format.

Luca Garulli
CEO at NuvolaBase.com
the Company behind OrientDB
Follow me on http://twitter.com/lgarulli




Introduction

This tutorial explains step-by-step how to create partitioned graphs using the Record Level Security feature introduced in OrientDB 1.2.0. This feature is so powerful we can totally separate database’s records as sand-boxes where each “Restricted” records can’t be accessed by non authorized users. This tutorial demonstrates this sand-boxes works well also with the GraphDB API and the TinkerPop stackPartitioning graphs allows to build real Multi-tenant applications in a breeze.

Requirements:


Index of contents

Create a new empty graph database

First open the console of the GraphDB Edition and create the new database “blog” of type “graph” against the local file-system:
$ cd $ORIENTDB_HOME/bin
$ console
.shOrientDB console v.1.2.0-SNAPSHOT www.orientechnologies.comType 'help' to display all the commands supported.
Installing extensions for GREMLIN language v.2.2.0-SNAPSHOT

orientdb
> create database local:../databases/blog admin admin local graphCreating database [local:../databases/blog] using the storage type [local]...
Database created successfully.
Current database is: local:../databases/blog

Enable graph partitioning

Now turn on partitioning against graph by letting classes V (Vertex) and E (Edge) to extend the ORestricted class. In this way any access to Vertex and Edge instances can be restricted:
orientdb> alter class V superclass ORestrictedClass updated successfully

orientdb
> alter class E superclass ORestricted
Class updated successfully

Create 2 users

Now let’s go creating 2 users: “luca” and “steve”. First ask the current roles in database to know the “writer” role’s rid:
orientdb> select from orole
---+---------+--------------------+--------------------+--------------------+--------------------
 
#| RID     |name                |mode                |rules               |inheritedRole
---+---------+--------------------+--------------------+--------------------+--------------------
 
0|     #4:0|admin               |1                   |{}                  |null
 
1|     #4:1|reader              |0                   |{database=2, database.schema=2, database.cluster.internal=2, database.cluster.orole=2, database.cluster.ouser=2, database.class.*=2, database.cluster.*=2, database.command=2, database.hook.record=2}|null
 
2|     #4:2|writer              |0                   |{database=2, database.schema=7, database.cluster.internal=2, database.cluster.orole=2, database.cluster.ouser=2, database.class.*=15, database.cluster.*=15, database.command=15, database.hook.record=15}|null
---+---------+--------------------+--------------------+--------------------+--------------------
3 item(s) found. Query executed in 0.045 sec(s).
Found it, it’s the #4:2. Not create 2 users with as first role #4:2 (writer):
orientdb> insert into ouser set name = 'luca', status = 'ACTIVE', password = 'luca', roles = [#4:2]
Inserted record 'OUser#5:4{name:luca,password:{SHA-256}D70F47790F689414789EEFF231703429C7F88A10210775906460EDBF38589D90,roles:[1]} v1' in 0,001000 sec(s).

orientdb
> insert into ouser set name = 'steve', status = 'ACTIVE', password = 'steve', roles = [#4:2]
Inserted record 'OUser#5:3{name:steve,password:{SHA-256}F148389D080CFE85952998A8A367E2F7EAF35F2 D72D2599A5B0412FE4094D65C,roles:[1]} v1' in 0,001000 sec(s).

Create a simple graph as user ‘Luca’

Now it’s time to disconnect and reconnect to the blog database using the new “luca” user:
orientdb> disconnect
Disconnecting from the database [blog]...OK

orientdb
> connect local:../databases/blog luca lucaConnecting to database [local:../databases/blog] with user 'luca'...OK
Now create 2 vertices: a Restaurant and a Pizza:
orientdb> create vertex set label = 'food', name = 'Pizza'
Created vertex 'V#9:0{label:food,name:Pizza,_allow:[1]} v0' in 0,001000 sec(s).

orientdb
> create vertex set label = 'restaurant', name = "Dante's Pizza"
Created vertex 'V#9:1{label:restaurant,name:Dante's Pizza,_allow:[1]} v0' in 0,000000 sec(s).
Now connect these 2 vertices with an edge labelled “menu”:
orientdb> create edge from #9:0 to #9:1 set label = 'menu'
Created edge '[E#10:0{out:#9:0,in:#9:1,label:menu,_allow:[1]} v1]' in 0,003000 sec(s).
To check if everything is ok execute a select against vertices:
orientdb> select from v
---+---------+--------------------+--------------------+--------------------+--------------------
 
#| RID     |label               |name                |_allow              |out
---+---------+--------------------+--------------------+--------------------+--------------------
 
0|     #9:0|food                |Pizza               |[1]                 |[1]
 
1|     #9:1|restaurant          |Dante's Pizza       |[1]                 |null                |[1]
---+---------+--------------------+--------------------+--------------------+--------------------+--------------------
2 item(s) found. Query executed in 0.034 sec(s).

Create a simple graph as user ‘Steve’

Now let’s connect to the database using the ‘Steve’ user and check if there are vertices:
orientdb> disconnect
Disconnecting from the database [blog]...OK

orientdb
> connect local:../databases/blog steve steveConnecting to database [local:../databases/blog] with user 'steve'...OK

orientdb
> select from v
0 item(s) found. Query executed in 0.0 sec(s).
Ok, no vertices found. Try to create something:
orientdb> create vertex set label = 'car', name = 'Ferrari Modena'
Created vertex 'V#9:2{label:car,name:Ferrari Modena,_allow:[1]} v0' in 0,000000 sec(s).

orientdb
> create vertex set label = 'driver', name = 'steve'
Created vertex 'V#9:3{label:driver,name:steve,_allow:[1]} v0' in 0,000000 sec(s).

orientdb
> create edge from #9:2 to #9:3 set label = 'drive'
Created edge '[E#10:1{out:#9:2,in:#9:3,label:drive,_allow:[1]} v1]' in 0,002000 sec(s).
Now check the graph just created:
orientdb> select from v
---+---------+--------------------+--------------------+--------------------+--------------------
 
#| RID     |label               |name                |_allow              |out
---+---------+--------------------+--------------------+--------------------+--------------------
 
0|     #9:2|car                 |Ferrari Modena      |[1]                 |[1]
 
1|     #9:3|driver              |steve               |[1]                 |null                |[1]
---+---------+--------------------+--------------------+--------------------+--------------------+--------------------
2 item(s) found. Query< span> executed in 0.034 sec(s).
The “Steve” user doesn’t see the vertices and edges creates by other users!
What happen if we try to connect 2 vertices of different users?
orientdb> create edge from #9:2 to #9:0 set label = 'security-test'

Error: com.orientechnologies.orient.core.exception.OCommandExecutionException: Error on execution of command: OCommandSQL [text=create edge from #9:2 to #9:0 set label = 'security-test']
Error: java.lang.IllegalArgumentException: Source vertex '#9:0' does not exist
The partition is totally isolated and OrientDB thinks the vertex doesn’t exist while it’s present, but invisible to the current user.

TinkerPop Stack

Record Level Security feature is very powerful because acts at low level inside the OrientDB engine. This is why everything works like a charm, even the TinkerPop stack.

Now try to display all the vertices and edges using Gremlin:
orientdb> gremlin g.V
[v[#9:2], v[#9:3]]
Script executed in 0,448000 sec(s).
orientdb
> gremlin g.E

e
[#10:1][#9:2-drive->#9:3]
Script executed in 0,123000 sec(s).

The same is using other technologies that use the TinkerPop Blueprints: TinkerPop RexterTinkerPop PipesTinkerPop FurnaceTinkerPop Frames and ThinkAurelius Faunus.


This tutorial has been published in http://code.google.com/p/orient/wiki/PartitionedGraphs.





Unlock the full potential of your enterprise’s data