OrientDB Manual Orient DB Manual(2.2.X)

User Manual: Pdf

Open the PDF directly: View PDF PDF.
Page Count: 1243

DownloadOrientDB Manual Orient DB-Manual(2.2.X)
Open PDF In BrowserView PDF
Table of Contents
Introduction

1.1

Getting Started

1.2

Installation

1.2.1

Run the server

1.2.2

Run the console

1.2.3

Run the Studio

1.2.4

Classes

1.2.5

Clusters

1.2.6

Record ID

1.2.7

Relationships

1.2.8

Basic SQL

1.2.9

Working with Graphs

1.2.10

Using Schema with Graphs

1.2.11

Setup a Distributed Database

1.2.12

Working with Distributed Graphs

1.2.13

Data M odeling
Basic Concepts

1.3
1.3.1

Supported Types

1.3.1.1

Inheritance

1.3.1.2

Concurrency

1.3.1.3

Schema

1.3.1.4

Graph or Document API?

1.3.1.5

Cluster Selection

1.3.1.6

M anaging Dates

1.3.1.7

Graph Consistency

1.3.2

Fetching Strategies

1.3.3

Use Cases

1.3.4

Time Series

1.3.4.1

Chat

1.3.4.2

Key Value

1.3.4.3

Queue system

1.3.4.4

Administration
Console

1.4
1.4.1

Backup

1.4.1.1

Begin

1.4.1.2

Browse Class

1.4.1.3

Browse Cluster

1.4.1.4

List Classes

1.4.1.5

Cluster Status

1.4.1.6

List Clusters

1.4.1.7

List Servers

1.4.1.8

1

List Server Users

1.4.1.9

Commit

1.4.1.10

Config

1.4.1.11

Config Get

1.4.1.12

Config Set

1.4.1.13

Connect

1.4.1.14

Create Cluster

1.4.1.15

Create Database

1.4.1.16

Create Index

1.4.1.17

Create Link

1.4.1.18

Create Property

1.4.1.19

Declare Intent

1.4.1.20

Delete

1.4.1.21

Dictionary Get

1.4.1.22

Dictionary Keys

1.4.1.23

Dictionary Put

1.4.1.24

Dictionary Remove

1.4.1.25

Disconnect

1.4.1.26

Display Record

1.4.1.27

Display Raw Record

1.4.1.28

Drop Cluster

1.4.1.29

Drop Database

1.4.1.30

Drop Server User

1.4.1.31

Export Database

1.4.1.32

Export Record

1.4.1.33

Freeze DB

1.4.1.34

Get

1.4.1.35

Gremlin

1.4.1.36

Import Database

1.4.1.37

Indexes

1.4.1.38

Info

1.4.1.39

Info Class

1.4.1.40

Info Property

1.4.1.41

Insert

1.4.1.42

Js

1.4.1.43

Jss

1.4.1.44

List Databases

1.4.1.45

List Connections

1.4.1.46

Load Record

1.4.1.47

Load Script

1.4.1.48

Profiler

1.4.1.49

Properties

1.4.1.50

Release DB

1.4.1.51

Reload Record

1.4.1.52

2

Repair Database

1.4.1.53

Restore

1.4.1.54

Rollback

1.4.1.55

Set

1.4.1.56

Set Server User

1.4.1.57

Sleep

1.4.1.58

Upgrading

1.4.2

Backward compatibility

1.4.2.1

From 2.1.x to 2.2.x

1.4.2.2

From 2.0.x to 2.1.x

1.4.2.3

From 1.7.x to 2.0.x

1.4.2.4

From 1.6.x to 1.7.x

1.4.2.5

From 1.5.x to 1.6.x

1.4.2.6

From 1.4.x to 1.5.x

1.4.2.7

From 1.3.x to 1.4.x

1.4.2.8

Backup and Restore
Incremental Backup and Restore

1.4.3
1.4.3.1

Export and Import

1.4.4

Export format

1.4.4.1

Import From RDBM S

1.4.4.2

To Document M odel

1.4.4.2.1

To Graph M odel

1.4.4.2.2

Import From Neo4j
Neo4j to OrientDB Importer
Tutorial: Importing the northwind Database from Neo4j
Import from Neo4j using GraphM L
Tutorial: Importing the movie Database from Neo4j
ETL

1.4.4.3
1.4.4.3.1
1.4.4.3.1.1
1.4.4.3.2
1.4.4.3.2.1
1.4.5

Configuration

1.4.5.1

Blocks

1.4.5.2

Sources

1.4.5.3

Extractors

1.4.5.4

Transformers

1.4.5.5

Loaders

1.4.5.6

Tutorial: Importing the Open Beer Database into OrientDB

1.4.5.7

Import from CSV to a Graph

1.4.5.8

Import a tree structure

1.4.5.9

Import from JSON

1.4.5.10

Import from RDBM S

1.4.5.11

Import from DB-Pedia

1.4.5.12

Import from Parse (Facebook)

1.4.5.13

Logging

1.4.6

Scheduler

1.4.7

Studio

1.4.8

3

Query

1.4.8.1

Edit Document

1.4.8.2

Edit Vertex

1.4.8.3

Schema

1.4.8.4

Class

1.4.8.5

Graph Editor

1.4.8.6

Functions

1.4.8.7

Security

1.4.8.8

Database M anagement

1.4.8.9

Dashboard

1.4.8.10

Server M anagement

1.4.8.11

Cluster M anagement

1.4.8.12

Data Centers

1.4.8.13

Query Profiler

1.4.8.14

Studio Auditing

1.4.8.15

Studio

1.4.8.16

Teleporter

1.4.8.17

Teleporter

1.4.9

Installation and configuration

1.4.9.1

Execution strategies

1.4.9.2

Sequential executions and One-Way Synchronizer

1.4.9.3

Import filters

1.4.9.4

Inheritance

1.4.9.5

Single Table Inheritance

1.4.9.5.1

Table Per Class Inheritance

1.4.9.5.2

Table Per Concrete Class Inheritance

1.4.9.5.3

Import Configuration
Troubleshooting

1.4.9.6
1.4.10

Java

1.4.10.1

Query Examples

1.4.10.2

Performance Tuning

1.4.11

Setting Configuration

1.4.11.1

Graph API

1.4.11.2

Document API

1.4.11.3

Object API

1.4.11.4

Profiler

1.4.11.5

Leak Detector

1.4.11.6

Distributed tuning

1.4.11.7

Security

1.4.12

Database security

1.4.12.1

Server security

1.4.12.2

Database encryption

1.4.12.3

Secure SSL connections

1.4.12.4

Security Configuration

1.4.12.5

4

Kerberos Example

1.4.12.6

Security v2.2 Code Changes

1.4.12.7

Security v2.2 New Features

1.4.12.8

Symmetric Key Authentication

1.4.12.9

Server M anagement

1.4.13

Install as Service on Unix

1.4.13.1

Install as Service on Windows

1.4.13.2

Install with Docker

1.4.13.3

Stress Test Tool
APIs and Drivers

1.4.14
1.5

Functions

1.5.1

Creating Functions

1.5.1.1

Using Functions

1.5.1.2

Accessing the Database

1.5.1.3

Server-side Functions

1.5.1.4

Available Plugins and Tools

1.5.2

Java API

1.5.3

Java API Introduction

1.5.3.1

Graph API

1.5.3.2

Vertices and Edges

1.5.3.2.1

Blueprints Extension

1.5.3.2.2

Factory

1.5.3.2.3

Schema

1.5.3.2.4

Class

1.5.3.2.4.1

Property

1.5.3.2.4.2

Partitioned

1.5.3.2.5

Comparison

1.5.3.2.6

Lightweight Edges

1.5.3.2.7

Graph Batch Insert

1.5.3.2.8

Document API

1.5.3.3

Database

1.5.3.3.1

Documents

1.5.3.3.2

Schema

1.5.3.3.3

Classes

1.5.3.3.3.1

Property

1.5.3.3.3.2

Field Part

1.5.3.3.4

Comparison

1.5.3.3.5

Object API
Binding

1.5.3.4
1.5.3.4.1

Traverse

1.5.3.5

Live Query

1.5.3.6

M ulti-Threading

1.5.3.7

Transactions

1.5.3.8

Binary Data

1.5.3.9

5

Web Apps

1.5.3.10

JDBC Driver

1.5.3.11

JPA

1.5.3.12

JM X

1.5.4

Gremlin API

1.5.5

Javascript

1.5.6

Javascript API
OrientJS (Node.js)

1.5.6.1
1.5.7

Server API

1.5.7.1

Database API

1.5.7.2

Record API

1.5.7.3

Class API

1.5.7.4

Class

1.5.7.4.1

Property

1.5.7.4.2

Records

1.5.7.4.3

Index API

1.5.7.5

Function API

1.5.7.6

Queries

1.5.7.7

create()

1.5.7.7.1

delete()

1.5.7.7.2

fetch()

1.5.7.7.3

insert()

1.5.7.7.4

liveQuery()

1.5.7.7.5

select()

1.5.7.7.6

transform()

1.5.7.7.7

traverse()

1.5.7.7.8

update()

1.5.7.7.9

Transactions

1.5.7.8

Events

1.5.7.9

PyOrient

1.5.8

Client

1.5.8.1

command()

1.5.8.1.1

batch()

1.5.8.1.2

data_cluster_add()

1.5.8.1.3

data_cluster_count()

1.5.8.1.4

data_cluster_data_range()

1.5.8.1.5

data_cluster_drop()

1.5.8.1.6

db_count_records()

1.5.8.1.7

db_create()

1.5.8.1.8

db_drop()

1.5.8.1.9

db_exists()

1.5.8.1.10

db_list()

1.5.8.1.11

db_open()

1.5.8.1.12

db_reload()

1.5.8.1.13

6

db_size()

1.5.8.1.14

get_session_token()

1.5.8.1.15

query()

1.5.8.1.16

query_async()

1.5.8.1.17

record_create()

1.5.8.1.18

record_delete()

1.5.8.1.19

record_load()

1.5.8.1.20

record_update()

1.5.8.1.21

set_session_token()

1.5.8.1.22

tx_commit()

1.5.8.1.23

attach()

1.5.8.1.23.1

begin()

1.5.8.1.23.2

commit()

1.5.8.1.23.3

rollback()

1.5.8.1.23.4

OGM

1.5.8.2

Connection

1.5.8.2.1

Schemas

1.5.8.2.2

Brokers

1.5.8.2.3

Batch

1.5.8.2.4

Scripts

1.5.8.2.5

C#/.NET

1.5.9

Server

1.5.9.1

ConfigGet()

1.5.9.1.1

ConfigList()

1.5.9.1.2

ConfigSet()

1.5.9.1.3

CreateDatabase()

1.5.9.1.4

DatabaseExists()

1.5.9.1.5

Databases()

1.5.9.1.6

DropDatabase()

1.5.9.1.7

Database

1.5.9.2

Clusters()

1.5.9.2.1

Command()

1.5.9.2.2

GetClusterIdFor()

1.5.9.2.3

GetClusterNameFor()

1.5.9.2.4

GetClusters()

1.5.9.2.5

Gremlin()

1.5.9.2.6

Insert()

1.5.9.2.7

JavaScript()

1.5.9.2.8

Query()

1.5.9.2.9

Select()

1.5.9.2.10

SqlBatch()

1.5.9.2.11

Update()

1.5.9.2.12

Query
Conditionals

1.5.9.3
1.5.9.3.1

7

Limiters

1.5.9.3.2

Sort

1.5.9.3.3

Transaction

1.5.9.4

Add()

1.5.9.4.1

AddEdge()

1.5.9.4.2

AddOrUpdate()

1.5.9.4.3

Delete()

1.5.9.4.4

GetPendingObject()

1.5.9.4.5

Update()

1.5.9.4.6

PHP

1.5.10
Client

1.5.10.1

Server

1.5.10.2

dbCreate()

1.5.10.2.1

dbDrop()

1.5.10.2.2

dbExists()

1.5.10.2.3

dbList()

1.5.10.2.4

Database

1.5.10.3

command()

1.5.10.3.1

dataClusterAdd()

1.5.10.3.2

dataClusterCount()

1.5.10.3.3

dataClusterDrop()

1.5.10.3.4

dataClusterDataRange()

1.5.10.3.5

dbCountRecords()

1.5.10.3.6

dbReload()

1.5.10.3.7

dbSize()

1.5.10.3.8

query()

1.5.10.3.9

queryAsync()

1.5.10.3.10

recordCreate()

1.5.10.3.11

recordLoad()

1.5.10.3.12

recordUpdate()

1.5.10.3.13

sqlBatch()

1.5.10.3.14

ClusterM ap

1.5.10.4

dropClusterID()

1.5.10.4.1

getClusterID()

1.5.10.4.2

getIdList()

1.5.10.4.3

Record

1.5.10.5

getOClass()

1.5.10.5.1

getOData()

1.5.10.5.2

getRid()

1.5.10.5.3

jsonSerialize()

1.5.10.5.4

recordSerialize()

1.5.10.5.5

setOClass()

1.5.10.5.6

setOData()

1.5.10.5.7

setRid()

1.5.10.5.8

8

ID

1.5.10.6

Transaction

1.5.10.7

attach()

1.5.10.7.1

begin()

1.5.10.7.2

commit()

1.5.10.7.3

rollback()

1.5.10.7.4

Elixir

1.5.11

Server

1.5.11.1

create_db()

1.5.11.1.1

db_exists?()

1.5.11.1.2

distrib-config()

1.5.11.1.3

drop_db()

1.5.11.1.4

Database

1.5.11.2

command()

1.5.11.2.1

create_record()

1.5.11.2.2

db_countrecords()

1.5.11.2.3

db_reload()

1.5.11.2.4

db_size()

1.5.11.2.5

delete_record()

1.5.11.2.6

live_query()

1.5.11.2.7

live_query_unsubscribe()

1.5.11.2.8

load_record()

1.5.11.2.9

script()

1.5.11.2.10

update_record()

1.5.11.2.11

Types

1.5.11.3

Structs

1.5.11.4

BinaryRecord

1.5.11.4.1

Date

1.5.11.4.2

DateTime

1.5.11.4.3

Document

1.5.11.4.4

RID

1.5.11.4.5

Scala API

1.5.12

HTTP API

1.5.13

Binary Protocol

1.5.14

CSV Serialization

1.5.14.1

Schemaless Serialization

1.5.14.2

Commands

1.5.14.3

SQL Reference
Commands

1.6
1.6.1

Alter Class

1.6.1.1

Alter Cluster

1.6.1.2

Alter Database

1.6.1.3

Alter Property

1.6.1.4

Alter Sequence

1.6.1.5

9

Create Class

1.6.1.6

Create Cluster

1.6.1.7

Create Edge

1.6.1.8

Create Function

1.6.1.9

Create Index

1.6.1.10

Create Link

1.6.1.11

Create Property

1.6.1.12

Create Sequence

1.6.1.13

Create User

1.6.1.14

Create Vertex

1.6.1.15

Delete

1.6.1.16

Delete Edge

1.6.1.17

Delete Vertex

1.6.1.18

Drop Class

1.6.1.19

Drop Cluster

1.6.1.20

Drop Index

1.6.1.21

Drop Property

1.6.1.22

Drop Sequence

1.6.1.23

Drop User

1.6.1.24

Explain

1.6.1.25

Find References

1.6.1.26

Grant

1.6.1.27

HA Remove Server

1.6.1.28

HA Status

1.6.1.29

HA Sync Cluster

1.6.1.30

HA Sync Database

1.6.1.31

HA Set

1.6.1.32

Insert

1.6.1.33

Live Select

1.6.1.34

Live Unsubscribe

1.6.1.35

M atch

1.6.1.36

M ove Vertex

1.6.1.37

Optimize Database

1.6.1.38

Rebuild Index

1.6.1.39

Revoke

1.6.1.40

Select

1.6.1.41

Traverse

1.6.1.42

Truncate Class

1.6.1.43

Truncate Cluster

1.6.1.44

Truncate Record

1.6.1.45

Update

1.6.1.46

Update Edge

1.6.1.47

Filtering

1.6.2

Functions

1.6.3

10

M ethods

1.6.4

Batch

1.6.5

Pagination

1.6.6

Sequences and auto increment

1.6.7

Pivoting with Query

1.6.8

Command Cache

1.6.9

Query Optimization
Indexing

1.6.10
1.7

SB-Tree

1.7.1

Hash

1.7.2

Auto-Sharding

1.7.3

Full Text

1.7.4

Lucene Full Text

1.7.5

Lucene Spatial Index

1.7.6

Scaling

1.8

Lifecycle

1.8.1

Configuration

1.8.2

Server M anager

1.8.2.1

Runtime Configuration

1.8.2.2

Replication

1.8.3

Sharding

1.8.4

Data Centers

1.8.5

Tuning

1.8.6

HA SQL Commands

1.8.7

HA Remove Server

1.8.7.1

HA Status

1.8.7.2

HA Sync Cluster

1.8.7.3

HA Sync Database

1.8.7.4

HA Set

1.8.7.5

Internals

1.9

Storages

1.9.1

M emory storage

1.9.1.1

PLocal storage

1.9.1.2

Engine

1.9.1.2.1

Disk-Cache

1.9.1.2.2

WAL (Journal)

1.9.1.2.3

Local storage (deprecated)

1.9.1.3

Clusters

1.9.2

Limits

1.9.3

RidBag

1.9.4

SQL Syntax

1.9.5

Custom Index Engine

1.9.6

Caching

1.9.7

Transaction

1.9.8

11

Hooks - Triggers

1.9.9

Dynamic Hooks

1.9.10

Java (Native) Hooks

1.9.10.1

Java Hook Tutorial

1.9.10.2

Server

1.9.11

Embed the Server

1.9.11.1

Web Server

1.9.11.2

System Database

1.9.12

System Users

1.9.13

Implementation

1.9.13.1

M ulti Tenant

1.9.14

Plugins

1.9.15

Automatic Backup

1.9.15.1

SysLog

1.9.15.2

M ail

1.9.15.3

JM X

1.9.15.4

Rexster

1.9.15.5

Gephi Graph Render

1.9.15.6

spider-box

1.9.15.7

Script Interpreter Plugin

1.9.15.8

Contribute to OrientDB

1.10

Hackaton

1.10.1

Report an issue

1.10.2

Get in touch

1.10.2.1

M ore Tutorials

1.10.2.2

Presentations
Roadmap
Enterprise Edition
Auditing
Tutorials

1.10.3
1.10.3.1
1.11
1.11.1
1.12

Tutorial: Importing the Open Beer Database into OrientDB

1.12.1

Tutorial: Importing the movie Database from Neo4j

1.12.2

Tutorial: Importing the northwind Database from Neo4j

1.12.3

Java Hook Tutorial

1.12.4

Release Notes

1.13

12

Introduction

OrientDB Manual - version 2.2.x

Quick Navigation
Getting S tarted

Main Topics

Developers

Introduction to OrientDB

Basic Concepts

SQL

Installation

Supported Data Types

Gremlin

First Steps

Inheritance

HTTP API

Troubleshooting

Security

Java API

Enterprise Edition

Indexes

NodeJS

ACID Transactions

PHP

Functions

Python

Caching Levels

.NET

Common Use Cases

Other Drivers
Network Binary Protocol
Javadocs

Operations
Installation
3rd party Plugins
Upgrade
Configuration
Distributed Architecture (replication, sharding and high-availability)
Performance Tuning
ETL to Import any kind of data into OrientDB
Import from Relational DB
Backup and Restore
Export and Import

Quick References

13

Introduction
Console
Studio web tool
Workbench (Enterprise Edition)
OrientDB Server
Network-Binary-Protocol
Gephi Graph Analysis Visual tool
Rexster Support and configuration
Continuous integration

Resources
User Group - Have question, troubles, problems?
#orientdb IRC channel on freenode
Professional Support
Training - Training and classes.
Events - Follow OrientDB at the next event!
Team - M eet the team behind OrientDB
Contribute - Contribute to the project.
Who is using OrientDB? - Clients using OrientDB in production.

Questions or Need Help?
Check out our Get in Touch page for different ways of getting in touch with us.

PDF
This documentation is also available in PDF format.

Past releases
v1.7.8
v2.0.x
v2.1.x
Welcome to OrientDB - the first M ulti-M odel Open Source NoSQL DBM S that brings together the power of graphs and the flexibility
of documents into one scalable high-performance operational database.
Every effort has been made to ensure the accuracy of this manual. However, OrientDB, LTD. makes no warranties with respect
to this documentation and disclaims any implied warranties of merchantability and fitness for a particular purpose. The
information in this document is subject to change without notice.

14

Getting Started

Getting Started
Over the past few years, there has been an explosion of many NoSQL database solutions and products. The meaning of the word
"NoSQL" is not a campaign against the SQL language. In fact, OrientDB allows for SQL syntax! NoSQL is probably best described by
the following:
NoSQL, meaning "not only SQL", is a movement encouraging developers and business people to open their minds and consider
new possibilities beyond the classic relational approach to data persistence.
Alternatives to relational database management systems have existed for many years, but they have been relegated primarily to niche use
cases such as telecommunications, medicine, CAD and others. Interest in NoSQL alternatives like OrientDB is increasing dramatically.
Not surprisingly, many of the largest web companies like Google, Amazon, Facebook, Foursquare and Twitter are using NoSQL based
solutions in their production environments.
What motivates companies to leave the comfort of a well established relational database world? It is basically the great need to better
solve today's data problems. Specifically, there are a few key areas:
Performance
Scalability (often huge)
Smaller footprint
Developer productivity and friendliness
Schema flexibility
M ost of these areas also happen to be the requirements of modern web applications. A few years ago, developers designed systems that
could handle hundreds of concurrent users. Today it is not uncommon to have a potential target of thousands or millions of users
connected and served at the same time.
Changing technology requirements have been taken into account on the application front by creating frameworks, introducing standards
and leveraging best practices. However, in the database world, the situation has remained more or less the same for over 30 years. From
the 1970s until recently, relational DBM Ss have played the dominant role. Programming languages and methodologies have evolved, but
the concept of data persistence and the DBM S have remained unchanged for the most part: it is all still tables, records and joins.

NoSQL Models
NoSQL-based solutions in general provide a powerful, scalable, and flexible way to solve data needs and use cases, which have
previously been managed by relational databases. To summarize the NoSQL options, we'll examine the most common models or
categories:
Key / Value databases: where the data model is reduced to a simple hash table, which consists of key / value pairs. It is often
easily distributed across multiple servers. The most recognized products of this group include Redis, Dynamo, and Riak.
Column-oriented databases: where the data is stored in sections of columns offering more flexibility and easy aggregation.
Facebook's Cassandra, Google's BigTable, and Amazon's SimpleDB are some examples of column-oriented databases.
Document databases: where the data model consists of document collections, in which each individual document can have
multiple fields without necessarily having a defined schema. The best known products of this group are M ongoDB and CouchDB.
Graph databases: where the domain model consists of vertices interconnected by edges creating rich graph structures. The best
known products of this group are OrientDB, Neo4j and Titan.
OrientDB is a document-graph database, meaning it has full native graph capabilities coupled with features normally only found
in document databases.
Each of these categories or models has its own peculiarities, strengths and limitations. There is no single category or model, which is
better than the others. However, certain types of databases are better at solving specific problems. This leads to the motto of NoSQL:
choose the best tool for your specific use case.
The goal of Orient Technologies in building OrientDB was to create a robust, highly scalable database that can perform optimally in the
widest possible set of use cases. Our product is designed to be a fantastic "go to" solution for practically all of your data persistence
needs. In the following parts of this tutorial, we will look closely at OrientDB, one of the best open-source, multi-model, next

15

Getting Started
generation NoSQL products on the market today.

16

Installation

Installation
OrientDB is available in two editions:
Community Edition is released as an open source project under the Apache 2 license. This license allows unrestricted free usage
for both open source and commercial projects.
Enterprise Edition is commercial software built on top of the Community Edition. Enterprise is developed by the same team that
developed the OrientDB engine. It serves as an extension of the Community Edition, providing Enterprise features, such as:
Non-Stop Backup and Restore
Scheduled FULL and Incremental Backups
Query Profiler
Distributed Clustering configuration
M etrics Recording
Live M onitoring with configurable Alerts
The Community Edition is available as a binary package for download or as source code on GitHub. The Enterprise Edition license is
included with Support purchases.

Use Docker
If you have Docker installed in your computer, this is the easiest way to run OrientDB. From the command line type:
$ docker run -d --name orientdb -p 2424:2424 -p 2480:2480
-e ORIENTDB_ROOT_PASSWORD=root orientdb:latest

Where instead of "root", type the root's password you want to use.

Use Ansible
If you manage your servers through Ansible, you can use the following role : https://galaxy.ansible.com/migibert/orientdb which is highly
customizable and allows you to deploy OrientDB as a standalone instance or multiple clusterized instances.
For using it, you can follow these steps :
Install the role
ansible-galaxy install migibert.orientdb

Create an Ansible inventory
Assuming you have one two servers with respective IPs fixed at 192.168.10.5 and 192.168.10.6, using ubuntu user.
[orientdb-servers]
192.168.20.5 ansible_ssh_user=ubuntu
192.168.20.6 ansible_ssh_user=ubuntu

Create an Ansible playbook
In this example, we provision a two node cluster using multicast discovery mode. Please note that this playbook assumes java is already
installed on the machine so you should have one step before that install Java 8 on the servers

17

Installation
- hosts: orientdb-servers
become: yes
vars:
orientdb_version: 2.0.5
orientdb_enable_distributed: true
orientdb_distributed:
hazelcast_network_port: 2434
hazelcast_group: orientdb
hazelcast_password: orientdb
multicast_enabled: True
multicast_group: 235.1.1.1
multicast_port: 2434
tcp_enabled: False
tcp_members: []
orientdb_users:
- name: root
password: root
tasks:
- apt:
name: openjdk-8-jdk
state: present
roles:
- role: orientdb-role

Run the playbook

ansible-playbook -i inventory playbook.yml

Prerequisites
Both editions of OrientDB run on any operating system that implements the Java Virtual machine (JVM ). Examples of these include:
Linux, all distributions, including ARM (Raspberry Pi, etc.)
M ac OS X
M icrosoft Windows, from 95/NT and later
Solaris
HP-UX
IBM AIX
OrientDB requires Java, version 1.7 or higher.
Note: In OSGi containers, OrientDB uses a

ConcurrentLinkedHashMap

implementation provided by concurrentlinkedhashmap to

create the LRU based cache. This library actively uses the sun.misc package which is usually not exposed as a system package.
To overcome this limitation you should add property

org.osgi.framework.system.packages.extra

with value

sun.misc

to your

list of framework properties.
It may be as simple as passing an argument to the VM starting the platform:
$ java -Dorg.osgi.framework.system.packages.extra=sun.misc

Binary Installation
OrientDB provides a pre-compiled binary package to install the database on your system. Depending on your operating system, this is
a tarred or zipped package that contains all the relevant files you need to run OrientDB. For desktop installations, go to OrientDB
Downloads and select the package that best suits your system.
On server installations, you can use the

wget

utility:

$ wget http://bit.ly/orientdb-ce-tele-2-2-23 -O orientdb-community-2.2.23.zip

Whether you use your web browser or
example,

/opt/orientdb/

wget

, unzip or extract the downloaded file into a directory convenient for your use, (for

on Linux). This creates a directory called orientdb-community-2.2.23 with relevant files and scripts, which

you will need to run OrientDB on your system.

18

Installation

Source Code Installation
In addition to downloading the binary packages, you also have the option of compiling OrientDB from the Community Edition source
code, available on GitHub. This process requires that you install Git and Apache M aven on your system.
To compile OrientDB from source code, clone the Community Edition repository, then run M aven (

mvn

) in the newly created

directory:
$ git clone https://github.com/orientechnologies/orientdb
$ git checkout develop
$ cd orientdb
$ mvn clean install

It is possible to skip tests:
$ mvn clean install -DskipTests

The develop branch contains code for the next version of OrientDB. Stable versions are tagged on master branch. For each maintained
version OrientDB has its own

hotfix

branch. As the time of writing this notes, the state of branches is:

develop: work in progress for next 3.0.x release (3.0.x-SNAPSHOT)
2.2.x: hot fix for next 2.2.x stable release (2.2.x-SNAPSHOT)
2.1.x: hot fix for next 2.1.x stable release (2.1.x-SNAPSHOT)
2.0.x: hot fix for next 2.0.x stable release (2.0.x-SNAPSHOT)
last tag on master is 2.2.0
The build process installs all jars in the local maven repository and creates archives under the

distribution

module inside the

target

directory. At the time of writing, building from branch 2.1.x gave:
$ls -l distribution/target/
total 199920
1088 26 Jan 09:57 archive-tmp
102 26 Jan 09:57 databases
102 26 Jan 09:57 orientdb-community-2.2.1-SNAPSHOT.dir
48814386 26 Jan 09:57 orientdb-community-2.2.1-SNAPSHOT.tar.gz
53542231 26 Jan 09:58 orientdb-community-2.2.1-SNAPSHOT.zip
$

The directory

orientdb-community-2.2.1-SNAPSHOT.dir

contains the OrientDB distribution uncompressed. Take a look to Contribute to

OrientDB if you want to be involved.

Update Permissions
For Linux, M ac OS X and UNIX-based operating system, you need to change the permissions on some of the files after compiling from
source.
$ chmod 755 bin/*.sh
$ chmod -R 777 config

These commands update the execute permissions on files in the

config/

directory and shell scripts in

bin/

, ensuring that you can

run the scripts or programs that you've compiled.

Post-installation Tasks
For desktop users installing the binary, OrientDB is now installed and can be run through shell scripts found in the package

bin

directory of the installation. For servers, there are some additional steps that you need to take in order to manage the database server for
OrientDB as a service. The procedure for this varies, depending on your operating system.
Install as Service on Unix, Linux and M ac OS X
Install as Service on M icrosoft Windows

19

Installation

Upgrading
When the time comes to upgrade to a newer version of OrientDB, the methods vary depending on how you chose to install it in the first
place. If you installed from binary downloads, repeat the download process above and update any symbolic links or shortcuts to point
to the new directory.
For systems where OrientDB was built from source, pull down the latest source code and compile from source.
$ git pull origin master
$ mvn clean install

Bear in mind that when you build from source, you can switch branches to build different versions of OrientDB using Git. For example,
$ git checkout 2.2.x
$ mvn clean install

builds the

2.2.x

branch, instead of

master

.

Building a single executable jar with OrientDB
OrientDB for internal components like engines, operators, factories uses Java SPI Service Provider Interface. That means that the jars of
OrientDB are shipped with files in

META-INF/services

that contains the implementation of components. Bear in mind that when

building a single executable jar, you have to concatenate the content of files with the same name in different orientdb-*.jar . If you are
using M aven Shade Plugin you can use Service Resource Transformer to do that.

Other Resources
To learn more about how to install OrientDB on specific environments, please refer to the guides below:
Install with Docker
Install with Ansible
Install on Linux Ubuntu
Install on JBoss AS
Install on GlassFish
Install on Ubuntu 12.04 VPS (DigitalOcean)
Install on Vagrant

20

Run the server

Running the OrientDB Server
When you finish installing OrientDB, whether you build it from source or download the binary package, you are ready to launch the
database server. You can either start it through the system daemon or through the provided server script. This article only covers the
latter.
Note: If you would like to run OrientDB as a service on your system, there are some additional steps that you need to take. This
provides alternate methods for starting the server and allows you to launch it as a daemon when your system boots. For more
information on this process see:
Install OrientDB as a Service on Unix, Linux and M ac OS X
Install OrientDB as a Service on M icrosoft Windows

Starting the Database Server
While you can run the database server as system daemon, you also have the option of starting it directly. In the OrientDB installation
directory, (that is

$ORIENTDB_HOME

), under

bin

, there is a file named

server.sh

on Unix-based systems and

server.bat

on

Windows. Executing this file starts the server.
To launch the OrientDB database server, run the following commands:

21

Run the server

$

cd $ORIENTDB_HOME/bin

$

./server.sh

.
.`
,

`
`:.

`,`
.,.
.,,

,:`
:,,
,,,

.

.,.:::::

,`

.::,,,,::.,,,,,,`;;

````

`,.

::,,,,,,,:.,,.`

,,:,:,,,,,,,,::.

`

.:

`

`

,,:.,,,,,,,,,: `::, ,,

`

.:
``

::,::`

,:,,,,,,,,,,::,:

,,

:.

:,,,,,,,,,,:,::

,,

:

:,,,,,,,,,,:,::,

:

: :,::`

::::

::

:

.:

:

:

:

.:

,, .::::::::

:

:

.:

:

:

.:

`,...,,:,,,,,,,,,: .:,. ,, ,,
.,,,,::,,,,,,,:

.:

`: , ,,

...,::,,,,::.. `:

.,,

,::::,,,. `:

,,

:

`

:

:

.:

:,

:

:

:

.:

:

:

.:

:::::

,,:` `,,.
,,,
,,.
``

.,`
`,

S E R V E R

`.
``
`

2012-12-28 01:25:46:319 INFO Loading configuration from: config/orientdb-serverconfig.xml... [OServerConfigurationLoaderXml]
2012-12-28 01:25:46:625 INFO OrientDB Server v1.6 is starting up... [OServer]
2012-12-28 01:25:47:142 INFO -> Loaded memory database 'temp' [OServer]
2012-12-28 01:25:47:289 INFO Listening binary connections on 0.0.0.0:2424
[OServerNetworkListener]
2012-12-28 01:25:47:290 INFO Listening http connections on 0.0.0.0:2480
[OServerNetworkListener]
2012-12-28 01:25:47:317 INFO OrientDB Server v1.6 is active. [OServer]

The database server is now running. It is accessible on your system through ports

2424

and

2480

. At the first startup the server will

ask for the root user password. The password is stored in the config file.

Stop the Server
On the console where the server is running a simple CTRL+c will shutdown the server.
The shutdown.sh (shutdown.bat) script could be used to stop the server:
$

cd $ORIENTDB_HOME/bin

$

./shutdown.sh -p ROOT_PASSWORD

On *nix systems a simple call to shutdown.sh will stop the server running on localhost:
$

cd $ORIENTDB_HOME/bin

$

./shutdown.sh

22

Run the server
It is possible to stop servers running on remote hosts or even on different ports on localhost:
$

cd $ORIENTDB_HOME/bin

$

./shutdown.sh -h odb1.mydomain.com -P 2424-2430 -u root -p ROOT_PASSWORD

List of params
-h | --host HOS TNAME or IP ADDRES S : the host or ip where OrientDB is running, default to localhost
-P | --ports PORT or PORT RANGE : single port value or range of ports; default to 2424-2430
-u | --user ROOT US ERNAME : root's username; deafult to root
-p | --password ROOT PAS S WORD : root's user password; mandatory
NOTE On Windows systems password is always mandatory because the script isn't able to discover the pid of the OrientDB's
process.

Server Log Messages
Following the masthead, the database server begins to print log messages to standard output. This provides you with a guide to what
OrientDB does as it starts up on your system.
1. The database server loads its configuration file from the file

$ORIENTDB_HOME/config/orientdb-server-config.xml

.

For more information on this step, see OrientDB Server.
2. The database server loads the

temp

database into memory. You can use this database for storing temporary data.

3. The database server begins listening for binary connections on port

2424

for all configured networks, (

0.0.0.0

).

4. The database server begins listening for HTTP connections on port

2480

for all configured networks, (

0.0.0.0

).

Accessing the Database Server
By default, OrientDB listens on two different ports for external connections.
Binary: OrientDB listens on port

2424

for binary connections from the console and for clients and drivers that support the

Network Binary Protocol.
HTTP: OrientDB listens on port

2480

for HTTP connections from OrientDB Studio Web Tool and clients and drivers that

support the HTTP/REST protocol, or similar tools, such as cURL.
If you would like the database server to listen at different ports or IP address, you can define these values in the configuration file
config/orientdb-server-config.xml

.

23

Run the console

Running the OrientDB Console
Once the server is running there are various methods you can use to connect to your database server to an individual databases. Two
such methods are the Network Binary and HTTP/REST protocols. In addition to these OrientDB provides a command-line interface for
connecting to and working with the database server.

Starting the OrientDB Console
In the OrientDB installation directory (that is,
console.sh

for Unix-based systems or

$ORIENTDB_HOME

console.bat

, where you installed the database) under

bin

, there is a file called

for Windows users.

To launch the OrientDB console, run the following command after you start the database server:
$

cd $ORIENTDB_HOME/bin

$

./console.sh

OrientDB console v.X.X.X (build 0) www.orientdb.com
Type 'HELP' to display all the commands supported.
Installing extensions for GREMLIN language v.X.X.X
orientdb>

The OrientDB console is now running. From this prompt you can connect to and manage any remote or local databases available to you.

Using the

HELP

Command

In the event that you are unfamiliar with OrientDB and the available commands, or if you need help at any time, you can use the
command, or type
orientdb>

?

HELP

into the console prompt.

HELP

AVAILABLE COMMANDS:
* alter class 

Alter a class in the database schema

* alter cluster  Alter class in the database schema
...

...

* help

Print this help

* exit

Close the console

For each console command available to you,

HELP

documents its basic use and what it does. If you know the particular command and

need details on its use, you can provide arguments to
orientdb>

HELP

for further clarification.

HELP SELECT

COMMAND: SELECT
- Execute a query against the database and display the results.
SYNTAX: select 
WHERE:
- : The query to execute

Connecting to Server Instances

24

Run the console
There are some console commands, such as

LIST DATABASES

or

CREATE DATABASE

, which you can only run while connected to a server

instance. For other commands, however, you must also connect to a database, before they run without error.
Before you can connect to a fresh server instance and fully control it, you need to know the root password for the database. The
root password is located in the configuration file at

config/orientdb-server-config.xml

. You can find it by searching for the

element. If you want to change it, edit the configuration file and restart the server.



...




...

With the required credentials, you can connect to the database server instance on your system, or establish a remote connection to one
running on a different machine.
orientdb>

CONNECT remote:localhost root my_root_password

Connecting to remote Server instance [remote:localhost] with user 'root'...OK

Once you have established a connection to the database server, you can begin to execute commands on that server, such as
DATABASES

and

orientdb>

CREATE DATABASE

LIST

.

LIST DATABASES

Found 1 databases:
* GratefulDeadConcerts (plocal)

To connect to this database or to a different one, use the
and password. By default, each database has an

admin

CONNECT

command from the console and specify the server URL, username,

user with a password of

admin

.

Warning: Always change the default password on production databases.
The above

LIST DATABASES

command shows a

GratefulDeadConcerts

installed on the local server. To connect to this database, run the

following command:
orientdb>

CONNECT remote:localhost/GratefulDeadConcerts admin admin

Connecting to database [remote:localhost/GratefulDeadConcerts] with user 'admin'...OK

The

CONNECT

command takes a specific syntax for its URL. That is,

remote:localhost/GratefulDeadConcerts

in the example. It has

three parts:
Protocol: The first part of the database address is the protocol the console should use in the connection. In the example, this is
remote

, indicating that it should use the TCP/IP protocol.

Address: The second part of the database address is hostname or IP address of the database server that you want the console to
connect to. In the example, this is

localhost

, since the connection is made to a server instance running on the local file system.

Database: The third part of the address is the name of the database that you want to use. In the case of the example, this is
GratefulDeadConcerts

.

For more detailed information about the commands, see Console Commands.

25

Run the console
Note: The OrientDB distribution comes with the bundled database

GratefulDeadConcerts

which represents the Graph of the

Grateful Dead's concerts. This database can be used by anyone to start exploring the features and characteristics of OrientDB.

26

Run the Studio

Run the Studio
If you're more comfortable interacting with database systems through a graphical interface then you can accomplish the most common
database tasks with OrientDB Studio, the web interface.

Connecting to Studio
By default, there are no additional steps that you need to take to start OrientDB Studio. When you launch the Server, whether through
the start-up script
$

server.sh

or as a system daemon, the Studio web interface opens automatically with it.

firefox http://localhost:2480

27

Run the Studio

From here you can create a new database, connect to or drop an existing database, import a public database and navigate to the Server
management interface.
For more information on the OrientDB Studio, see Studio.

28

Classes

Classes
M ulti-model support in the OrientDB engine provides a number of ways in approaching and understanding its basic concepts. These
concepts are clearest when viewed from the perspective of the Document Database API. Like many database management systems,
OrientDB uses the Record as an element of storage. There are many types of records, but with the Document Database API, records
always use the Document type. Documents are formed by a set of key/value pairs, referred to as fields and properties, and can belong to
a class.
The Class is a concept drawn from the Object-oriented programming paradigm. It is a type of data model that allows you to define
certain rules for records that belong to it. In the traditional Document database model, it is comparable to the collection, while in the
Relational database model it is comparable to the table.
For more information on classes in general, see Wikipedia.
To list all the configured classes on your system, use the
orientdb>

CLASSES

command in the console:

CLASSES

CLASSES:
-------------------+------------+----------+-----------+
NAME

| SUPERCLASS |CLUSTERS

| RECORDS

|

-------------------+------------+----------+-----------+
AbstractPerson

|

| -1

|

0 |

Account

|

| 11

|

1126 |

Actor

|

| 91

|

3 |

Address

|

| 19

|

166 |

Animal

|

| 17

|

0 |

....

| ....

| ....

|

.... |

Whiz

|

| 14

|

1001 |

-------------------+------------+----------+-----------+
TOTAL

22775 |

-------------------------------------------------------+

Working with Classes
In order to start using classes with your own applications, you need to understand how to create and configure a class for use. The class
in OrientDB is similar to the table in relational databases, but unlike tables, classes can be schema-less, schema-full or mixed. A class can
inherit properties from other classes thereby creating trees of classes (though the super-class relationship).
Each class has its own cluster or clusters, (created by default, if none are defined). For now we should know that a cluster is a place
where a group of records are stored. We'll soon see how

clustering

improves performance of querying the database.

For more information on classes in OrientDB, see Class.
To create a new class, use the
orientdb>

CREATE CLASS

command:

CREATE CLASS Student

Class created successfully. Total classes in database now: 92

This creates a class called
cluster called

student

now displayed in the

Student

. Given that no cluster was defined in the

CREATE CLASS

command, OrientDB creates a default

, to contain records assigned to this class. For the moment, the class has no records or properties tied to it. It is
CLASSES

listings.

Adding Properties to a Class

29

Classes
As mentioned above, OrientDB does allow you to work in a schema-less mode. That is, it allows you to create classes without defining
their properties. However, in the event that you would like to define indexes or constraints for your class, properties are mandatory.
Following the comparison to relational databases, if classes in OrientDB are similar to tables, properties are the columns on those tables.
To create new properties on
orientdb>

Student

, use the

CREATE PROPERTY

command in the console:

CREATE PROPERTY Student.name STRING

Property created successfully with id=1

orientdb>

CREATE PROPERTY Student.surname STRING

Property created successfully with id=2

orientdb>

CREATE PROPERTY Student.birthDate DATE

Property created successfully with id=3

These commands create three new properties on the

Student

class to provide you with areas to define the individual student's name,

surname and date of birth.

Displaying Class Information
On occasion, you may need to reference a particular class to see what clusters it belongs to and any properties configured for its use.
Using the

INFO CLASS

command, you can display information on the current configuration and properties of a class.

To display information on the class
orientdb>

Student

, use the

INFO CLASS

command:

INFO CLASS Student

Class................: Student
Default cluster......: student (id=96)
Supported cluster ids: [96]
Properties:
-----------+--------+--------------+-----------+----------+----------+-----+-----+
NAME

| TYPE

| LINKED TYPE/ | MANDATORY | READONLY | NOT NULL | MIN | MAX |

|

| CLASS

|

|

|

|

|

|

-----------+--------+--------------+-----------+----------+----------+-----+-----+
birthDate | DATE

| null

| false

| false

| false

|

|

|

name

| STRING | null

| false

| false

| false

|

|

|

surname

| STRING | null

| false

| false

| false

|

|

|

-----------+--------+--------------+-----------+----------+----------+-----+-----+

Adding Constraints to Properties
Constraints create limits on the data values assigned to properties. For instance, the type, the minimum or maximum size of, whether or
not a value is mandatory or if null values are permitted to the property.
To add a constraint, use the
orientdb>

ALTER PROPERTY

command:

ALTER PROPERTY Student.name MIN 3

Property updated successfully

30

Classes
This command adds a constraint to

Student

on the

name

property. It sets it so that any value given to this class and property must

have a minimum of three characters.

Viewing Records in a Class
Classes contain and define records in OrientDB. You can view all records that belong to a class using the
data belonging to a particular record with the
In the above examples, you created a

Student

orientdb>

OUser

command and

command.

DISPLAY RECORD

class and defined the schema for records that belong to that class, but you did not create

these records or add any data. As a result, running these commands on the
below, consider the

BROWSE CLASS

Student

class returns no results. Instead, for the examples

class.

INFO CLASS OUser

CLASS 'OUser'
Super classes........: [OIdentity]
Default cluster......: ouser (id=5)
Supported cluster ids: [5]
Cluster selection....: round-robin
Oversize.............: 0.0
PROPERTIES
----------+---------+--------------+-----------+----------+----------+-----+-----+
NAME

| TYPE

| LINKED TYPE/ | MANDATORY | READONLY | NOT NULL | MIN | MAX |

|

| CLASS

|

|

|

|

|

|

----------+---------+--------------+-----------+----------+----------+-----+-----+
password | STRING

| true

| false

| true

|

|

|

roles

| LINKSET | ORole

| null

| false

| false

| false

|

|

|

name

| STRING

| null

| true

| false

| true

|

|

|

status

| STRING

| null

| true

| false

| true

|

|

|

----------+---------+--------------+-----------+----------+----------+-----+-----+
INDEXES (1 altogether)
-------------------------------+----------------+
NAME

| PROPERTIES

|

-------------------------------+----------------+
OUser.name

| name

|

-------------------------------+----------------+

OrientDB ships with a number of default classes, which it uses in configuration and in managing data on your system, (the classes with
the

O

prefix shown in the

CLASSES

To see records assigned to the
orientdb>

command output). The

OUser

class, run the

OUser

BROWSE CLASS

class defines the users on your database.

command:

BROWSE CLASS OUser

---+------+-------+--------+-----------------------------------+--------+-------+
# | @RID | @Class| name

| password

| status | roles |

---+------+-------+--------+-----------------------------------+--------+-------+
0 | #5:0 | OUser | admin

| {SHA-256}8C6976E5B5410415BDE90... | ACTIVE | [1]

|

1 | #5:1 | OUser | reader | {SHA-256}3D0941964AA3EBDCB00EF... | ACTIVE | [1]

|

2 | #5:2 | OUser | writer | {SHA-256}B93006774CBDD4B299389... | ACTIVE | [1]

|

---+------+-------+--------+-----------------------------------+--------+-------+

31

Classes

In the example, you are listing all of the users of the database. While this is fine for your initial setup and as an
example, it is not particularly secure. To further improve security in production environments, see Security.

When you run

BROWSE CLASS

, the first column in the output provides the identifier number, which you can use to display detailed

information on that particular record.
To show the first record browsed from the
orientdb>

OUser

class, run the

DISPLAY RECORD

command:

DISPLAY RECORD 0

------------------------------------------------------------------------------+
Document - @class: OUser

@rid: #5:0

@version: 1

|

----------+-------------------------------------------------------------------+
Name | Value

|

----------+-------------------------------------------------------------------+
name | admin

|

password | {SHA-256}8C6976E5B5410415BDE908BD4DEE15DFB167A9C873F8A81F6F2AB... |
status | ACTIVE

|

roles | [#4:0=#4:0]

|

----------+-------------------------------------------------------------------+

Bear in mind that this command references the last call of

BROWSE CLASS

. You can continue to display other records, but you cannot

display records from another class until you browse that particular class.

32

Clusters

Clusters
The Cluster is a place where a group of records are stored. Like the Class, it is comparable with the collection in traditional document
databases, and in relational databases with the table. However, this is a loose comparison given that unlike a table, clusters allow you to
store the data of a class in different physical locations.
To list all the configured clusters on your system, use the
orientdb>

CLUSTERS

command in the console:

CLUSTERS

CLUSTERS:
-------------+------+-----------+-----------+
NAME

| ID

| TYPE

| RECORDS

|

-------------+------+-----------+-----------+
account

| 11

| PHYSICAL

|

actor

| 91

| PHYSICAL

|

1107 |
3 |

address

| 19

| PHYSICAL

|

166 |

animal

| 17

| PHYSICAL

|

0 |

animalrace

| 16

| PHYSICAL

|

2 |

....

| .... | ....

|

.... |

-------------+------+-----------+-----------+
TOTAL

23481 |

--------------------------------------------+

Understanding Clusters
By default, OrientDB creates one cluster for each Class. Starting from v2.2, OrientDB automatically creates multiple clusters per each
class (the number of clusters created is equals to the number of CPU's cores available on the server) to improve using of parallelism. All
records of a class are stored in the same cluster, which has the same name as the class. You can create up to 32,767 (or, 215 - 1) clusters
in a database. Understanding the concepts of classes and clusters allows you to take advantage of the power of clusters in designing new
databases.
While the default strategy is that each class maps to one cluster, a class can rely on multiple clusters. For instance, you can spawn
records physically in multiple locations, thereby creating multiple clusters.

Here, you have a class
USA_customers

Customer

that relies on two clusters:

, which is a cluster that contains all customers in the United States.

China_customers

, which is a cluster that contains all customers in China.

In this deployment, the default cluster is

USA_customers

. Whenever commands are run on the

Customer

class, such as

INSERT

statements, OrientDB assigns this new data to the default cluster.

33

Clusters

The new entry from the

INSERT

statement is added to the

USA_customers

cluster, given that it's the default. Inserting data into a non-

default cluster would require that you specify the cluster you want to insert the data into in your statement.
When you run a query on the

Customer

class, such as

SELECT

queries, for instance:

OrientDB scans all clusters associated with the class in looking for matches.
In the event that you know the cluster in which the data is stored, you can query that cluster directly to avoid scanning all others and
optimize the query.

34

Clusters

Here, OrientDB only scans the

China_customers

cluster of the

Customer

class in looking for matches

Note: The method OrientDB uses to select the cluster, where it inserts new records, is configurable and extensible. For more
information, see Cluster Selection.

Working with Clusters
While running in HA mode, upon the creation of a new record (document, vertex, edge, etc.) the coordinator server automatically assigns
the cluster among the list of local clusters for the current server. For more information look at HA: Cluster Ownership.
You may also find it beneficial to locate different clusters on different servers, physically separating where you store records in your
database. The advantages of this include:
Optimization Faster query execution against clusters, given that you need only search a subset of the clusters in a class.
Indexes With good partitioning, you can reduce or remove the use of indexes.
Parallel Queries: Queries can be run in parallel when made to data on multiple disks.
S harding: You can shard large data-sets across multiple instances.

Adding Clusters
When you create a class, OrientDB creates a default cluster of the same name. In order for you to take advantage of the power of
clusters, you need to create additional clusters on the class. This is done with the
ADDCLUSTER

ALTER CLASS

statement in conjunction with the

parameter.

To add a cluster to the
orientdb>

Customer

class, use an

ALTER CLASS

statement in the console:

ALTER CLASS Customer ADDCLUSTER UK_Customers

Class updated successfully

You now have a third cluster for the

Customer

class, covering those customers located in the United Kingdom.

Viewing Records in a Cluster
Clusters store the records contained by a class in OrientDB. You can view all records that belong to a cluster using the
command and the data belonging to a particular record with the

DISPLAY RECORD

BROWSE CLUSTER

command.

35

Clusters
In the above example, you added a cluster to a class for storing records customer information based on their locations around the world,
but you did not create these records or add any data. As a result, running these commands on the
Instead, for the examples below, consider the

ouser

Customer

class returns no results.

cluster.

OrientDB ships with a number of default clusters to store data from its default classes. You can see these using the
command. Among these, there is the
To see records stored in the
orientdb>

ouser

ouser

CLUSTERS

cluster, which stores data of the users on your database.

cluster, run the

BROWSE CLUSTER

command:

BROWSE CLUSTER OUser

---+------+--------+--------+----------------------------------+--------+-------+
# | @RID | @CLASS | name

| password

| status | roles |

---+------+-------+--------+-----------------------------------+--------+-------+
0 | #5:0 | OUser | admin

| {SHA-256}8C6976E5B5410415BDE90... | ACTIVE | [1]

|

1 | #5:1 | OUser | reader | {SHA-256}3D0941964AA3EBDCB00CC... | ACTIVE | [1]

|

2 | #5:2 | OUser | writer | {SHA-256}B93006774CBDD4B299389... | ACTIVE | [1]

|

---+------+--------+--------+----------------------------------+--------+-------+

The results are identical to executing

BROWSE CLASS

on the

OUser

class, given that there is only one cluster for the

OUser

class in this

example.

In the example, you are listing all of the users of the database. While this is fine for your initial setup and as an
example, it is not particularly secure. To further improve security in production environments, see Security.

When you run

BROWSE CLUSTER

, the first column in the output provides the identifier number, which you can use to display detailed

information on that particular record.
To show the first record browsed from the
orientdb>

ouser

cluster, run the

DISPLAY RECORD

command:

DISPLAY RECORD 0

------------------------------------------------------------------------------+
Document - @class: OUser

@rid: #5:0

@version: 1

|

----------+-------------------------------------------------------------------+
Name | Value

|

----------+-------------------------------------------------------------------+
name | admin

|

password | {SHA-256}8C6976E5B5410415BDE908BD4DEE15DFB167A9C873F8A81F6F2AB... |
status | ACTIVE

|

roles | [#4:0=#4:0]

|

----------+-------------------------------------------------------------------+

Bear in mind that this command references the last call of

BROWSE CLUSTER

. You can continue to display other records, but you cannot

display records from another cluster until you browse that particular cluster.

36

Record ID

Record ID
In OrientDB, each record has its own self-assigned unique ID within the database called Record ID or RID. It is composed of two parts:
#:

That is,


The cluster identifier.



The position of the data within the cluster.

Each database can have a maximum of 32,767 clusters, or 215 - 1. Each cluster can handle up to 9,223,372,036,780,000 records, or 263,
namely 9,223,372 trillion records.
The maximum size of a database is 278 records, or 302,231,454,903 trillion records. Due to limitations in hardware resources,
OrientDB has not been tested at such high numbers, but there are users working with OrientDB in the billions of records range.

Loading Records
Each record has a Record ID, which notes the physical position of the record inside the database. What this means is that when you load
a record by its RID, the load is significantly faster than it would be otherwise.
In document and relational databases, the more data that you have, the slower the database responds. OrientDB handles relationships as
physical links to the records. The relationship is assigned only once, when the edge is created
databases, which compute the relationship every time the database is run

O(log N)

O(1)

. You can compare this to relational

. In OrientDB, the size of a database does not effect

the traverse speed. The speed remains constant, whether for one record or one hundred billion records. This is a critical feature in the age
of Big Data.
To directly load a record, use the
orientdb>

LOAD RECORD

command in the console.

LOAD RECORD #12:4

-------------------------------------------------------ODocument - @class: Company

@rid: #12:4

@version: 8

-------------+-----------------------------------------Name | Value
-------------+-----------------------------------------addresses | [NOT LOADED: #19:159]
salary | 0.0
employees | 100004
id | 4
name | Microsoft4
initialized | false
salary2 | 0.0
checkpoint | true
created | Sat Dec 29 23:13:49 CET 2012
-------------+------------------------------------------

The

LOAD RECORD

command returns some useful information about this record. It shows:

that it is a document. OrientDB supports different types of records, but document is the only type covered in this chapter.
that it belongs to the

Company

that its current version is

8

class.

. OrientDB uses an M VCC system. Every time you update a record, its version increments by one.

37

Record ID
that we have different field types: floats in
for

initialized

that the field

and

checkpoint

addresses

has been

salary

and

, and date-time for
NOT LOADED

salary2

created

. It is also a

, integers for

employees

and

id

, string for

name

, booleans

.

LINK

to another record,

#19:159

. This is a relationship. For more

information on this concept, see Relationships.

38

Relationships

Relationships
One of the most important features of Graph databases lies in how they manage relationships. M any users come to OrientDB from
M ongoDB due to OrientDB having more efficient support for relationships.

Relations in Relational Databases
M ost database developers are familiar with the Relational model of databases and with relational database management systems, such as
M ySQL and M S-SQL. Given its more than thirty years of dominance, this has long been thought the best way to handle relationships.
By contrast, Graph databases suggest a more modern approach to this concept.
Consider, as an example, a database where you need to establish relationships between

Customer

and

Address

tables.

1-to-1 Relationship
Relational databases store the value of the target record in the

address

foreign key points to the Primary Key of the related record in the

row of the

Address

Customer

table. This is the Foreign Key. The

table.

Consider a case where you want to view the address of a customer named Luca. In a Relational database, like M ySQL, this is how you
would query the table:
mysql>

SELECT B.location FROM Customer A, Address B
WHERE A.name='Luca' AND A.address=B.id;

What happens here is a

JOIN

. That is, the contents of two tables are joined to form the results. The database executes the

JOIN

every

time you retrieve the relationship.

1-to-Many Relationship
Given that Relational databases have no concept of a collections, the

Customer

table cannot have multiple foreign keys. The only way

to manage a 1-to-M any Relationship in databases of this kind is to move the Foreign Key to the

Address

table.

39

Relationships

For example, consider a case where you want to return all addresses connected to the customer Luca, this is how you would query the
table:
mysql>

SELECT B.location FROM Customer A, Address B
WHERE A.name='Luca' AND B.customer=A.id;

Many-to-Many relationship
The most complicated case is the M any-to-M any relationship. To handle associations of this kind, Relational databases require a
separate, intermediary table that matches rows from both
double

JOIN

Customer

and

Address

tables in all required combinations. This results in a

per record at runtime.

For example, consider a case where you want to return all address for the customer Luca, this is how you would query the table:
mysql>

SELECT C.location FROM Customer A, CustomerAddress B, Address C
WHERE A.name='Luca' AND B.id=A.id AND B.address=C.id;

Understanding

JOIN

40

Relationships
In document and relational database systems, the more data that you have, the slower the database responds and

JOIN

operations have

a heavy runtime cost.
For relational database systems, the database computes the relationship every time you query the server. That translates to
block_size)

That is,

O(log N /

. OrientDB handles relationships as physical links to the records and assigns them only once, when the edge is created.

O(1)

.

In OrientDB, the speed of traversal is not affected by the size of the database. It is always constant regardless of whether it has one
record or one hundred billion records. This is a critical feature in the age of Big Data.
Searching for an identifier at runtime each time you execute a query, for every record will grow very expensive. The first optimization
with relational databases is the use of indexing. Indexes speed up searches, but they slow down

INSERT

,

UPDATE

, and

DELETE

operations. Additionally, they occupy a substantial amount of space on the disk and in memory.
Consider also whether searching an index is actually fast.

Indexes and JOIN
In the database industry, there are a number of indexing algorithms available. The most common in both relational and NoSQL database
systems is the B+ Tree.
Balance trees all work in a similar manner. For example, consider a case where you're looking for an entry with the name

Luca

: after

only five hops, the record is found.

While this is fine on a small database, consider what would happen if there were millions or billions of records. The database would have
to go through many, many more hops to find

Luca

. And, the database would execute this operation on every

Picture: joining four tables with thousands of records. The number of

JOIN

JOIN

per record.

operations could run in the millions.

Relations in OrientDB
There is no

JOIN

in OrientDB. Instead, it uses

LINK

.

LINK

is a relationship managed by storing the target Record ID in the source

record. It is similar to storing the pointer between two objects in memory.
When you have

Invoice

linked to

Customer

, then you have a pointer to

Customer

inside

Invoice

as an attribute. They are exactly

the same. In this way, it's as though your database was kept in memory: a memory of several exabytes.

Types of Relationships
In 1-to-N relationships, OrientDB handles the relationship as a collection of Record ID's, as you would when managing objects in
memory.

41

Relationships
OrientDB supports several different kinds of relationships:
LINK

Relationship that points to one record only.

LINKSET

Relationship that points to several records. It is similar to Java sets, the same Record ID can only be included once. The

pointers have no order.
LINKLIST
LINKMAP

Relationship that points to several records. It is similar to Java lists, they are ordered and can contain duplicates.
Relationship that points to several records with a key stored in the source record. The M ap values are the Record ID's.

It is similar to Java

Map

.

42

Basic SQL

SQL
M ost NoSQL products employ a custom query language. In this, OrientDB differs by focusing on standards in query languages. That is,
instead of inventing "Yet Another Query Language," it begins with the widely used and well-understood language of SQL. It then
extends SQL to support more complex graphing concepts, such as Trees and Graphs.
Why SQL? Because SQL is ubiquitous in the database development world. It is familiar and more readable and concise than its
competitors, such as M ap Reduce scripts or JSON based querying.

SELECT
The

statement queries the database and returns results that match the given parameters. For instance, earlier in Getting Started,

SELECT

two queries were presented that gave the same results:
available through a
orientdb>

SELECT

BROWSE CLUSTER ouser

and

BROWSE CLASS OUser

. Here is a third option,

statement.

SELECT FROM OUser

Notice that the query has no projections. This means that you do not need to enter a character to indicate that the query should return
the entire record, such as the asterisk in the Relational model, (that is,

SELECT * FROM OUser

).

Additionally, OUser is a class. By default, OrientDB executes queries against classes. Targets can also be:
Clusters To execute against a cluster, rather than a class, prefix
orientdb>

CLUSTER

to the target name.

SELECT FROM CLUSTER:Ouser

Record ID To execute against one or more Record ID's, use the identifier(s) as your target. For example.
orientdb>

SELECT FROM #10:3

orientdb>

SELECT FROM [#10:1, #10:30, #10:5]

Indexes To execute a query against an index, prefix
orientdb>

INDEX

to the target name.

SELECT VALUE FROM INDEX:dictionary WHERE key='Jay'

WHERE
M uch like the standard implementation of SQL, OrientDB supports
orientdb>

This returns all
WHERE

WHERE

conditions to filter the returning records too. For example,

SELECT FROM OUser WHERE name LIKE 'l%'

OUser

records where the name begins with

l

. For more information on supported operators and functions, see

.

ORDER BY
In addition to

WHERE

, OrientDB also supports

ORDER BY

clauses. This allows you to order the results returned by the query according

to one or more fields, in either ascending or descending order.
orientdb>

SELECT FROM Employee WHERE city='Rome' ORDER BY surname ASC, name ASC

The example queries the

Employee

class, it returns a listing of all employees in that class who live in Rome and it orders the results by

surname and name, in ascending order.

43

Basic SQL

GROUP BY
In the event that you need results of the query grouped together according to the values of certain fields, you can manage this using the
GROUP BY

clause.

orientdb>

SELECT SUM(salary) FROM Employee WHERE age < 40 GROUP BY job

In the example, you query the

Employee

class for the sum of the salaries of all employees under the age of forty, grouped by their job

types.

LIMIT
In the event that your query returns too many results, making it difficult to read or manage, you can use the

LIMIT

clause to reduce it

to the top most of the return values.
orientdb>

SELECT FROM Employee WHERE gender='male' LIMIT 20

In the example, you query the

Employee

class for a list of male employees. Given that there are likely to be a number of these, you

limit the return to the first twenty entries.

SKIP
When using the

LIMIT

clause with queries, you can only view the topmost of the return results. In the event that you would like to

view certain results further down the list, for instance the values from twenty to forty, you can paginate your results using the
keyword in the

LIMIT

SKIP

clause.

orientdb>

SELECT FROM Employee WHERE gender='male' LIMIT 20

orientdb>

SELECT FROM Employee WHERE gender='male' SKIP 20 LIMIT 20

orientdb>

SELECT FROM Employee WHERE gender='male' SKIP 40 LIMIT 20

The first query returns the first twenty results, the second returns the next twenty results, the third up to sixty. You can use these
queries to manage pages at the application layer.

INSERT
The

INSERT

statement adds new data to a class and cluster. OrientDB supports three forms of syntax used to insert new data into your

database.
The standard ANSI-93 syntax:
orientdb>

INSERT INTO

Employee(name, surname, gender)

VALUES('Jay', 'Miner', 'M')

The simplified ANSI-92 syntax:
orientdb>

INSERT INTO Employee SET name='Jay', surname='Miner', gender='M'

The JSON syntax:
orientdb>

INSERT INTO Employee CONTENT {name : 'Jay', surname : 'Miner',

gender : 'M'}

Each of these queries adds Jay M iner to the

Employee

class. You can choose whichever syntax that works best with your application.

44

Basic SQL

UPDATE
The

UPDATE

statement changes the values of existing data in a class and cluster. In OrientDB there are two forms of syntax used to

update data on your database.
The standard ANSI-92 syntax:
orientdb>

UPDATE Employee SET local=TRUE WHERE city='London'

The JSON syntax, used with the
orientdb>

MERGE

keyword, which merges the changes with the current record:

UPDATE Employee MERGE { local : TRUE } WHERE city='London'

Each of these statements updates the

Employee

class, changing the

local

property to

TRUE

when the employee is based in London.

DELETE
The

DELETE

statement removes existing values from your class and cluster. OrientDB supports the standard ANSI-92 compliant

syntax for these statements:
orientdb>

DELETE FROM Employee WHERE city <> 'London'

Here, entries are removed from the

Employee

class where the employee in question is not based in London.

S ee also:
The SQL Reference
The Console Command Reference

45

Working with Graphs

Working with Graphs
In graph databases, the database system graphs data into network-like structures consisting of vertices and edges. In the OrientDB
Graph model, the database represents data through the concept of a property graph, which defines a vertex as an entity linked with
other vertices and an edge, as an entity that links two vertices.
OrientDB ships with a generic vertex persistent class, called
new vertex using the
orientdb>

INSERT

command with

V

V

, as well as a class for edges, called

E

. As an example, you can create a

.

INSERT INTO V SET name='Jay'

Created record with RID #9:0

In effect, the Graph model database works on top of the underlying document model. But, in order to simplify this process, OrientDB
introduces a new set of commands for managing graphs from the console. Instead of
orientdb>

INSERT

, use

CREATE VERTEX

CREATE VERTEX V SET name='Jay'

Created vertex with RID #9:1

By using the graph commands over the standard SQL syntax, OrientDB ensures that your graphs remain consistent. For more
information on the particular commands, see the following pages:
CREATE VERTEX
DELETE VERTEX
CREATE EDGE
UPDATE EDGE
DELETE EDGE

Use Case: Social Network for Restaurant Patrons
While you have the option of working with vertexes and edges in your database as they are, you can also extend the standard
E

V

and

classes to suit the particular needs of your application. The advantages of this approach are,
It grants better understanding about the meaning of these entities.
It allows for optional constraints at the class level.
It improves performance through better partitioning of entities.
It allows for object-oriented inheritance among the graph elements.

For example, consider a social network based on restaurants. You need to start with a class for individual customers and another for the
restaurants they patronize. Create these classes to extend the
orientdb>

CREATE CLASS Person EXTENDS V

orientdb>

CREATE CLASS Restaurant EXTENDS V

V

class.

Doing this creates the schema for your social network. Now that the schema is ready, populate the graph with data.

46

Working with Graphs

orientdb>

CREATE VERTEX Person SET name='Luca'

Created record with RID #11:0

orientdb>

CREATE VERTEX Person SET name='Bill'

Created record with RID #11:1

orientdb>

CREATE VERTEX Person SET name='Jay'

Created record with RID #11:2

orientdb>

CREATE VERTEX Restaurant SET name='Dante', type='Pizza'

Created record with RID #12:0

orientdb>

CREATE VERTEX Restaurant SET name='Charlie', type='French'

Created record with RID #12:1

This adds three vertices to the
Restaurant

Person

class, representing individual users in the social network. It also adds two vertices to the

class, representing the restaurants that they patronize.

Creating Edges
For the moment, these vertices are independent of one another, tied together only by the classes to which they belong. That is, they are
not yet connected by edges. Before you can make these connections, you first need to create a class that extends
orientdb>

.

CREATE CLASS Eat EXTENDS E

This creates the class
Restaurant

E

Eat

, which extends the class

E

.

Eat

represents the relationship between the vertex

Person

and the vertex

.

When you create the edge from this class, note that the orientation of the vertices is important, because it gives the relationship its
meaning. For instance, creating an edge in the opposite direction, (from
as

Attendee

Restaurant

to

Person

), would call for a separate class, such

.

The user Luca eats at the pizza joint Dante. Create an edge that represents this connection:
orientdb>

CREATE EDGE Eat FROM ( SELECT FROM Person WHERE name='Luca' )

TO ( SELECT FROM Restaurant WHERE name='Dante' )

Creating Edges from Record ID
In the event that you know the Record ID of the vertices, you can connect them directly with a shorter and faster command. For
example, the person Bill also eats at the restaurant Dante and the person Jay eats at the restaurant Charlie. Create edges in the class
Eat

to represent these connections.

orientdb>

CREATE EDGE Eat FROM #11:1 TO #12:0

orientdb>

CREATE EDGE Eat FROM #11:2 TO #12:1

47

Working with Graphs

Querying Graphs
In the above example you created and populated a small graph of a social network of individual users and the restaurants at which they
eat. You can now begin to experiment with queries on a graph database.
To cross edges, you can use special graph functions, such as:
To retrieve the adjacent outgoing vertices

OUT()
IN()

To retrieve the adjacent incoming vertices
To retrieve the adjacent incoming and outgoing vertices

BOTH()

For example, to know all of the people who eat in the restaurant Dante, which has a Record ID of
that restaurant and traverse the incoming edges to discover which entries in the
orientdb>

Person

#12:0

, you can access the record for

class connect to it.

SELECT IN() FROM Restaurant WHERE name='Dante'

-------+----------------+
@RID

| in

|

-------+----------------+
#-2:1 | [#11:0, #11:1] |
-------+----------------+

This query displays the record ID's from the
EXPAND()

Person

class that connect to the restaurant Dante. In cases such as this, you can use the

special function to transform the vertex collection in the result-set by expanding it.

orientdb>

SELECT EXPAND( IN() ) FROM Restaurant WHERE name='Dante'

-------+-------------+-------------+---------+
@RID

| @CLASS

| Name

| out_Eat |

-------+-------------+-------------+---------+
#11:0 | Person

| Luca

| #12:0

|

#11:1 | Person

| Bill

| #12:0

|

-------+-------------+-------------+---------+

Creating Edge to Connect Users
Your application at this point shows connections between individual users and the restaurants they patronize. While this is interesting,
it does not yet function as a social network. To do so, you need to establish edges that connect the users to one another.
To begin, as before, create a new class that extends
orientdb>

E

:

CREATE CLASS Friend EXTENDS E

The users Luca and Jay are friends. They have Record ID's of
orientdb>

In the

Friend

#11:0

and

#11:2

. Create an edge that connects them.

CREATE EDGE Friend FROM #11:0 TO #11:2

relationship, orientation is not important. That is, if Luca is a friend of Jay's then Jay is a friend of Luca's. Therefore,

you should use the

BOTH()

function.

48

Working with Graphs

orientdb>

SELECT EXPAND( BOTH( 'Friend' ) ) FROM Person WHERE name = 'Luca'

-------+-------------+-------------+---------+-----------+
@RID

| @CLASS

| Name

| out_Eat | in_Friend |

-------+-------------+-------------+---------+-----------+
#11:2 | Person

| Jay

| #12:1

| #11:0

|

-------+-------------+-------------+---------+-----------+

Here, the
the

Eat

BOTH()

function takes the edge class

Friend

as an argument, crossing only relationships of the Friend kind, (that is, it skips

class, at this time). Note in the result-set that the relationship with Luca, with a Record ID of

#11:0

in the

in_

field.

You can also now view all the restaurants patronized by friends of Luca.
orientdb>

SELECT EXPAND( BOTH('Friend').out('Eat') ) FROM Person

WHERE name='Luca'

-------+-------------+-------------+-------------+--------+
@RID

| @CLASS

| Name

| Type

| in_Eat |

-------+-------------+-------------+-------------+--------+
#12:1 | Restaurant

| Charlie

| French

| #11:2

|

-------+-------------+-------------+-------------+--------+

Lightweight Edges
In version 1.4.x, OrientDB begins to manage some edges as Lightweight Edges. Lightweight Edges do not have Record ID's, but are
physically stored as links within vertices. Note that OrientDB only uses a Lightweight Edge only when the edge has no properties,
otherwise it uses the standard Edge.
From the logic point of view, Lightweight Edges are Edges in all effects, so that all graph functions work with them. This is to improve
performance and reduce disk space.
Because Lightweight Edges don't exist as separate records in the database, some queries won't work as expected. For instance,
orientdb>

SELECT FROM E

For most cases, an edge is used connecting vertices, so this query would not cause any problems in particular. But, it would not return
Lightweight Edges in the result-set. In the event that you need to query edges directly, including those with no properties, disable the
Lightweight Edge feature.
To disable the Lightweight Edge feature, execute the following command.
orientdb>

ALTER DATABASE CUSTOM useLightweightEdges=FALSE

You only need to execute this command once. OrientDB now generates new edges as the standard Edge, rather than the Lightweight
Edge. Note that this does not affect existing edges.
For troubleshooting information on Lightweight Edges, see Why I can't see all the edges. For more information in the Graph model in
OrientDB, see Graph API.

49

Using Schema with Graphs

Using Schema with Graphs
OrientDB, through the Graph API, offers a number of features above and beyond the traditional Graph Databases given that it supports
concepts drawn from both the Document Database and the Object Oriented worlds. For instance, consider the power of graphs, when
used in conjunction with schemas and constraints.

Use Case: Car Database
For this example, consider a graph database that maps the relationship between individual users and their cars. First, create the graph
schema for the

Person

and

Car

vertex classes, as well as the

orientdb>

CREATE CLASS Person EXTENDS V

orientdb>

CREATE CLASS Car EXTENDS V

orientdb>

CREATE CLASS Owns EXTENDS E

Owns

edge class to connect the two:

These commands lay out the schema for your graph database. That is, they define two vertex classes and an edge class to indicate the
relationship between the two. With that, you can begin to populate the database with vertices and edges.
orientdb>

CREATE VERTEX Person SET name = 'Luca'

Created vertex 'Person#11:0{name:Luca} v1' in 0,012000 sec(s).

orientdb>

CREATE VERTEX Car SET name = 'Ferrari Modena'

Created vertex 'Car#12:0{name:Ferrari Modena} v1' in 0,001000 sec(s).

orientdb>

CREATE EDGE Owns FROM ( SELECT FROM Person ) TO ( SELECT FROM Car )

Created edge '[e[#11:0->#12:0][#11:0-Owns->#12:0]]' in 0,005000 sec(s).

Querying the Car Database
In the above section, you create a car database and populated it with vertices and edges to map out the relationship between drivers and
their cars. Now you can begin to query this database, showing what those connections are. For example, what is Luca's car? You can find
out by traversing from the vertex Luca to the outgoing vertices following the
orientdb>

Owns

relationship.

SELECT name FROM ( SELECT EXPAND( OUT('Owns') ) FROM Person

WHERE name='Luca' )

----+-------+-----------------+
#

| @RID

| name

|

----+-------+-----------------+
0

| #-2:1 | Ferrari Modena

|

----+-------+-----------------+

As you can see, the query returns that Luca owns a Ferrari M odena. Now consider expanding your database to track where each person
lives.

50

Using Schema with Graphs

Adding a Location Vertex
Consider a situation, in which you might want to keep track of the countries in which each person lives. In practice, there are a number
of reasons why you might want to do this, for instance, for the purposes of promotional material or in a larger database to analyze the
connections to see how residence affects car ownership.
To begin, create a vertex class for the country, in which the person lives and an edge class that connects the individual to the place.
orientdb>

CREATE CLASS Country EXTENDS V

orientdb>

CREATE CLASS Lives EXTENDS E

This creates the schema for the feature you're adding to the cars database. The vertex class
people live and the edge class

Lives

to connect individuals in the vertex class

Person

Country

recording countries in which

to entries in

Country

.

With the schema laid out, create a vertex for the United Kingdom and connect it to the person Luca.
orientdb>

CREATE VERTEX Country SET name='UK'

Created vertex 'Country#14:0{name:UK} v1' in 0,004000 sec(s).

orientdb>

CREATE EDGE Lives FROM ( SELECT FROM Person ) TO ( SELECT FROM Country

Created edge '[e[#11:0->#14:0][#11:0-Lives->#14:0]]' in 0,006000 sec(s).

The second command creates an edge connecting the person Luca to the country United Kingdom. Now that your cars database is
defined and populated, you can query it, such as a search that shows the countries where there are users that own a Ferrari.
orientdb>

SELECT name FROM ( SELECT EXPAND( IN('Owns').OUT('Lives') )

FROM Car WHERE name LIKE '%Ferrari%' )

---+-------+--------+
# | @RID

| name

|

---+-------+--------+
0 | #-2:1 | UK

|

---+-------+--------+

Using in and out Constraints on Edges
In the above sections, you modeled the graph using a schema without any constraints, but you might find it useful to use some. For
instance, it would be good to require that an

Owns

relationship only exist between the vertex

orientdb>

CREATE PROPERTY Owns.out LINK Person

orientdb>

CREATE PROPERTY Owns.in LINK Car

These commands link outgoing vertices of the

Person

class to incoming vertices of the

Car

Person

and the vertex

Car

.

class. That is, it configures your database

so that a user can own a car, but a car cannot own a user.

Using MANDATORY Constraints on Edges
By default, when OrientDB creates an edge that lacks properties, it creates it as a Lightweight Edge. That is, it creates an edge that has
no physical record in the database. Using the

MANDATORY

setting, you can stop this behavior, forcing it to create the standard Edge,

without outright disabling Lightweight Edges.

51

Using Schema with Graphs

orientdb>

ALTER PROPERTY Owns.out MANDATORY TRUE

orientdb>

ALTER PROPERTY Owns.in MANDATORY TRUE

Using UNIQUE with Edges
For the sake of simplicity, consider a case where you want to limit the way people are connected to cars to where the user can only
match to the car once. That is, if Luca owns a Ferrari M odena, you might prefer not to have a double entry for that car in the event that
he buys a new one a few years later. This is particularly important given that our database covers make and model, but not year.
To manage this, you need to define a
orientdb>

UNIQUE

index against both the out and in properties.

CREATE INDEX UniqueOwns ON Owns(out,in) UNIQUE

Created index successfully with 0 entries in 0,023000 sec(s).

The index returns tells us that no entries are indexed. You have already created the

Onws

relationship between Luca and the Ferrari

M odena. In that case, however, OrientDB had created a Lightweight Edge before you set the rule to force the creation of documents for
Owns

instances. To fix this, you need to drop and recreate the edge.

orientdb>

DELETE EDGE FROM #11:0 TO #12:0

orientdb>

CREATE EDGE Owns FROM ( SELECT FROM Person ) TO ( SELECT FROM Car )

To confirm that this was successful, run a query to check that a record was created:
orientdb>

SELECT FROM Owns

---+-------+-------+--------+
# | @RID

| out

| in

|

---+-------+-------+--------+
0 | #13:0 | #11:0 | #12:0

|

---+-------+-------+--------+

This shows that a record was indeed created. To confirm that the constraints work, attempt to create an edge in

Owns

that connects

Luca to the United Kingdom.
orientdb>

CREATE EDGE Owns FROM ( SELECT FROM Person ) TO ( SELECT FROM Country )

Error: com.orientechnologies.orient.core.exception.OCommandExecutionException:
Error on execution of command: sql.create edge Owns from (select from Person)...
Error: com.orientechnologies.orient.core.exception.OValidationException: The
field 'Owns.in' has been declared as LINK of type 'Car' but the value is the
document #14:0 of class 'Country'

This shows that the constraints effectively blocked the creation, generating a set of errors to explain why it was blocked.
You now have a typed graph with constraints. For more information, see Graph Schema.

52

Setup a Distributed Database

Setting up a Distributed Graph Database
In addition to the standard deployment architecture, where it runs as a single, standalone database instance, you can also deploy
OrientDB using Distributed Architecture. In this environment, it shares the database across multiple server instances.

Launching Distributed Server Cluster
There are two ways to share a database across multiple server nodes:
Prior to startup, copy the specific database directory, under

to all servers.

$ORIENTDB_HOME/database

Keep the database on the first running server node, then start every other server node. Under the default configurations, OrientDB
automatically shares the database with the new servers that join.
This tutorial assumes that you want to start a distributed database using the second method.
NOTE: When you run in distributed mode, OrientDB needs more RAM. The minimum is 2GB of heap, but we suggest to use at least 4GB
of heap memory. To change the heap modify the Java memory settings in the file

bin/dserver.sh

(or dserver.bat on Windows).

Starting the First Server Node
Unlike the standard standalone deployment of OrientDB, there is a different script that you need to use when launching a distributed
server instance. Instead of
find it in the
$

bin

server.sh

, you use

dserver.sh

. In the case of Windows, use

dserver.bat

. Whichever you need, you can

of your installation directory.

./bin/dserver.sh

Bear in mind that OrientDB uses the same

orientdb-server-config.xml

configuration file, regardless of whether it's running as a server

or distributed server. For more information, see Distributed Configuration.
The first time you start OrientDB as a distributed server, it generates the following output:
+---------------------------------------------------------------+
|

WARNING: FIRST DISTRIBUTED RUN CONFIGURATION

|

+---------------------------------------------------------------+
| This is the first time that the server is running as

|

| distributed. Please type the name you want to assign to the

|

| current server node.

|

|

|

| To avoid this message set the environment variable or JVM

|

| setting ORIENTDB_NODE_NAME to the server node name to use.

|

+---------------------------------------------------------------+
Node name [BLANK=auto generate it]:

You need to give the node a name here. OrientDB stores it in the
your

orientdb-server-config.xml

nodeName

parameter of

OHazelcastPlugin

. It adds the variable to

configuration file.

Distributed Startup Process
When OrientDB starts as a distributed server instance, it loads all databases in the

database

directory and configures them to run in

distributed mode. For this reason, the first load, OrientDB copies the default distributed configuration, (that is, the
distributed-db-config.json

configuration file), into each database's directory, renaming it

distributed-config.json

default-

. On subsequent

starts, each database uses this file instead of the default configuration file. Since the shape of the cluster changes every time nodes join or
leave, the configuration is kept up to date by each distributed server instance.
For more information on working with the

default-distributed-db-config.json

configuration file, see Distributed Configuration.

Starting Additional Server Nodes
53

Setup a Distributed Database
When you have the first server node running, you can begin to start the other server nodes. Each server requires the same Hazelcast
credentials in order to join the same cluster. You can define these in the

hazelcast.xml

configuration file.

The fastest way to initialize multiple server nodes is to copy the OrientDB installation directory from the first node to each of the
subsequent nodes. For instance,
$

scp user@ip_address $ORIENTDB_HOME

This copies both the databases and their configuration files onto the new distributed server node.
Bear in mind, if you run multiple server instances on the same host, such as when testing, you need to change the port entry in
the

hazelcast.xml

configuration file.

For the other server nodes in the cluster, use the same

dserver.sh

command as you used in starting the first node. When the other

server nodes come online, they begin to establish network connectivity with each other. M onitoring the logs, you can see where they
establish connections from messages such as this:
WARN [node1384014656983] added new node id=Member [192.168.1.179]:2435 name=null
[OHazelcastPlugin]
INFO [192.168.1.179]:2434 [orientdb] Re-partitioning cluster data... Migration
queue size: 135 [PartitionService]
INFO [192.168.1.179]:2434 [orientdb] All migration tasks has been completed,
queues are empty. [PartitionService]
INFO [node1384014656983] added node configuration id=Member [192.168.1.179]:2435
name=node1384015873680, now 2 nodes are configured [OHazelcastPlugin]
INFO [node1384014656983] update configuration db=GratefulDeadConcerts
from=node1384015873680 [OHazelcastPlugin]
WARN [node1383734730415]->[node1384015873680] deploying database
GratefulDeadConcerts...[ODeployDatabaseTask]
WARN [node1383734730415]->[node1384015873680] sending the compressed database
GratefulDeadConcerts over the network, total 339,66Kb [ODeployDatabaseTask]

In the example, two server nodes were started on the same machine. It has an IP address of 10.37.129.2, but is using OrientDB on two
different ports: 2434 and 2435, where the current is called

this

. The remainder of the log is relative to the distribution of the database

to the second server.
On the second server node output, OrientDB dumps messages like this:
WARN [node1384015873680]<-[node1383734730415] installing database
GratefulDeadConcerts in databases/GratefulDeadConcerts... [OHazelcastPlugin]
WARN [node1384015873680] installed database GratefulDeadConcerts in
databases/GratefulDeadConcerts, setting it online... [OHazelcastPlugin]
WARN [node1384015873680] database GratefulDeadConcerts is online [OHazelcastPlugin]
WARN [node1384015873680] updated node status to 'ONLINE' [OHazelcastPlugin]
INFO OrientDB Server v2.2.11-SNAPSHOT is active. [OServer]

What these messages mean is that the database
node1383734730415

GratefulDeadConcerts

was correctly installed from the first node, that is

through the network.

Migrating from standalone server to a cluster
If you have a standalone instance of OrientDB and you want to move to a cluster you should follow these steps:
Install OrientDB on all the servers of the cluster and configure it (according to the sections above)
Stop the standalone server
Copy the specific database directories under

$ORIENTDB_HOME/database

Start all the servers in the cluster using the script

dserver.sh

(or

to all the servers of the cluster

dserver.bat

if on Windows)

54

Setup a Distributed Database
If the standalone server will be part of the cluster, you can use the existing installation of OrientDB; you don't need to copy the
database directories since they're already in place and you just have to start it before all the other servers with

dserver.sh

.

55

Working with Distributed Graphs

Working with Distributed Graphs
When OrientDB joins a distributed cluster, all clients connecting to the server node are constantly notified about this state. This ensures
that, in the event that server node fails, the clients can switch transparently to the next available server.
You can check this through the console. When OrientDB runs in a distributed configuration, the current cluster shape is visible through
the
$

INFO

command.

$ORIENTDB_HOME/bin/console.sh

OrientDB console v.1.6 www.orientechnologies.com
Type 'help' to display all the commands supported.
Installing extensions for GREMLIN language v.2.5.0-SNAPSHOT

orientdb>

CONNECT remote:localhost/GratefulDeadConcerts admin admin

Connecting to database [remote:localhost/GratefulDeadConcerts] with user 'admin'...OK

orientdb>

INFO

Current database: GratefulDeadConcerts (url=remote:localhost/GratefulDeadConcerts)

For reference purposes, the server nodes in the example have the following configurations. As you can see, it is a two node cluster
running a single server host. The first node listens on port

2481

while the second on port

2480

.

+---------+------+-----------------------------------------+-----+---------+--------------+--------------+----------------------+
|Name

|Status|Databases

|Conns|StartedOn|Binary

|HTTP

|UsedMemory

|
+---------+------+-----------------------------------------+-----+---------+--------------+--------------+----------------------+
|europe-0 |ONLINE|distributed-node-deadlock=ONLINE (MASTER)|5

|16:53:59 |127.0.0.1:2424|127.0.0.1:2480|269.32MB/3.56GB (7.40

%)|
|europe-1 |ONLINE|distributed-node-deadlock=ONLINE (MASTER)|4

|16:54:03 |127.0.0.1:2425|127.0.0.1:2481|268.89MB/3.56GB (7.38

%)|
+---------+------+-----------------------------------------+-----+---------+--------------+--------------+----------------------+

Testing Distributed Architecture
Once you have a distributed database up and running, you can begin to test its operations on a running environment. For example, begin
by creating a vertex, setting the
orientdb>

node

property to

1

.

CREATE VERTEX V SET node = 1

Created vertex 'V#9:815{node:1} v1' in 0,013000 sec(s).

From another console, connect to the second node and execute the following command:

56

Working with Distributed Graphs

orinetdb>

SELECT FROM V WHERE node = 1

----+--------+-------+
#

| @RID

| node

|

----+--------+-------+
0

| #9:815 | 1

|

----+--------+-------+
1 item(s) found. Query executed in 0.19 sec(s).

This shows that the vertex created on the first node has successfully replicated to the second node.

Logs in Distributed Architecture
From time to time server nodes go down. This does not necessarily relate to problems in OrientDB, (for instance, it could originate from
limitations in system resources).
To test this out, kill the first node. For example, assuming the first node has a process identifier, (that is, a PID), of

1254

on your

system, run the following command:
$

kill -9 1254

This command kills the process on PID
$

1254

. Now, check the log messages for the second node:

less orientdb.log

INFO [127.0.0.1]:2435 [orientdb] Removing Member [127.0.0.1]:2434
[ClusterService]
INFO [127.0.0.1]:2435 [orientdb]
Members [1] {
Member [127.0.0.1]:2435 this
}

[ClusterService]
WARN [europe-0] node removed id=Member [127.0.0.1]:2434
name=europe-1 [OHazelcastPlugin]
INFO [127.0.0.1]:2435 [orientdb] Partition balance is ok, no need to
re-partition cluster data...

[PartitionService]

What the logs show you is that the second node is now aware that it cannot reach the first node. You can further test this by running the
console connected to the first node..
orientdb>

SELECT FROM V LIMIT 2

WARN Caught I/O errors from /127.0.0.1:2425 (local
socket=0.0.0.0/0.0.0.0:51512), trying to reconnect (error:
java.io.IOException: Stream closed) [OStorageRemote]
WARN Connection re-acquired transparently after 30ms and 1 retries: no errors
will be thrown at application level [OStorageRemote]
---+------+----------------+--------+--------------+------+-----------------+----# | @RID | name

| song_type | performances | type | out_followed_by | ...

---+------+----------------+--------+--------------+------+-----------------+----1 | #9:1 | HEY BO DIDDLEY | cover

| 5

| song | [5]

| ...

2 | #9:2 | IM A MAN

| 1

| song | [2]

| ...

| cover

---+------+----------------+--------+--------------+------+-----------------+-----

57

Working with Distributed Graphs
This shows that the console auto-switched to the next available node. That is, it switched to the second node upon noticing that the first
was no longer functional. The warnings reports show what happened in a transparent way, so that the application doesn't need to
manage the issue.
From the console connected to the second node, create a new vertex.
orientdb>

CREATE VERTEX V SET node=2

Created vertex 'V#9:816{node:2} v1' in 0,014000 sec(s).

Given that the first node remains nonfunctional, OrientDB journals the operation. Once the first node comes back online, the second
node synchronizes the changes into it.
Restart the first node and check that it successfully auto-realigns. Reconnect the console to the first node and run the following
command:
orientdb>

SELECT FROM V WHERE node=2

---+--------+-------+
# | @RID

| node

|

---+--------+-------+
0 | #9:816 | 2

|

---+--------+-------+
1 item(s) found. Query executed in 0.209 sec(s).

This shows that the first node has realigned itself with the second node.
This process is repeatable with N server nodes, where every server is a master. There is no limit to the number of running servers. With
many servers spread across a slow network, you can tune the network timeouts to be more permissive and let a large, distributed cluster
of servers work properly.
For more information, Distributed Architecture.

58

Data M odeling

Multi-Model
The OrientDB engine supports Graph, Document, Key/Value, and Object models, so you can use OrientDB as a replacement for a
product in any of these categories. However, the main reason why users choose OrientDB is because of its true Multi-Model DBM S
abilities, which combine all the features of the four models into the core. These abilities are not just interfaces to the database engine, but
rather the engine itself was built to support all four models. This is also the main difference to other multi-model DBM Ss, as they
implement an additional layer with an API, which mimics additional models. However, under the hood, they're truly only one model,
therefore they are limited in speed and scalability.

The Document Model
The data in this model is stored inside documents. A document is a set of key/value pairs (also referred to as fields or properties), where
the key allows access to its value. Values can hold primitive data types, embedded documents, or arrays of other values. Documents are
not typically forced to have a schema, which can be advantageous, because they remain flexible and easy to modify. Documents are
stored in collections, enabling developers to group data as they decide. OrientDB uses the concepts of "classes" and "clusters" as its
form of "collections" for grouping documents. This provides several benefits, which we will discuss in further sections of the
documentation.
OrientDB's Document model also adds the concept of a "LINK" as a relationship between documents. With OrientDB, you can decide
whether to embed documents or link to them directly. When you fetch a document, all the links are automatically resolved by OrientDB.
This is a major difference to other Document Databases, like M ongoDB or CouchDB, where the developer must handle any and all
relationships between the documents herself.
The table below illustrates the comparison between the relational model, the document model, and the OrientDB document model:
Relational Model

Document Model

OrientDB Document Model

Table

Collection

Class or Cluster

Row

Document

Document

Column

Key/value pair

Document field

Relationship

not available

Link

The Graph Model
A graph represents a network-like structure consisting of Vertices (also known as Nodes) interconnected by Edges (also known as Arcs).
OrientDB's graph model is represented by the concept of a property graph, which defines the following:
Vertex - an entity that can be linked with other Vertices and has the following mandatory properties:
unique identifier
set of incoming Edges
set of outgoing Edges
Edge - an entity that links two Vertices and has the following mandatory properties:
unique identifier
link to an incoming Vertex (also known as head)
link to an outgoing Vertex (also known as tail)
label that defines the type of connection/relationship between head and tail vertex
In addition to mandatory properties, each vertex or edge can also hold a set of custom properties. These properties can be defined by
users, which can make vertices and edges appear similar to documents. In the table below, you can find a comparison between the graph
model, the relational data model, and the OrientDB graph model:

59

Data M odeling
Relational Model

Graph Model

OrientDB Graph Model

Table

Vertex and Edge Class

Class that extends "V" (for Vertex) and "E" (for Edges)

Row

Vertex

Vertex

Column

Vertex and Edge property

Vertex and Edge property

Relationship

Edge

Edge

The Key/Value Model
This is the simplest model of the three. Everything in the database can be reached by a key, where the values can be simple and complex
types. OrientDB supports Documents and Graph Elements as values allowing for a richer model, than what you would normally find in
the classic Key/Value model. The classic Key/Value model provides "buckets" to group key/value pairs in different containers. The most
classic use cases of the Key/Value M odel are:
POST the value as payload of the HTTP call ->

//

GET the value as payload from the HTTP call ->

//

DELETE the value by Key, by calling the HTTP call ->

//

The table below illustrates the comparison between the relational model, the Key/Value model, and the OrientDB Key/Value model:
Relational Model

Key/Value Model

OrientDB Key/Value Model

Table

Bucket

Class or Cluster

Row

Key/Value pair

Document

Column

not available

Document field or Vertex/Edge property

Relationship

not available

Link

The Object Model
This model has been inherited by Object Oriented programming and supports Inheritance between types (sub-types extends the
super-types), Polymorphism when you refer to a base class and Direct binding from/to Objects used in programming languages.
The table below illustrates the comparison between the relational model, the Object model, and the OrientDB Object model:
Relational Model

Object Model

OrientDB Object Model

Table

Class

Class or Cluster

Row

Object

Document or Vertex

Column

Object property

Document field or Vertex/Edge property

Relationship

Pointer

Link

60

Basic Concepts

Basic Concepts
Record
The smallest unit that you can load from and store in the database. Records come in four types:
Document
RecordBytes
Vertex
Edge
A Record is the smallest unit that can be loaded from and stored into the database. A record can be a Document, a RecordBytes record
(BLOB) a Vertex or even an Edge.

Document
The Document is the most flexible record type available in OrientDB. Documents are softly typed and are defined by schema classes
with defined constraints, but you can also use them in a schema-less mode too.
Documents handle fields in a flexible manner. You can easily import and export them in JSON format. For example,
{
"name"

: "Jay",

"surname"

: "Miner",

"job"

: "Developer",

"creations" : [
{
"name"

: "Amiga 1000",

"company" : "Commodore Inc."
}, {
"name"

: "Amiga 500",

"company" : "Commodore Inc."
}
]
}

For Documents, OrientDB also supports complex relationships. From the perspective of developers, this can be understood as a
persistent

Map

.

BLOB
In addition to the Document record type, OrientDB can also load and store binary data. The BLOB record type was called
RecordBytes

before OrientDB v2.2.

Vertex
In Graph databases, the most basic unit of data is the node, which in OrientDB is called a vertex. The Vertex stores information for the
database. There is a separate record type called the Edge that connects one vertex to another.
Vertices are also documents. This means they can contain embedded records and arbitrary properties.

Edge
In Graph databases, an arc is the connection between two nodes, which in OrientDB is called an edge. Edges are bidirectional and can
only connect two vertices.
Edges can be regular or lightweight. The Regular Edge saves as a Document, while the Lightweight Edge does not. For an understanding
of the differences between these, see Lightweight Edges.
For more information on connecting vertices in general, see Relationships, below.

61

Basic Concepts

Record ID
When OrientDB generates a record, it auto-assigns a unique unit identifier, called a Record ID, or RID. The syntax for the Record ID is
the pound sign with the cluster identifier and the position. The format is like this:
#:

.

Cluster Identifier: This number indicates the cluster to which the record belongs. Positive numbers in the cluster identifier
indicate persistent records. Negative numbers indicate temporary records, such as those that appear in result-sets for queries that
use projections.
Position: This number defines the absolute position of the record in the cluster.
NOTE: The prefix character

#

is mandatory to recognize a Record ID.

Records never lose their identifiers unless they are deleted. When deleted, OrientDB never recycles identifiers, except with

local

storage. Additionally, you can access records directly through their Record ID's. For this reason, you don't need to create a field to serve
as the primary key, as you do in Relational databases.

Record Version
Records maintain their own version number, which increments on each update. In optimistic transactions, OrientDB checks the version
in order to avoid conflicts at commit time.

Class
The concept of the Class is taken from the Object Oriented Programming paradigm. In OrientDB, classes define records. It is closest to
the concept of a table in Relational databases.
Classes can be schema-less, schema-full or a mix. They can inherit from other classes, creating a tree of classes. Inheritance, in this
context, means that a sub-class extends a parent class, inheriting all of its attributes.
Each class has its own cluster. A class must have at least one cluster defined, which functions as its default cluster. But, a class can
support multiple clusters. When you execute a query against a class, it automatically propagates to all clusters that are part of the class.
When you create a new record, OrientDB selects the cluster to store it in using a configurable strategy.
When you create a new class, by default, OrientDB creates a new persistent cluster with the same name as the class, in lowercase.

Abstract Class
The concept of an Abstract Class is one familiar to Object-Oriented programming. In OrientDB, this feature has been available since
version 1.2.0. Abstract classes are classes used as the foundation for defining other classes. They are also classes that cannot have
instances. For more information on how to create an abstract class, see CREATE CLASS.
This concept is essential to Object Orientation, without the typical spamming of the database with always empty, auto-created clusters.
For more information on Abstract Class as a concept, see Abstract Type and Abstract M ethods and Classes

Class vs. Cluster in Queries
The combination of classes and clusters is very powerful and has a number of use cases. Consider an example where you create a class
Invoice

, with two clusters

orientdb>

invoice2016

and

invoice2017

. You can query all invoices using the class as a target with

SELECT

.

SELECT FROM Invoice

In addition to this, you can filter the result-set by year. The class

Invoice

includes a

year

field, you can filter it through the

WHERE

clause.
orientdb>

SELECT FROM Invoice WHERE year = 2016

62

Basic Concepts
You can also query specific objects from a single cluster. By splitting the class

Invoice

across multiple clusters, (that is, one per year),

you can optimize the query by narrowing the potential result-set.
orientdb>

SELECT FROM CLUSTER:invoice2016

Due to the optimization, this query runs significantly faster, because OrientDB can narrow the search to the targeted cluster.

Cluster
Where classes in provide you with a logical framework for organizing data, clusters provide physical or in-memory space in which
OrientDB actually stores the data. It is comparable to the collection in Document databases and the table in Relational databases.
When you create a new class, the

process also creates a physical cluster that serves as the default location in which to

CREATE CLASS

store data for that class. OrientDB forms the cluster name using the class name, with all lower case letters. Beginning with version 2.2,
OrientDB creates additional clusters for each class, (one for each CPU core on the server), to improve performance of parallelism.
For more information, see the Clusters Tutorial.

Relationships
OrientDB supports two kinds of relationships: referenced and embedded. It can manage relationships in a schema-full or schema-less
scenario.

Referenced Relationships
In Relational databases, tables are linked through
relationships natively without computing

JOIN

JOIN

commands, which can prove costly on computing resources. OrientDB manges

's. Instead, it stores direct links to the target objects of the relationship. This boosts the

load speed for the entire graph of connected objects, such as in Graph and Object database systems.
For example
customer
Record A

------------->

Record B

CLASS=Invoice

CLASS=Customer

RID=5:23

RID=10:2

Here, record

A

contains the reference to record

B

in the property

customer

. Note that both records are reachable by other records,

given that they have a Record ID.
With the Graph API, Edges are represented with two links stored on both vertices to handle the bidirectional relationship.

1:1 and 1:n Referenced Relationships
OrientDB expresses relationships of these kinds using links of the

LINK

type.

1:n and n:n Referenced Relationships
OrientDB expresses relationships of these kinds using a collection of links, such as:
LINKLIST

An ordered list of links.

LINKSET

An unordered set of links, which does not accept duplicates.

LINKMAP

An ordered map of links, with

String

as the key type. Duplicates keys are not accepted.

With the Graph API, Edges connect only two vertices. This means that 1:n relationships are not allowed. To specify a 1:n relationship
with graphs, create multiple edges.

Embedded Relationships

63

Basic Concepts
When using Embedded relationships, OrientDB stores the relationship within the record that embeds it. These relationships are stronger
than Reference relationships. You can represent it as a UM L Composition relationship.
Embedded records do not have their own Record ID, given that you can't directly reference it through other records. It is only accessible
through the container record.
In the event that you delete the container record, the embedded record is also deleted. For example,
address
Record A

<>---------->

Record B

CLASS=Account

CLASS=Address

RID=5:23

NO RID!

Here, record

A

contains the entirety of record

B

in the property

address

. You can reach record

B

only by traversing the container

record. For example,
orientdb>

SELECT FROM Account WHERE address.city = 'Rome'

1:1 and n:1 Embedded Relationships
OrientDB expresses relationships of these kinds using the

EMBEDDED

type.

1:n and n:n Embedded Relationships
OrientDB expresses relationships of these kinds using a collection of links, such as:
EMBEDDEDLIST

An ordered list of records.

EMBEDDEDSET

An unordered set of records, that doesn't accept duplicates.

EMBEDDEDMAP

An ordered map of records as the value and a string as the key, it doesn't accept duplicate keys.

Inverse Relationships
In OrientDB, all Edges in the Graph model are bidirectional. This differs from the Document model, where relationships are always
unidirectional, requiring the developer to maintain data integrity. In addition, OrientDB automatically maintains the consistency of all
bidirectional relationships.

Database
The database is an interface to access the real Storage. IT understands high-level concepts such as queries, schemas, metadata, indices
and so on. OrientDB also provides multiple database types. For more information on these types, see Database Types.
Each server or Java VM can handle multiple database instances, but the database name must be unique. You can't manage two databases
at the same time, even if they are in different directories. To handle this case, use the
/

$

dollar character as a separator instead of the

slash character. OrientDB binds the entire name, so it becomes unique, but at the file system level it converts

$

with

/

, allowing

multiple databases with the same name in different paths. For example,
test$customers -> test/customers
production$customers = production/customers

To open the database, use the following code:
test = new ODatabaseDocumentTx("remote:localhost/test$customers");
production = new ODatabaseDocumentTx("remote:localhost/production$customers");

Database URL
OrientDB uses its own URL format, of engine and database name as

:

.

64

Basic Concepts
Engine

Description

Example

plocal

This engine writes to the file system to store data. There is a LOG
of changes to restore the storage in case of a crash.

plocal:/temp/databases/petshop/petshop

memory

Open a database completely in memory

memory:petshop

remote

The storage will be opened via a remote network connection. It
requires an OrientDB Server up and running. In this mode, the
database is shared among multiple clients. Syntax: remote::
[]/db-name . The port is optional and defaults to 2424.

remote:localhost/petshop

Database Usage
You must always close the database once you finish working on it.
NOTE: OrientDB automatically closes all opened databases, when the process dies gracefully (not by killing it by force). This is
assured if the Operating System allows a graceful shutdown.

65

Supported Types

Supported Types
OrientDB supports several types natively. Below is the complete table.

#id

Type

Description

Autoconversion
from/to

Minimum
Maximum

Java type

0

Boolean

Handles only the values True or
False

java.lang.Boolean
boolean

or

0
1

String

1

Integer

32-bit signed Integers

java.lang.Integer
int

or

-2,147,483,648
+2,147,483,647

Any
Number,
String

2

Short

Small 16-bit signed integers

java.lang.Short
short

-32,768
32,767

Any
Number,
String

3

Long

Big 64-bit signed integers

java.lang.Long
long

-263
+263-1

Any
Number,
String

4

Float

Decimal numbers

java.lang.Float
float

2-149
-23 127
(2-2 )*2

Any
Number,
String

5

Double

Decimal numbers with high
precision

java.lang.Double
double

2-1074
-52 1023
(2-2 )*2

Any
Number,
String

6

Datetime

Any date with the precision up to
milliseconds. To know more about
it, look at M anaging Dates

java.util.Date

1002020303

Date, Long,
String

7

String

Any string as alphanumeric
sequence of chars

java.lang.String

-

-

8

Binary

Can contain any value as byte array

byte[]

0
2,147,483,647

String

9

Embedded

The Record is contained inside the
owner. The contained Record has
no RecordId

ORecord

-

ORecord

Embedded
list

The Records are contained inside
the owner. The contained records
have no RecordIds and are
reachable only by navigating the
owner record

List

0
41,000,000
items

String

Embedded
set

The Records are contained inside
the owner. The contained Records
have no RecordId and are reachable
only by navigating the owner
record

Set

0
41,000,000
items

String

12

Embedded
map

The Records are contained inside
the owner as values of the entries,
while the keys can only be Strings.
The contained ords e no RecordIds
and are reachable only by
navigating the owner Record

Map

0
41,000,000
items

13

Link

Link to another Record. It's a
common one-to-one relationship

ORID , 

1:-1
32767:2^63-1

String

14

Link list

Links to other Records. It's a
common one-to-many relationship
where only the RecordIds are
stored

List>
String

,

Collection

41,000,000
items

Map

0
41,000,000
items

String

-128
+127

Any
Number,
String

extends
ORecord>
String

,

16

Link map

Links to other Records as value of
the entries, while keys can only be
Strings. It's a common One-toM any Relationship. Only the
RecordIds are stored

17

Byte

Single byte. Useful to store small 8bit signed integers

18

Transient

Any value not stored on database

19

Date

Any date as year, month and day.
To know more about it, look at
M anaging Dates

java.util.Date

--

Date, Long,
String

20

Custom

used to store a custom type
providing the marshall and
unmarshall methods

OSerializableStream

0
X

-

21

Decimal

Decimal numbers without rounding

java.math.BigDecimal

?
?

Any
Number,
String

22

LinkBag

List of RecordIds as spec RidBag

ORidBag

?
?

-

23

Any

Not determinated type, used to
specify Collections of mixed type,
and null

-

-

java.lang.Byte
byte

-

or

67

Inheritance

Inheritance
Unlike many Object-relational mapping tools, OrientDB does not split documents between different classes. Each document resides in
one or a number of clusters associated with its specific class. When you execute a query against a class that has subclasses, OrientDB
searches the clusters of the target class and all subclasses.

Declaring Inheritance in Schema
In developing your application, bear in mind that OrientDB needs to know the class inheritance relationship. This is an abstract concept
that applies to both POJO's and Documents.
For example,
OClass account = database.getMetadata().getSchema().createClass("Account");
OClass company = database.getMetadata().getSchema().createClass("Company").setSuperClass(account);

Using Polymorphic Queries
By default, OrientDB treats all queries as polymorphic. Using the example above, you can run the following query from the console:
orientdb>

SELECT FROM Account WHERE name.toUpperCase() = 'GOOGLE'

This query returns all instances of the classes

Account

and

Company

that have a property name that matches

Google

.

How Inheritance Works
Consider an example, where you have three classes, listed here with the cluster identifier in the parentheses.
Account(10) <|--- Company (13) <|--- OrientTechnologiesGroup (27)

By default, OrientDB creates a separate cluster for each class. It indicates this cluster by the
OClass
int[]

and indicates the cluster used by default when not specified. However, the class

), that contains all the clusters able to contain the records of that class.

clusterIds

defaultClusterId

OClass

and

property in the class

has a property

defaultClusterId

clusterIds

, (as

are the same by

default.
When you execute a query against a class, OrientDB limits the result-sets to only the records of the clusters contained in the
clusterIds

property. For example,

orientdb>

SELECT FROM Account WHERE name.toUpperCase() = 'GOOGLE'

This query returns all the records with the name property set to
specified. For the class

Account

GOOGLE

, OrientDB searches inside the clusters

from all three classes, given that the base class
10

,

13

and

27

Account

was

, following the inheritance specified in the

schema.

68

Concurrency

Concurrency
OrientDB uses an optimistic approach to concurrency. Optimistic Concurrency Control, or OCC assumes that multiple transactions can
compete frequently without interfering with each other. It's very important that you don't share instances of databases, graphs, records,
documents, vertices and edges between threads because they are non thread-safe. For more information look at M ulti-Threading.

How does it work?
Consider the following scenario, where 2 clients, A and B, want to update the amount of a bank account:
Client A

Client B

|

|

(t1)

|

Read record #13:22

|

amount is 100

(t2)

|

Read record #13:22

(t3)

amount is 100

Update record #13:22

|

set amount = amount + 10

(t4)

|
|

Update record #13:22
set amount = amount + 10

|

|

Client A (t1) and B (t2) read the record #13:22 and both receive the last amount as USD 100. Client A updates the amount by adding
USD 10 (t3), then the Client B is trying to do the same thing: updates the amount by adding USD 10. Here is the problem: Client B is
doing an operation based on current information: the amount was USD 100. But at the moment of update, such information is changed
(by Client A on t3), so the amount is USD 110 in the database. Should the update succeed by setting the new amount to USD 120?
In some cases this could be totally fine, in others not. It depends by the use case. For example, in your application there could be a logic
where you are donating USD 10 to all the accounts where the amount is <=100. The owner of the account behind the record #13:22 is
more lucky than the others, because it receives the donation even if it has USD 110 at that moment.
For this reason in OrientDB when this situation happens a

OConcurrentModificationException

exception is thrown, so the application

can manage it properly. Usually the 3 most common strategies to handle this exceptions are:
1. Retry doing the same operation by reloading the record #13:22 first with the updated amount
2. Ignore the change, because the basic condition is changed
3. Propagate the exception to the user, so he can decide what to do in this case

Optimistic Concurrency in OrientDB
Optimistic concurrency control is used in environments with low data contention. That is, where conflicts are rare and transactions can
complete without the expense of managing locks and without having transactions wait for locks to clear. This means a reduced
throughput over other concurrency control methods.
OrientDB uses OCC for both Atomic Operations and Transactions.

Atomic Operations
OrientDB supports M ulti-Version Concurrency Control, or M VCC, with atomic operations. This allows it to avoid locking server side
resources. At the same time, it checks the version in the database. If the version is equal to the record version contained in the operation,
the operation is successful. If the version found is higher than the record version contained in the operation, then another thread or user
has already updated the same record. In this case, OrientDB generates an

OConcurrentModificationException

exception.

Given that behavior of this kind is normal on systems that use optimistic concurrency control, developers need to write concurrencyproof code. Under this design, the application retries transactions x times before reporting the error. It does this by catching the
exception, reloading the affected records and attempting to update them again. For example, consider the code for saving a document,

69

Concurrency
int maxRetries = 10;
List result = db.query("SELECT FROM Client WHERE id = '39w39D32d2d'");
ODocument address = result.get(0);
for (int retry = 0; retry < maxRetries; ++retry) {
try {
// LOOKUP FOR THE INVOICE VERTEX
address.field( "street", street );
address.field( "zip", zip );
address.field( "city", cityName );
address.field( "country", countryName );
address.save();
// EXIT FROM RETRY LOOP
break;
}
catch( ONeedRetryException e ) {
// IF SOMEONE UPDATES THE ADDRESS DOCUMENT
// AT THE SAME TIME, RETRY IT.
}
}

Transactions
OrientDB supports optimistic transactions. The database does not use locks when transactions are running, but when the transaction
commits, each record (document or graph element) version is checked to see if there have been updates from another client. For this
reason, you need to code your applications to be concurrency-proof.
Optimistic concurrency requires that you retire the transaction in the event of conflicts. For example, consider a case where you want to
connect a new vertex to an existing vertex:
int maxRetries = 10;
for (int retry = 0; retry < maxRetries; ++retry) {
try {
// LOOKUP FOR THE INVOICE VERTEX
Vertex invoice = graph.getVertices("invoiceId", 2323);
// CREATE A NEW ITEM
Vertex invoiceItem = graph.addVertex("class:InvoiceItem");
invoiceItem.field("price", 1000);
// ADD IT TO THE INVOICE
invoice.addEdge(invoiceItem);
graph.commit();
// EXIT FROM RETRY LOOP
break;
}
catch( OConcurrentModificationException e ) {
// SOMEONE HAS UPDATED THE INVOICE VERTEX
// AT THE SAME TIME, RETRY IT
}
}

Concurrency Level
In order to guarantee atomicity and consistency, OrientDB uses an exclusive lock on the storage during transaction commits. This means
that transactions are serialized.
Given this limitation, developers with OrientDB are working on improving parallelism to achieve better scalability on multi-core
machines, by optimizing internal structure to avoid exclusive locking.

Concurrency when Adding Edges

70

Concurrency
Consider the case where multiple clients attempt to add edges on the same vertex. OrientDB could throw the
OConcurrentModificationException

exception. This occurs because collections of edges are kept on vertices, meaning that, every time

OrientDB adds or removes an edge, both vertices update and their versions increment. You can avoid this issue by using RIDBAG
Bonsai structure, which are never embedded, so the edge never updates the vertices.
To use this configuration at run-time, before launching OrientDB, use this code:
OGlobalConfiguration.RID_BAG_EMBEDDED_TO_SBTREEBONSAI_THRESHOLD.setValue(-1);

Alternatively, you can set a parameter for the Java virtual-machine on startup, or even at run-time, before OrientDB is used:
$

java -DridBag.embeddedToSbtreeBonsaiThreshold=-1

While running in distributed mode S BTrees are not supported. If using a distributed database
then you must set
ridBag.embeddedToSbtreeBonsaiThreshold = Integer.MAX\_VALUE
to avoid replication errors.

Troubleshooting
Reduce Transaction Size
On occasion, OrientDB throws the

OConcurrentModificationException

exception even when you concurrently update the first element.

In particularly large transactions, where you have thousands of records involved in a transaction, one changed record is enough to roll the
entire process back with an

OConcurrentModificationException

exception.

To avoid issues of this kind, if you plan to update many elements in the same transaction with high-concurrency on the same vertices, a
best practice is to reduce the transaction size.

71

Schema

Schema
While OrientDb can work in a schema-less mode, you may find it necessary at times to enforce a schema on your data model. OrientDB
supports both schema-full and schema-hybrid solutions.
In the case of schema-hybrid mode, you only set constraints for certain fields and leave the user to add custom fields to the record. This
mode occurs at a class level, meaning that you can have an

Employee

class as schema-full and an

EmployeeInformation

class as schema-

less.
S chema-full Enables strict-mode at a class-level and sets all fields as mandatory.
S chema-less Enables classes with no properties. Default is non-strict-mode, meaning that records can have arbitrary fields.
S chema-hybrid Enables classes with some fields, but allows records to define custom fields. This is also sometimes called schemamixed.
NOTE Changes to the schema are not transactional. You must execute these commands outside of a transaction.
You can access the schema through SQL or through the Java API. Examples here use the latter. To access the schema API in Java, you
need the Schema instance of the database you want to use. For example,
OSchema schema = database.getMetadata().getSchema();

Class
OrientDB draws from the Object Oriented programming paradigm in the concept of the Class. A class is a type of record. In comparison
to Relational database systems, it is most similar in conception to the table.
Classes can be schema-less, schema-full or schema-hybrid. They can inherit from other classes, shaping a tree of classes. In other words,
a sub-class extends the parent class, inheriting all attributes.
Each class has its own clusters. By default, these clusters are logical, but they can also be physical. A given class must have at least one
cluster defined as its default, but it can support multiple clusters. OrientDB writes new records into the default cluster, but always
reads from all defined clusters.
When you create a new class, OrientDB creates a default physical cluster that uses the same name as the class, but in lowercase.

Creating Persistent Classes
Classes contain one or more properties. This mode is similar to the classical model of the Relational database, where you must define
tables before you can begin to store records.
To create a persistent class in Java, use the

createClass()

method:

OClass account = database.getMetadata().getSchema().createClass("Account");

This method creates the class
records in the class

Account

Account

on the database. It simultaneously creates the physical cluster

account

, to provide storage for

.

Getting Persistent Classes
With the new persistent class created, you may also need to get its contents.
To retrieve a persistent class in Java, use the

getClass()

method:

OClass account = database.getMetadata().getSchema().getClass("Account");

This method retrieves from the database the persistent class
returns

NULL

Account

. If the query finds that the

Account

class does not exist, it

.

72

Schema

Dropping Persistent Classes
In the event that you no longer want the class, you can drop, or delete, it from the database.
To drop a persistent class in Java, use the

OSchema.dropClass()

method:

database.getMetadata().getSchema().dropClass("Account");

This method drops the class

Account

from your database. It does not delete records that belong to this class unless you explicitly ask

it to do so:
database.command(new OCommandSQL("DELETE FROM Account")).execute();
database.getMetadata().getSchema().dropClass("Account");

Constraints
Working in schema-full mode requires that you set the strict mode at the class-level, by defining the
TRUE

setStrictMode()

method to

. In this case, records of that class cannot have undefined properties.

Properties
In OrientDB, a property is a field assigned to a class. For the purposes of this tutorial, consider Property and Field as synonymous.

Creating Class Properties
After you create a class, you can define fields for that class. To define a field, use the

createProperty()

method.

OClass account = database.getMetadata().getSchema().createClass("Account");
account.createProperty("id", OType.Integer);
account.createProperty("birthDate", OType.Date);

These lines create a class

Account

, then defines two properties

id

and

birthDate

. Bear in mind that each field must belong to one

of the supported types. Here these are the integer and date types.

Dropping Class Properties
In the event that you would like to remove properties from a class you can do so using the

dropProperty()

method under

OClass

.

database.getMetadata().getSchema().getClass("Account").dropProperty("name");

When you drop a property from a class, it does not remove records from that class unless you explicitly ask for it, using the
REMOVE

UPDATE...

statements. For instance,

database.getMetadata().getSchema().getClass("Account").dropProperty("name");
database.command(new OCommandSQL("UPDATE Account REMOVE name")).execute();

The first method drops the property from the class. The second updates the database to remove the property.

Relationships
OrientDB supports two types of relationships: referenced and embedded.

Referenced Relationships
In the case of referenced relationships, OrientDB uses a direct link to the referenced record or records. This allows the database to avoid
the costly

JOIN

operations used by Relational databases.

73

Schema
customer
Record A

------------->

Record B

CLASS=Invoice

CLASS=Customer

RID=5:23

RID=10:2

In the example, Record A contains the reference to Record B in the property

customer

. Both records are accessible by any other

records since each has a Record ID.

1:1 and n:1 Reference Relationships
In one to one and many to one relationships, the reference relationship is expressed using the

LINK

type. For instance.

OClass customer= database.getMetadata().getSchema().createClass("Customer");
customer.createProperty("name", OType.STRING);
OClass invoice = database.getMetadata().getSchema().createClass("Invoice");
invoice.createProperty("id", OType.INTEGER);
invoice.createProperty("date", OType.DATE);
invoice.createProperty("customer", OType.LINK, customer);

Here, records of the class

link to a record of the class

Invoice

Customer

, through the field

customer

.

1:n and n:n Reference Relationships.
In one to many and many to many relationships, OrientDB expresses the referenced relationship using collections of links.
An ordered list of links.

LINKLIST
LINKSET

An unordered set of links, that does not accept duplicates.

LINKMAP

An ordered map of links, with a string key. It does not accept duplicate keys.

For example,
OClass orderItem = db.getMetadata().getSchema().createClass("OrderItem");
orderItem.createProperty("id", OType.INTEGER);
orderItem.createProperty("animal", OType.LINK, animal);
OClass order = db.getMetadata().getSchema().createClass("Order");
order.createProperty("id", OType.INTEGER);
order.createProperty("date", OType.DATE);
order.createProperty("items", OType.LINKLIST, orderItem);

Here, you have two classes:

Order

and

OrderItem

and a 1:n referenced relationship is created between them.

Embedded Relationships
In the case of embedded relationships, OrientDB contains the relationship within the record. Embedded relationships are stronger than
referenced relationships, but the embedded record does not have its own Record ID. Because of this, you cannot reference them directly
through other records. The relationship is only accessible through the container record. If the container record is deleted, then the
embedded record is also deleted.
address
Record A

<>---------->

Record B

CLASS=Account

CLASS=Address

RID=5:23

NO RID!

Here, Record A contains the entirety of Record B in the property

address

. You can only reach Record B by traversing the container,

Record A.
orientdb>

SELECT FROM Account WHERE Address.city = 'Rome'

1:1 and n:1 Embedded Relationships
74

Schema
For one to one and many to one embedded relationships, OrientDB uses links of the

EMBEDDED

type. For example,

OClass address = database.getMetadata().getSchema().createClass("Address");
OClass account = database.getMetadata().getSchema().createClass("Account");
account.createProperty("id", OType.INTEGER);
account.createProperty("birthDate", OType.DATE);
account.createProperty("address", OType.EMBEDDED, address);

Here, records of the class

Account

embed records for the class

Address

.

1:n and n:n Embedded Relationships
In the case of one to many and many to many relationships, OrientDB sues a collection embedded link types:
EMBEDDEDLIST

An ordered list of records.

EMBEDDEDSET

An unordered set of records. It doesn't accept duplicates.

EMBEDDEDMAP

An ordered map of records as key-value pairs. It doesn't accept duplicate keys.

For example,
OClass orderItem = db.getMetadata().getSchema().createClass("OrderItem");
orderItem.createProperty("id", OType.INTEGER);
orderItem.createProperty("animal", OType.LINK, animal);
OClass order = db.getMetadata().getSchema().createClass("Order");
order.createProperty("id", OType.INTEGER);
order.createProperty("date", OType.DATE);
order.createProperty("items", OType.EMBEDDEDLIST, orderItem);

This establishes a one to many relationship between the classes

Order

and

OrderItem

.

Constraints
OrientDB supports a number of constraints for each field. For more information on setting constraints, see the

ALTER PROPERTY

command.
Minimum Value:

setMin()

The field accepts a string, because it works also for date ranges.

Maximum Value:

setMax()

The field accepts a string, because it works also for date rangers.

Mandatory:

setMandatory()

Read Only:

setReadonly()

Not Null:

setNotNull()

This field is required.
This field cannot update after being created.

This field cannot be null.

Unique: This field doesn't allow duplicates or speedup searches.
Regex: This field must satisfy Regular Expressions
For example,
profile.createProperty("nick", OType.STRING).setMin("3").setMax("30").setMandatory(true).setNotNull(true);
profile.createIndex("nickIdx", OClass.INDEX_TYPE.UNIQUE, "nick"); // Creates unique constraint
profile.createProperty("name", OType.STRING).setMin("3").setMax("30");
profile.createProperty("surname", OType.STRING).setMin("3").setMax("30");
profile.createProperty("registeredOn", OType.DATE).setMin("2010-01-01 00:00:00");
profile.createProperty("lastAccessOn", OType.DATE).setMin("2010-01-01 00:00:00");

Indices as Constraints
To define a property value as unique, use the

UNIQUE

index constraint. For example,

profile.createIndex("EmployeeId", OClass.INDEX_TYPE.UNIQUE, "id");

You can also constrain a group of properties as unique by creating a composite index made from multiple fields. For instance,

75

Schema
profile.createIndex("compositeIdx", OClass.INDEX_TYPE.NOTUNIQUE, "name", "surname");

For more information about indexes look at Index guide.

76

Graph or Document API?

Graph or Document API?
In OrientDB, we created 2 different APIs: the Document API and the Graph API. The Graph API works on top of the Document API.
The Document API contains the Document, Key/Value and Object Oriented models. The Graph API handles the Vertex and Edge
relationships.
YOU, THE USER
||

||

_||_

||

\

/

||

\/

_||_

+-------------+
|

Graph API

\

|

/

\/

+-------------+-----------------+
|

Document API

|

+-------------------------------+
| Key/Value and Object Oriented |
+-------------------------------+

Graph API
With OrientDB 2.0, we improved our Graph API to support all models in just one M ulti-M odel API. This API will probably cover
80% of your database use cases, so it should be your "go to" API, if you're starting with OrientDB.
Using the Graph API:
Your Data ('records' in the RDBM S world) will be modeled as Vertices and Edges. You can store properties in both.
You can still work in Schema-Less, Schema-Full or Hybrid modes.
Relationships are modeled as Bidirectional Edges. If the Lightweight edge setting is active, OrientDB uses Lightweight Edges in
cases where edges have no properties, so it has the same impact on speed and space as with Document LINKs, but with the
additional bonus of having bidirectional connections. This means you can use the

MOVE VERTEX

command to refactor your graph

with no broken LINKs. For more information how Edges are managed, please refer to Lightweight Edges.

Document API
What about the remaining 20% of your database use cases? Should you need a Document Database (while retaining the additional
OrientDB features, like LINKs) or you come from the Document Database world, using the Document API could be the right choice.
These are the Pros and Cons of using the Document API:
The Document API is simpler than the Graph API in general.
Relationships are only mono-directional. If you need bidirectional relationships, it is your responsibility to maintain both LINKs.
A Document is an atomic unit, while with Graphs, the relationships are modeled through In and Out properties. For this reason,
Graph operations must be done within transactions. In contrast, when you create a relationship between documents with a LINK,
the targeted linked document is not involved in this operation. This results in better M ulti-Threaded support, especially with
insert, delete and update operations.

77

Cluster Selection

Cluster Selection
When you create a new record and specify the class to which it belongs, OrientDB automatically selects a cluster, where it stores the
physical data of the record. There are a number of configuration strategies available for you to use in determining how OrientDB selects
the appropriate cluster for the new record.
It selects the cluster using the

default

defaultClusterId

property from the class. Prior to version 1.7, this was the default

method.
round-robin
balanced

It arranges the configured clusters for the class into sequence and assigns each new record to the next cluster in order.

It checks the number of records in the configured clusters for the class and assigns the new record to whichever is the

smallest at the time. To avoid latency issues on data insertions, OrientDB calculates cluster size every five seconds or longer.
local

When the database is run in distributed mode, it selects the master cluster on the current node. This helps to avoid conflicts

and reduce network latency with remote calls between nodes.
In distributed mode the local cluster strategy is always selected automatically and can't be changed. The local strategy acts as a wrapper
for the underlying strategy (round-robin by default) by filtering the allowed clusters by selecting only those the local server is a master.
But in Studio is never displayed properly, because the underlying name is taken.
Whichever cluster selection strategy works best for your application, you can assign it through the

ALTER CLASS...CLUSTERSELECTION

command. For example,
orientdb>

ALTER CLASS Account CLUSTERSELECTION round-robin

When you run this command, it updates the

Account

class to use the

round-robin

selection strategy. It cycles through available

clusters, adding new records to each in sequence.

Custom Cluster Selection Strategies
In addition to the cluster selection strategies listed above, you can also develop your own select strategies through the Java API. This
ensures that the strategies that are available by default do not meet your particular needs, you can develop one that does.
1. Using your preferred text editor, create the implementation in Java. In order to use a custom strategy, the class must implement the
OClusterSelectionStrategy

interface.

package mypackage;
public class RandomSelectionStrategy implements OClusterSelectionStrategy {
public int getCluster(final OClass iClass, final ODocument doc) {
final int[] clusters = iClass.getClusterIds();
// RETURN A RANDOM CLUSTER ID IN THE LIST
int r = new Random().nextInt(clusters.length);
return clusters[r];
}
public String getName(){ return "random"; }
}

Bear in mind that the method
to assign the

clusterId

getCluster()

also receives the

ODocument

cluster to insert. You may find this useful, if you want

variable, based on the Document content.

2. Register the implementation as a service. You can do this by creating a new file under

META-INF/service

com.orientechnologies.orient.core.metadata.schema.clusterselection.OClusterSelectionStrategy

. Use the filename

. For its contents, code your

class with the full package. For instance,
mypackage.RandomSelectionStrategy

78

Cluster Selection
This adds to the default content in the OrientDB core:
com.orientechnologies.orient.core.metadata.schema.clusterselection.ORoundRobinClusterSelectionStrategy
com.orientechnologies.orient.core.metadata.schema.clusterselection.ODefaultClusterSelectionStrategy
com.orientechnologies.orient.core.metadata.schema.clusterselection.OBalancedClusterSelectionStrategy

3. From the database console, assign the new selection strategy to your class with the
orientdb>

The class

Employee

ALTER CLASS...CLUSTERSELECTION

command.

ALTER CLASS Employee CLUSTERSELECTION random

now selects clusters using

random

, your custom strategy.

79

M anaging Dates

Managing Dates
OrientDB treats dates as first class citizens. Internally, it saves dates in the Unix time format. M eaning, it stores dates as a

long

variable, which contains the count in milliseconds since the Unix Epoch, (that is, 1 January 1970).

Date and Datetime Formats
In order to make the internal count from the Unix Epoch into something human readable, OrientDB formats the count into date and
datetime formats. By default, these formats are:
Date Format:

yyyy-MM-dd

Datetime Format:

yyyy-MM-dd HH:mm:ss

In the event that these default formats are not sufficient for the needs of your application, you can customize them through
DATABASE...DATEFORMAT

orientdb>

and

DATETIMEFORMAT

ALTER

commands. For instance,

ALTER DATABASE DATEFORMAT "dd MMMM yyyy"

This command updates the current database to use the English format for dates. That is, 14 Febr 2015.

SQL Functions and Methods
To simplify the management of dates, OrientDB SQL automatically parses dates to and from strings and longs. These functions and
methods provide you with more control to manage dates:
S QL

Description

DATE()

Function converts dates to and from strings and dates, also uses custom formats.

SYSDATE()

Function returns the current date.

.format()

M ethod returns the date in different formats.

.asDate()

M ethod converts any type into a date.

.asDatetime()

M ethod converts any type into datetime.

.asLong()

M ethod converts any date into long format, (that is, Unix time).

For example, consider a case where you need to extract only the years for date entries and to arrange them in order. You can use the
.format()

method to extract dates into different formats.

orientdb>

SELECT @RID, id, date.format('yyyy') AS year FROM Order

--------+----+------+
@RID

| id | year |

--------+----+------+
#31:10 | 92 | 2015 |
#31:10 | 44 | 2014 |
#31:10 | 32 | 2014 |
#31:10 | 21 | 2013 |
--------+----+------+

In addition to this, you can also group the results. For instance, extracting the number of orders grouped by year.

80

M anaging Dates

orientdb>

SELECT date.format('yyyy') AS Year, COUNT(*) AS Total

FROM Order ORDER BY Year

------+--------+
Year |

Total |

------+--------+
2015 |

1 |

2014 |

2 |

2013 |

1 |

------+--------+

Dates before 1970
While you may find the default system for managing dates in OrientDB sufficient for your needs, there are some cases where it may not
prove so. For instance, consider a database of archaeological finds, a number of which date to periods not only before 1970 but possibly
even before the Common Era. You can manage this by defining an era or epoch variable in your dates.
For example, consider an instance where you want to add a record noting the date for the foundation of Rome, which is traditionally
referred to as April 21, 753 BC. To enter dates before the Common Era, first run the [
the

GG

ALTER DATABASE DATETIMEFORMAT

] command to add

variable to use in referencing the epoch.

orientdb>

ALTER DATABASE DATETIMEFORMAT "yyyy-MM-dd HH:mm:ss GG"

Once you've run this command, you can create a record that references date and datetime by epoch.
orientdb>

CREATE VERTEX V SET city = "Rome", date = DATE("0753-04-21 00:00:00 BC")

orientdb>

SELECT @RID, city, date FROM V

-------+------+------------------------+
@RID

| city | date

|

-------+------+------------------------+
#9:10 | Rome | 0753-04-21 00:00:00 BC |
-------+------+------------------------+

Using .format() on Insertion
In addition to the above method, instead of changing the date and datetime formats for the database, you can format the results as you
insert the date.
orientdb>

CREATE VERTEX V SET city = "Rome", date = DATE("yyyy-MM-dd HH:mm:ss GG")

orientdb>

SELECT @RID, city, date FROM V

------+------+------------------------+
@RID | city | date

|

------+------+------------------------+
#9:4 | Rome | 0753-04-21 00:00:00 BC |
------+------+------------------------+

Here, you again create a vertex for the traditional date of the foundation of Rome. However, instead of altering the database, you format
the date field in

CREATE VERTEX

command.

Viewing Unix Time

81

M anaging Dates
In addition to the formatted date and datetime, you can also view the underlying count from the Unix Epoch, using the

asLong()

method for records. For example,
orientdb>

SELECT @RID, city, date.asLong() FROM #9:4

------+------+------------------------+
@RID | city | date

|

------+------+------------------------+
#9:4 | Rome | -85889120400000

|

------+------+------------------------+

M eaning that, OrientDB represents the date of April 21, 753 BC, as -85889120400000 in Unix time. You can also work with dates
directly as longs.
orientdb>

CREATE VERTEX V SET city = "Rome", date = DATE(-85889120400000)

orientdb>

SELECT @RID, city, date FROM V

-------+------+------------------------+
@RID

| city | date

|

-------+------+------------------------+
#9:11 | Rome | 0753-04-21 00:00:00 BC |
-------+------+------------------------+

Use ISO 8601 Dates
According to ISO 8601, Combined date and time in UTC: 2014-12-20T00:00:00. To use this standard change the datetimeformat in the
database:
ALTER DATABASE DATETIMEFORMAT "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"

82

Graph Consistency

Graph Consistency
Before OrientDB v2.1.7, the graph consistency could be assured only by using transactions. The problems with using transactions for
simple operations like creation of edges are:
speed, the transaction has a cost in comparison with non-transactional operations
management of optimistic retry at application level. Furthermore, with 'remote' connections this means high latency
low scalability on high concurrency (this will be resolved in OrientDB v3.0, where commits will not lock the database anymore)
As of v2.1.7, OrientDB provides a new mode to manage graphs without using transactions. It uses the Java class
via SQL by changing the global setting
tx

OrientGraphNoTx

or

to one of the following values:

sql.graphConsistencyMode

, the default, uses transactions to maintain consistency. This was the only available setting before v2.1.7

notx_sync_repair

, avoids the use of transactions. Consistency, in case of a JVM crash, is guaranteed through a database repair

operation, which runs at startup in synchronous mode. The database cannot be used until the repair is finished.
notx_async_repair

, also avoids the use of transactions. Consistency, in case of JVM crash, is guaranteed through a database repair

operation, which runs at startup in asynchronous mode. The database can be used immediately, as the repair procedure will run in
the background.
Both the new modes

notx_sync_repair

and

notx_async_repair

will manage conflicts automatically, with a configurable RETRY

(default=50). In case changes to the graph occur concurrently, any conflicts are caught transparently by OrientDB and the operations are
repeated. The operations that support the auto-retry are:
CREATE EDGE
DELETE EDGE
DELETE VERTEX

Usage
To use consistency modes that don't use transactions, set the
notx_async_repair

in OrientDB

bin/server.sh

sql.graphConsistencyMode

script or in the

global setting to

config/orientdb-server-config.xml

notx_sync_repair

or

file under properties section.

Example:
...

...

...


The same could be set by code, before you open any Graph. Example:
OGlobalConfiguration.SQL_GRAPH_CONSISTENCY_MODE.setValue("notx_sync_repair");

To make this setting persistent, set the

txRequiredForSQLGraphOperations

property in the storage configuration, so during the following

opening of the Graph, you don't need to set the global setting again:
g.getRawGraph().getStorage().getConfiguration().setProperty("txRequiredForSQLGraphOperations", "false");

Usage via Java API
In order to use non-transactional graphs, after having configured the consistency mode (as above), you can now work with the
OrientGraphNoTx

class. Example:

OrientGraphNoTx g = new OrientGraphNoTx("plocal:/temp/mydb");
...
v1.addEdge( "Friend", v2 );

83

Graph Consistency
Concurrent threads that change the graph will retry the graph change in case of concurrent modification (M VCC). The default value for
maximum retries is 50. To change this value, call the

setMaxRetries()

API:

OrientGraphNoTx g = new OrientGraphNoTx("plocal:/temp/mydb");
g.setMaxRetries(100);

This setting will be used on the active graph instance. You can have multiple threads, which work on the same graph by using multiple
graph instances, one per thread. Each thread can then have different settings. It's also allowed to wirk with threads, which use
transactions (

OrientGraph

class) and to work with concurrent threads, which don't use transactions.

84

Fetching Strategies

Fetching Strategies
Fetchplans are used in two different scopes:
1. A Connection that uses the Binary Protocol can early load records to the client. On traversing of connected records, the client
doesn't have to execute further remote calls to the server, because the requested records are already in the client's cache.
2. A Connection that uses the HTTP/JSON Protocol can expand the resulting JSON to include connected records as embedded in the
same JSON. This is useful with the HTTP protocol to fetch all the connected records in just one call.

Format for Fetch Plans
In boths scopes, the fetchplan syntax is the same. In terms of their use, Fetch Plans are strings that you can use at run-time on queries
and record loads. The syntax for these strings is:
[[levels]]fieldPath:depthLevel

Levels Is an optional value that indicates which levels to use with the Fetch Plans. Levels start from

0

. As of version 2.1, levels

use the following syntax:
Level The specific level on which to use the Fetch Plan. For example, using the level
Range The range of levels on which to use the Fetch Plan. For example,
levels. You can also use the partial range syntax:

[-3]

[0-2]

[0]

would apply only to the first level.

means to use it on the first through third

which means from the first to fourth levels, while

[4-]

means from

the fifth level to infinity.
Any The wildcard variable indicates that you want to use the Fetch Plan on all levels. For example,

[*]

.

Field Path Is the field name path, which OrientDB expects in dot notation. The path begins from either the root record or the
wildcard variable

*

to indicate any field. You can also use the wildcard at the end of the path to specify all paths that start for a

name.
Depth Level Is the depth of the level requested. The depth level variable uses the following syntax:
0

Indicates to load the current record.

1-N

Indicates to load the current record to the nth record.

-1

Indicates an unlimited level.

-2

Indicates an excluded level.

In the event that you want to express multiple rules for your Fetch Plans, separate them by spaces.
Consider the following Fetch Plans for use with the example above:
Fetch Plan

Description

*:-1

Fetches recursively the entire tree.

*:-1 orders:0

Fetches recursively all records, but uses the field orders in the root class. Note that the field
orders only loads its direct content, (that is, the records 8:12 , 8:19 , and 8:23 ). No other
records inside of them load.

*:0
address.city.country:0
[*]in_*:-2 out_*:-2

Fetches only non-document fields in the root class and the field
records 10:1 , 11:2 and 12:3 ).

address.city.country

, (that is,

Fetches all properties, except for edges at any level.

Early loading of records
By default, OrientDB loads linked records in a lazy manner. That is to say, it does not load linked fields until it traverses these fields. In
situations where you need the entire tree of a record, this can prove costly to performance. For instance,

85

Fetching Strategies
Invoice
3:100
|
| customer
+---------> Customer
|

5:233

| address

city

country

+---------> Address---------> City ---------> Country
|

10:1

11:2

12:3

|
| orders
+--------->* [OrderItem OrderItem OrderItem]
[

8:12

Here, you have a class,

8:19

Invoice

8:23

]

, with linked fields

customer

,

city

, and

orders

. If you were to run a

SELECT

query on

Invoice

,

it would not load the linked class, and it would require seven different loads to build the returned value. In the event that you have a
remote connection, that means seven network calls as well.
In order to avoid performance issues that may arise from this behavior, OrientDB supports fetching strategies, called Fetch Plans, that
allow you to customize how it loads linked records. The aim of a Fetch Plan is to pre-load connected records in a single call, rather than
several. The best use of Fetch Plans is on records loaded through remote connections and when using JSON serializers to produce JSON
with nested records.
NOTE OrientDB handles circular dependencies to avoid any loops while it fetches linking records.

Remote Connections
Under the default configuration, when a client executes a query or loads a single record directly from a remote database, it continues to
send network calls for each linked record involved in the query, (that is, through

OLazyRecordList

). You can mitigate this with a Fetch

Plan.
When the client executes a query, set a Fetch Plan with a level different from

0

. This causes the server to traverse all the records of the

return result-set, sending them in response to a single call. OrientDB loads all connected records into the local client, meaning that the
collections remain lazy, but when accessing content, the record is loaded from the local cache to mitigate the need for additional
connections.

Examples using SQL
Acquire Profile and it's first level friendships
SELECT OUT("out_Friend") as friends FROM Profile fetchplan friends:1

This will provide a result set of Profile records with a field called
out_Friend

edge. Only the

friends

friends

that contains an array of verticies connected via a

field is apart of the fetchplan in this instance, any further will be treated as normal.

Examples using the Java APIs
Execute a query with a custom fetch plan
List resultset = database.query(new OSQLSynchQuery("select * from Profile").setFetchPlan("*:-1"));

Export a document and its nested documents in JSON
Export an invoice and its customer:
invoice.toJSON("fetchPlan:customer:1");

Export an invoice, its customer, and orders:

86

Fetching Strategies
invoice.toJSON("fetchPlan:customer:1 orders:2");

Export an invoice and all the connected records up to 3rd level of depth:
invoice.toJSON("fetchPlan:*:3");

From SQL:
SELECT @this.toJSON('fetchPlan:out_Friend:4') FROM #10:20

Export path in outgoing direction by removing all the incoming edges by using wildcards (Since 2.0):
SELECT @this.toJSON('fetchPlan:in_*:-2') FROM #10:20

NOTES ::
To avoid looping, the record already traversed by fetching are exported only by their RIDs (RecordID) form
"fetchPlan" setting is case sensitive

Browse objects using a custom fetch plan
for (Account a : database.browseClass(Account.class).setFetchPlan("*:0 addresses:-1")) {
System.out.println( a.getName() );
}

NOTE: Fetching Object will mean their presence inside your domain entities. So if you load an object using fetchplan

*:0

all

LINK type references won't be loaded.

87

Use Cases

Use Cases
This page contains the solution to the most common use cases. Please don't consider them as the definitive solution, but as suggestions
where to get the idea to solve your needs.

Use cases
Time Series
Chat
Use OrientDB as a Key/Value DBM S
Persistent, Distributed and Transactional Queues

88

Time Series

Time Series Use Case
M anaging records related to historical information is pretty common. When you have millions of records, indexes start show their
limitations, because the cost to find the records is O(logN). This is also the main reason why Relational DBM S are so slow with huge
databases.
So when you have millions of record the best way to scale up linearly is avoid using indexes at all or as much as you can. But how can
you retrieve records in a short time without indexes? Should OrientDB scan the entire database at every query? No. You should use the
Graph properties of OrientDB. Let's look at a simple example, where the domain are logs.
A typical log record has some information about the event and a date. Below is the Log record to use in our example. We're going to use
the JSON format to simplify reading:
{
"date" : 12293289328932,
"priority" : "critical",
"note" : "System reboot"
}

Now let's create a tree (that is a directed, non cyclic graph) to group the Log records based on the granularity we need. Example:
Year -> month (map) -> Month -> day (map) -> Day -> hour

(map) -> Hour

Where Year, M onth, Day and Hour are vertex classes. Each Vertex links the other Vertices of smaller type. The links should be handled
using a M ap to make easier the writing of queries.
Create the classes:
CREATE CLASS Year
CREATE CLASS Month
CREATE CLASS Day
CREATE CLASS Hour
CREATE PROPERTY Year.month LINKMAP Month
CREATE PROPERTY Month.day LINKMAP Day
CREATE PROPERTY Day.hour LINKMAP Hour

Example to retrieve the vertex relative to the date M arch 2012, 20th at 10am (2012/03/20 10:00:00):
SELECT month[3].day[20].hour[10].logs FROM Year WHERE year = "2012"

If you need more granularity than the Hour you can go ahead until the Time unit you need:
Hour -> minute (map) -> Minute -> second (map) -> Second

Now connect the record to the right Calendar vertex. If the usual way to retrieve Log records is by hour you could link the Log records
in the Hour. Example:
Year -> month (map) -> Month -> day (map) -> Day -> hour

(map) -> Hour -> log (set) -> Log

The "log" property connects the Time Unit to the Log records. So to retrieve all the log of M arch 2012, 20th at 10am:
SELECT expand( month[3].day[20].hour[10].logs ) FROM Year WHERE year = "2012"

That could be used as starting point to retrieve only a sub-set of logs that satisfy certain rules. Example:

89

Time Series
SELECT FROM (
SELECT expand( month[3].day[20].hour[10].logs ) FROM Year WHERE year = "2012"
) WHERE priority = 'critical'

That retrieves all the CRITICAL logs of M arch 2012, 20th at 10am.

Join multiple hours
If you need multiple hours/days/months as result set you can use the UNION function to create a unique result set:
SELECT expand( records ) from (
SELECT union( month[3].day[20].hour[10].logs, month[3].day[20].hour[11].logs ) AS records
FROM Year WHERE year = "2012"
)

In this example we create a union between the 10th and 11th hours. But what about extracting all the hours of a day without writing a
huge query? The shortest way is using the Traverse. Below the Traverse to get all the hours of one day:
TRAVERSE hour FROM (
SELECT expand( month[3].day[20] ) FROM Year WHERE year = "2012"
)

So putting all together this query will extract all the logs of all the hours in a day:
SELECT expand( logs ) FROM (
SELECT union( logs ) AS logs FROM (
TRAVERSE hour FROM (
SELECT expand( month[3].day[20] ) FROM Year WHERE year = "2012"
)
)
)

Aggregate
Once you built up a Calendar in form of a Graph you can use it to store aggregated values and link them to the right Time Unit.
Example: store all the winning ticket of Online Games. The record structure in our example is:
{
"date" : 12293289328932,
"win" : 10.34,
"machine" : "AKDJKD7673JJSH",
}

You can link this record to the closest Time Unit like in the example above, but you could sum all the records in the same Day and link it
to the Day vertex. Example:
Create a new class to store the aggregated daily records:
CREATE CLASS DailyLog

Create the new record from an aggregation of the hour:
INSERT INTO DailyLog
SET win = (
SELECT SUM(win) AS win FROM Hour WHERE date BETWEEN '2012-03-20 10:00:00' AND '2012-03-20 11:00:00'
)

Link it in the Calendar graph assuming the previous command returned #23:45 as the RecordId of the brand new DailyLog record:

90

Time Series
UPDATE (
SELECT expand( month[3].day[20] ) FROM Year WHERE year = "2012"
) ADD logs = #23:45

91

Chat

Chat Use Case
OrientDB allows modeling of rich and complex domains. If you want to develop a chat based application, you can use whatever you
want to create the relationships between User and Room.
We suggest avoiding using Edges or Vertices connected with edges for messages. The best way is using the document API by creating
one class per chat room, with no index, to have super fast access to last X messages. In facts, OrientDB stores new records in append
only, and the @rid is auto generated as incrementing.
The 2 most common use cases in a chat are:
writing a message in a chat room
load last page of messages in a chat room

Create the initial schema
In order to work with the chat rooms, the rule of the thumb is creating a base abstract class ("ChatRoom") and then let to the concrete
classes to represent individual ChatRooms.

Create the base ChatRoom class
create class ChatRoom
alter class ChatRoom abstract true
create property ChatRoom.date datetime
create property ChatRoom.text string
create property ChatRoom.user LINK OUser

Create a new ChatRoom
create class ItalianRestaurant extends ChatRoom

Class "ItalianRestaurant" will extend all the properties from ChatRoom.
Why creating a base class? Because you could always execute polymorphic queries that are cross-chatrooms, like get all the message
from user "Luca":
select from ChatRoom where user.name = 'Luca'

Create a new message in the Chat Room
To create a new message in the chat room you can use this code:
public ODocument addMessage(String chatRoom, String message, OUser user) {
ODocument msg = new ODocument(chatRoom);
msg.field( "date", new Date() );
msg.field( "text", message );
msg.field( "user", user );
msg.save();
return msg;
}

Example:
addMessage("ItalianRestaurant", "Have you ever been at Ponza island?", database.getUser());

92

Chat

Retrieve last messages
You can easily fetch pages of messages ordered by date in descending order, by using the OrientDB's

@rid

. Example:

select from ItalianRestaurant order by @rid desc skip 0 limit 50

You could write a generic method to access to a page of messages, like this:
public Iterable loadMessages(String chatRoom, fromLast, pageSize) {
return graph.getRawGraph().command("select from " + chatRoom + " order by @rid desc skip " + fromLast + " limit " + pageSize
).execute();
}

Loading the 2nd (last) page from chat "ItalianRestaurant", would become this query (with pageSize = 50):
select from ItalianRestaurant order by @rid desc skip 50 limit 50

This is super fast and O(1) even with million of messages.

Limitations
Since OrientDB can handle only 32k clusters, you could have maximum 32k chat rooms. Unless you want to rewrite the entire
FreeNode, 32k chat rooms will be more than enough for most of the cases.
However, if you need more than 32k chat rooms, the suggested solution is still using this approach, but with multiple databases (even
on the same server, because one OrientDB Server instance can handle thousands of databases concurrently).
In this case you could use one database to handle all the metadata, like the following classes:
ChatRoom, containing all the chatrooms, and the database where are stored. Example:

{ "@class": "ChatRoom", "description":

"OrientDB public channel", "databaseName", "db1", "clusterName": "orientdb" }

User, containing all the information about accounts with the edges to the ChatRoom vertices where they are subscribed
OrientDB cannot handle cross-database links, so when you want to know the message's author, you have to look up into the
"M etadata" database by @RID (that is O(1)).

93

Key Value

Key Value Use Case
OrientDB can also be used as a Key Value DBM S by using the super fast Indexes. You can have as many Indexes as you need.

HTTP
OrientDB RESTful HTTP protocol allows to talk with a OrientDB Server instance using the HTTP protocol and JSON. OrientDB
supports also a highly optimized Binary protocol for superior performances.

Operations
To interact against OrientDB indexes use the four methods of the HTTP protocol in REST fashion:
PUT, to create or modify an entry in the database
GET, to retrieve an entry from the database. It's idempotent that means no changes to the database happen. Remember that in IE6
the URL can be maximum of 2,083 characters. Other browsers supports longer URLs, but if you want to stay compatible with all
limit to 2,083 characters
DELETE, to delete an entry from the database

Create an entry
To create a new entry in the database use the Index-PUT API.
Syntax:

http://:[]/index//

Example:
HTTP PUT:

http://localhost:2480/index/customers/jay

{
"name" : "Jay",
"surname" : "Miner"
}

HTTP Response 204 is returned.

Retrieve an entry
To retrieve an entry from the database use the Index-GET API.
Syntax:

http://:[]/index//

Example:
HTTP GET:

http://localhost:2480/index/customers/jay

HTTP Response 200 is returned with this JSON as payload:
{
"name" : "Jay",
"surname" : "Miner"
}

Remove an entry

94

Key Value
To remove an entry from the database use the Index-DELETE API.
Syntax:

http://:[]/index//

Example:
HTTP DELETE:

http://localhost:2480/index/customers/jay

HTTP Response 200 is returned

Step-by-Step tutorial
Before to start assure you've a OrientDB server up and running. In this example we'll use curl considering the connection to localhost to
the default HTTP post 2480. The default "admin" user is used.

Create a new index
To use OrientDB as a Key/Value store we need a brand new manual index, let's call it "mainbucket". We're going to create it as UNIQUE
because keys cannot be duplicated. If you can have multiple keys consider:
creating the index as NOTUNIQUE
leave it as UNIQUE but as value handle array of documents
Create the new manual unique index "mainbucket":
> curl --basic -u admin:admin localhost:2480/command/demo/sql -d "create index mainbucket UNIQUE"

Response:
{ "result" : [
{ "@type" : "d" , "@version" : 0, "value" : 0, "@fieldTypes" : "value=l" }
]
}

Store the first entry
Below we're going to insert the first entry by using the HTTP PUT method passing "jay" as key in the URL and as value the entire
document in form of JSON:
> curl --basic -u admin:admin -X PUT localhost:2480/index/demo/mainbucket/jay -d "{'name':'Jay','surname':'Miner'}"

Response:
Key 'jay' correctly inserted into the index mainbucket.

Retrieve the entry just inserted
Below we're going to retrieve the entry we just entered by using the HTTP GET method passing "jay" as key in the URL:
> curl --basic -u admin:admin localhost:2480/index/demo/mainbucket/jay

Response:

95

Key Value
[{
"@type" : "d" , "@rid" : "#3:477" , "@version" : 0,
"name" : "Jay",
"surname" : "Miner"
}]

Note that an array is always returned in case multiple records are associated to the same key (if NOTUNIQUE index is used). Look also
at the document has been created with RID #3:477. You can load it directly if you know the RID. Remember to remove the # character.
Example:
> curl --basic -u admin:admin localhost:2480/document/demo/3:477

Response:
{
"@type" : "d" , "@rid" : "#3:477" , "@version" : 0,
"name" : "Jay",
"surname" : "Miner"
}

Drop an index
Once finished drop the index "mainbucket" created for the example:
> curl --basic -u admin:admin localhost:2480/command/demo/sql -d "drop index mainbucket"

Response:
{ "result" : [
{ "@type" : "d" , "@version" : 0, "value" : 0, "@fieldTypes" : "value=l" }
]
}

96

Queue system

Distributed queues use case
Implementing a persistent, distributed and transactional queue system using OrientDB is possible and easy. Besides the fact you don't
need a specific API accomplish a queue, there are multiple approaches you can follow depending by your needs. The easiest way is
using OrientDB SQL, so this works with any driver.
Create the queue class first:
create class queue

You could have one class per queue. Example of push operation:
insert into queue set text = "this is the first message", date = date()

Since OrientDB by default keeps the order of creation of records, a simple delete from the queue class with limit = 1 gives to you the
perfect pop:
delete from queue return before limit 1

The "return before" allows you to have the deleted record content. If you need to peek the queue, you can just use the select:
select from queue limit 1

That's it. Your queue will be persistent, if you want transactional and running in cluster distributed.

97

Administration

Administration

OrientDB has a number of tools to make administration of the database easier. There is the console, which allows you to run a large
number of commands.
There is also the OrientDB Studio, which allows you to run queries and visually look at the graph.

OrientDB also offers several tools for the import and export of data, logging and trouble shooting, along with ETL tools.
All of OrientDB's administration facilities are aimed to make your usage of OrientDB as simple and as easy as possible.
For more information see:
Studio
Console
Backup and Restore
Export and Import
Logging
Trouble shooting
Performance Tuning
ETL Tools
Stress Test Tool

98

Console

Console
OrientDB provides a Console Tool, which is a Java application that connects to and operates on OrientDB databases and Server
instances.

Console Modes
There are two modes available to you, while executing commands through the OrientDB Console: interactive mode and batch mode.

Interactive Mode
By default, the Console starts in interactive mode. In this mode, the Console loads to an

orientdb>

prompt. From there you can

execute commands and SQL statements as you might expect in any other database console.
You can launch the console in interactive mode by executing the
systems in the

bin

console.sh

for Linux OS systems or

console.bat

for Windows

directory of your OrientDB installation. Note that running this file requires execution permissions.

$

cd $ORIENTDB_HOME/bin

$

./console.sh

OrientDB console v.X.X.X (build 0) www.orientdb.com
Type 'HELP' to display all the commands supported.
Installing extensions for GREMLIN language v.X.X.X
orientdb>

From here, you can begin running SQL statements or commands. For a list of these commands, see commands.

Batch mode
When the Console runs in batch mode, it takes commands as arguments on the command-line or as a text file and executes the commands
in that file in order. Use the same

console.sh

or

console.bat

file found in

bin

at the OrientDB installation directory.

Command-line: To execute commands in batch mode from the command line, pass the commands you want to run in a string,
separated by a semicolon.
$

$ORIENTDB_HOME/bin/console.sh "CONNECT REMOTE:localhost/demo;SELECT FROM Profile"

S cript Commands: In addition to entering the commands as a string on the command-line, you can also save the commands to a
text file as a semicolon-separated list.
$

vim commands.txt

CONNECT REMOTE:localhost/demo;SELECT FROM Profile

$

$ORIENTDB_HOME/bin/console.sh commands.txt

Ignoring Errors
When running commands in batch mode, you can tell the console to ignore errors, allowing the script to continue the execution, with the
ignoreErrors

setting.

99

Console

$

vim commands.txt

SET ignoreErrors TRUE

Enabling Echo
Regardless of whether you call the commands as an argument or through a file, when you run console commands in batch mode, you
may also need to display them as they execute. You can enable this feature using the

echo

setting, near the start of your commands

list.
$

vim commands.txt

SET echo TRUE

Enabling Date in prompt
Starting from v2.2.9, to enable the date in the prompt, set the variable

promptDateFormat

with the date format following the

SimpleDateFormat specs.

orientdb {db=test1}> set promptDateFormat "yyy-MM-dd hh:mm:ss.sss"
orientdb {db=test1 (2016-08-26 09:34:12.012)}>

Console commands
OrientDB implements a number of SQL statements and commands that are available through the Console. In the event that you need
information while working in the console, you can access it using either the
Command

HELP

or

?

command.

Description

ALTER CLASS

Changes the class schema

ALTER CLUSTER

Changes the cluster attributes

ALTER DATABASE

Changes the database attributes

ALTER PROPERTY

Changes the class's property schema

BACKUP DATABASE

Backup a database

BEGIN

Begins a new transaction

BROWSE CLASS

Browses all the records of a class

BROWSE CLUSTER

Browses all the records of a cluster

CLASSES

Displays all the configured classes

CLUSTER STATUS

Displays the status of distributed cluster of servers

CLUSTERS

Displays all the configured clusters

COMMIT

Commits an active transaction

CONFIG

Displays the configuration where the opened database is located (local or remote)

CONFIG GET

Returns a configuration value

CONFIG SET

Set a configuration value

CONNECT

Connects to a database

100

Console
CREATE CLASS

Creates a new class

CREATE CLUSTER

Creates a new cluster inside a database

CREATE CLUSTER

Creates a new record cluster

CREATE DATABASE

Creates a new database

CREATE EDGE

Create a new edge connecting two vertices

CREATE INDEX

Create a new index

CREATE LINK

Create a link reading a RDBM S JOIN

CREATE VERTEX

Create a new vertex

DECLARE INTENT

Declares an intent

DELETE

Deletes a record from the database using the SQL syntax. To know more about the SQL syntax go here

DICTIONARY KEYS

Displays all the keys in the database dictionary

DICTIONARY GET

Loookups for a record using the dictionary. If found set it as the current record

DICTIONARY PUT

Inserts or modify an entry in the database dictionary. The entry is composed by key=String, value=recordid

DICTIONARY
REMOVE

Removes the association in the dictionary

DISCONNECT

Disconnects from the current database

DISPLAY RECORD

Displays current record's attributes

DISPLAY RAW
RECORD

Displays current record's raw format

DROP CLASS

Drop a class

DROP CLUSTER

Drop a cluster

DROP DATABASE

Drop a database

DROP INDEX

Drop an index

DROP PROPERTY

Drop a property from a schema class

EXPLAIN

Explain a command by displaying the profiling values while executing it

EXPORT DATABASE

Exports a database

EXPORT RECORD

Exports a record in any of the supported format (i.e. json)

FIND REFERENCES

Find the references to a record

FREEZE DATABASE

Freezes the database locking all the changes. Use this to raw backup. Once frozen it uses the
DATABASE to release it

GET

Returns the value of a property

GRANT

Grants a permission to a user

GREMLIN

Executes a Gremlin script

IMPORT DATABASE

Imports a database previously exported

INDEXES

Displays information about indexes

INFO

Displays information about current status

INFO CLASS

Displays information about a class

INSERT

Inserts a new record in the current database using the SQL syntax. To know more about the SQL syntax go
here

JS

Executes a Javascript in the console

JSS

Executes a Javascript in the server

RELEASE

101

Console
LIST DATABASES
LIST
CONNECTIONS

List the available databases
List the available connections

LOAD RECORD

Loads a record in memory and set it as the current one

LOAD SCRIPT

Loads a script and execute it

PROFILER

Controls the Profiler

PROPERTIES

Returns all the configured properties

pwd

Display current path

REBUILD INDEX

Rebuild an index

RELEASE
DATABASE

Releases a Console Freeze Database database

RELOAD RECORD

Reloads a record in memory and set it as the current one

RELOAD SCHEMA

Reloads the schema

ROLLBACK

Rollbacks the active transaction started with begin

RESTORE
DATABASE

Restore a database

SELECT

Executes a SQL query against the database and display the results. To know more about the SQL syntax go
here

REVOKE

Revokes a permission to a user

SET

Changes the value of a property

SLEEP

Sleep for the time specified. Useful on scripts

TRAVERSE

Traverse a graph of records

TRUNCATE CLASS

Remove all the records of a class (by truncating all the underlying configured clusters)

TRUNCATE
CLUSTER

Remove all the records of a cluster

TRUNCATE RECORD

Truncate a record you can't delete because it's corrupted

UPDATE

Updates a record in the current database using the SQL syntax. To know more about the SQL syntax go
here

HELP

Prints this help

EXIT

Closes the console

Custom Commands
In addition to the commands implemented by OrientDB, you can also develop custom commands to extend features in your particular
implementation. To do this, edit the OConsoleDatabaseApp class and add to it a new method. There's an auto-discovery system in
place that adds the new method to the available commands. To provide a description of the command, use annotations. The command
name must follow the Java code convention of separating words using camel-case.
For instance, consider a case in which you might want to add a

MOVE CLUSTER

command to the console:

@ConsoleCommand(description = "Move the physical location of cluster files")
public void moveCluster(
@ConsoleParameter(name = "cluster-name", description = "The name or the id of the cluster to remove") String iClusterName,
@ConsoleParameter(name = "target-path", description = "path of the new position where to move the cluster files") String iN
ewPath ) {
checkCurrentDatabase(); // THE DB MUST BE OPENED
System.out.println("Moving cluster '" + iClusterName + "' to path " + iNewPath + "...");
}

102

Console
Once you have this code in place,
orientdb>

MOVE CLUSTER

now appears in the listing of available commands shown by

HELP

.

HELP

AVAILABLE COMMANDS:
* alter class

Alter a class in the database schema

* alter cluster

Alter class in the database schema

...

...

* move cluster

Move the physical location of cluster files

...

...

* help

Print this help

* exit

Close the console

orientdb>

MOVE CLUSTER foo /temp

Moving cluster 'foo' to path /tmp...

In the event that you develop a custom command and find it especially useful in your deployment, you can contribute your code to the
OrientDB Community!

103

Backup

Console - BACKUP
Executes a complete backup on the currently opened database. It then compresses the backup file using the ZIP algorithm. You can then
restore a database from backups, using the

RESTORE DATABASE

command. You can automate backups using the Automatic-Backup server

plugin.
Backups and restores are similar to the

EXPORT DATABASE

and

IMPORT DATABASE

, but they offer better performance than these options.

NOTE: OrientDB Community Edition does not support backing up remote databases. OrientDB Enterprise Edition does
support this feature. For more information on how to implement this with Enterprise Edition, see Remote Backups.
S yntax:
BACKUP DATABASE  [-incremental] [-compressionLevel=] [-bufferSize=]


-incremental

Defines the path to the backup file.
Option to execute an incremental backup. When enabled, it computes the data to backup as all new changes since

the last backup. Available only in the OrientDB Enterprise Edition version 2.2 or later.
-

Defines the level of compression for the backup file. Valid levels are

compressionLevel

0

to

. The default is

9

9

. Available in

1.7 or later.
Defines the compression buffer size. By default, this is set to 1M B. Available in 1.7 or later.

-bufferSize

Example:
Backing up a database:
orientdb>

CONNECT plocal:../databases/mydatabase admin admin

orientdb>

BACKUP DATABASE /backups/mydb.zip

Backing current database to: database mydb.zip
Backup executed in 0.52 seconds

Backup API
In addition to backups called through the Console, you can also manage backups through the Java API. Using this, you can perform
either a full or incremental backup on your database.

Full Backup
In Java or any other language that runs on top of the JVM , you can initiate a full backup by using the

backup()

method on a database

instance.
db.backup(out, options, callable, listener, compressionLevel, bufferSize);

out

Refers to the

OutputStream

that it uses to write the backup content. Use a

FileOutputStream

to make the backup

persistent on disk.
options

Defines backup options as a

Map

object.

callable

Defines the callback to execute when the database is locked.

listener

Defines the listened called for backup messages.

compressionLevel

compression and

Defines the level of compression for the backup. It supports levels between
9

0

and

9

, where

0

equals no

the maximum. Higher compression levels do mean smaller files, but they also mean the backup requires more

from the CPU at execution time.
bufferSize

Defines the buffer size in bytes. The larger the buffer, the more efficient the comrpession.

Example:

104

Backup
ODatabaseDocumentTx db = new ODatabaseDocumentTx("plocal:/temp/mydb");
db.open("admin", "admin");
try{
OCommandOutputListener listener = new OCommandOutputListener() {
@Override
public void onMessage(String iText) {
System.out.print(iText);
}
};
OutputStream out = new FileOutputStream("/temp/mydb.zip");
db.backup(out,null,null,listener,9,2048);
} finally {
db.close();
}

Incremental Backup
As of version 2.2, OrientDB Enterprise Edition supports incremental backups executed through Java or any language that runs on top of
the JVM , using the

incrementalBackup()

method against a database instance.

db.incrementalBackup(backupDirectory);

backupDirectory

Defines the directory where it generates the incremental backup files.

It is important that previous incremental backup files are present in the same directory, in order to compute the database portion to back
up, based on the last incremental backup.
Example:
ODatabaseDocumentTx db = new ODatabaseDocumentTx("plocal:/temp/mydb");
db.open("admin", "admin");
try{
db.backup("/var/backup/orientdb/mydb");
} finally {
db.close();
}

For more information, see:
Restore Database
Export Database
Import Database
Console-Commands
ODatabaseExport Java class

105

Begin

Console - BEGIN
Initiates a transaction. When a transaction is open, any commands you execute on the database remain temporary. In the event that you
are satisfied with the changes, you can call the
ROLLBACK

COMMIT

command to commit them to the database. Otherwise, you can call the

command, to roll the changes back to the point where you called

BEGIN

.

S yntax:
BEGIN

Examples
Begin a transaction:
orientdb>

BEGIN

Transaction 1 is running

Attempting to begin a transaction when one is already open:
orinetdb>

BEGIN

Error: an active transaction is currently open (id=1).

Commit or rollback

before starting a new one.

M aking changes when a transaction is open:
orientdb>

INSERT INTO Account (name) VALUES ('tx test') SELECT FROM Account WHERE name LIKE 'tx%'

---+-------+---------# | RID

| name

---+-------+---------0 | #9:-2 | tx test
---+-------+----------

When a transaction is open, new records all have temporary Record ID's, which are given negative values, (for instance, like the
shown above). These remain in effect until you run

#9:-2

COMMIT

For more information on Transactions, see
Transactions
Console Command COM M IT
Console Command ROLLBACK
Console Commands

106

Browse Class

Console - BROWSE CLASS
Displays all records associated with the given class.
S yntax:
BROWSE CLASS 



Defines the class for the records you want to display.

Example:
Browse records associated with the class
orientdb>

City

:

BROWSE CLASS City

----+------+------------------# | RID

| NAME

----+------+------------------0 | -6:0 | Rome
1 | -6:1 | London
2 | -6:2 | Honolulu
----+------+-------------------

For more information on other commands, see Console Commands.

107

Browse Cluster

Console - BROWSE CLUSTER
Displays all records associated with the given cluster.
S yntax:
BROWSE CLUSTER 



Defines the cluster for the records you want to display.

Example:
Browse records associated with the cluster
orientdb>

City

:

BROWSE CLUSTER City

----+------+------------------# | RID

| NAME

----+------+------------------0 | -6:0 | Rome
1 | -6:1 | London
2 | -6:2 | Honolulu
----+------+-------------------

For more information on other commands, see Console Commands.

108

List Classes

Console - LIST CLASSES
Displays all configured classes in the current database.
S yntax:
Long Syntax:
LIST CLASSES

Short Syntax:
CLASSES

Example
List current classes in the database:
orientdb>

LIST CLASSES

CLASSES
-------------+------+-------------+----------NAME

|

ID

| CLUSTERS

| ELEMENTS

-------------+------+-------------+----------Person

|

0 | person

|

7

Animal

|

1 | animal

|

5

AnimalRace

|

2 | AnimalRace

|

0

AnimalType

|

3 | AnimalType

|

1

OrderItem

|

4 | OrderItem

|

0

Order

|

5 | Order

|

0

City

|

6 | City

|

3

-------------+------+-------------+----------TOTAL

16

-----------------------------------------------

For more information on other commands, see Console Commands.

109

Cluster Status

Console - CLUSTER STATUS
Displays the status of the cluster in distributed configuration.
S yntax:
CLUSTER STATUS

Example:
Display the status of the cluster:
orientdb>

CLUSTER STATUS

{
"localName": "_hzInstance_1_orientdb",
"localId": "3735e690-9a7b-44d2-b4bc-27089da065e2",
"members": [
{
"id": "3735e690-9a7b-44d2-b4bc-27089da065e2",
"name": "node1",
"startedOn": "2015-05-14 17:06:40:418",
"listeners": [
{
"protocol": "ONetworkProtocolBinary",
"listen": "10.3.15.55:2424"
},
{
"protocol": "ONetworkProtocolHttpDb",
"listen": "10.3.15.55:2480"
}
],
"databases": []
}
]
}

For more information on other commands, see Console Commands.

110

List Clusters

Console - LIST CLUSTERS
Displays all configured clusters in the current database.
S yntax:
Long Syntax:
LIST CLUSTERS

Short Syntax:
CLUSTERS

Example:
List current clusters on database:
orientdb>

LIST CLUSTERS

CLUSTERS
-------------+------+-----------+----------NAME

|

ID

| TYPE

| ELEMENTS

-------------+------+-----------+----------metadata

|

0 | Physical

|

11

index

|

1 | Physical

|

0

default

|

2 | Physical

|

779

csv

|

3 | Physical

|

1000

binary

|

4 | Physical

|

1001

person

|

5 | Physical

|

7

animal

|

6 | Physical

|

5

animalrace

|

-2 | Logical

|

0

animaltype

|

-3 | Logical

|

1

orderitem

|

-4 | Logical

|

0

order

|

-5 | Logical

|

0

city

|

-6 | Logical

|

3

-------------+------+-----------+----------TOTAL

2807

--------------------------------------------

For information on creating new clusters in the current database, see the

CREATE CLUSTER

command. For more information on

other commands, see Console Commands.

111

List Servers

Console - LIST SERVERS
Displays all active servers connected within a cluster.
This command was introduced in OrientDB version 2.2.
S yntax:
LIST SERVERS

Example:
List the servers currently connected to the cluster:
orientdb>

LIST SERVERS

CONFIGURED SERVERS
-+----+------+-----------+-------------+-----------+-----------+-----------+---------+--------#|Name|Status|Connections|StartedOn

|Binary

|HTTP

|UsedMemory

|FreeMemory|MaxMemory
-+----+------+-----------+-------------+-----------+-----------+-----------+---------+--------0|no2 |ONLINE|0

|2015-10-

30...|192.168.0.6|192.168.0.6|80MB(8.80%)|215MB(23%)|910MB
1|no1 |ONLINE|0

|2015-10-30...|192.168.0.6|192.168.0.6|90MB(2.49%)|195MB(5%)

|3.5GB
-+----+------+-----------+-------------+-----------+-----------+-----------+---------+---------

Use the

DISPLAY

orientdb>

command to show information on a specific server:

DISPLAY 0

-------------+-----------------------------Name | Value
-------------+-----------------------------Name | node2
Status | ONLINE
Connections | 0
StartedOn | Fri Oct 30 21:41:07 CDT 2015
Binary | 192.168.0.6:2425
HTTP | 192.168.0.6:2481
UsedMemory | 80,16MB (8,80%)
FreeMemory | 215,34MB (23,65%)
MaxMemory | 910,50MB
-------------+------------------------------

For more information on other commands, see Console Commands.

112

List Server Users

Console - LIST SERVER USERS
This feature was introduced in OrientDB version 2.2.
Displays all configured users on the server. In order to display the users, the current system user that is running the console must have
permissions to read the

$ORINETDB_HOME/config/orientdb-server-config.xml

configuration file. For more information, see OrientDB

Server Security.
S yntax:
LIST SERVER USERS

Example:
List configured users on a server:
orientdb>

LIST SERVER USERS

SERVER USERS
- 'root', permissions: *
- 'guest', permissions: connect,server.listDatabases,server.dblist

For more information, see
SET SERVER USER
DROP SERVER USER

For more information on other console commands, see Console Commands.

113

Commit

Console - COMMIT
Closes a transaction, committing the changes you have made to the database. Use the
don't want to save the changes you've made, use the

ROLLBACK

BEGIN

command to open a transaction. If you

command to revert the database state back to the point where you

opened the transaction.
For more information, see Transactions.
S yntax
COMMIT

Example
Initiate a transaction, using the
orientdb>

BEGIN

command:

BEGIN

Transaction 2 is running

For the sake of example, attempt to open another transaction:
orientdb>

BEGIN

Error: an active transaction is currently open (id=2). Commit or rollback
before starting a new one.

Insert data into the class
orientdb>

Account

, using an

INSERT

statement:

INSERT INTO Account (name) VALUES ('tx test')

Inserted record 'Account#9:-2{name:tx test} v0' in 0,000000 sec(s).

Commit the transaction to the database:
orientdb>

COMMIT

Transaction 2 has been committed in 4ms

Display the new content, using a
orientdb>

SELECT

query:

SELECT FROM Account WHERE name LIKE 'tx%'

---+---------+---------# | RID

| name

---+---------+---------0 | #9:1107 | tx test
---+---------+---------1 item(s) found. Query executed in 0.041 sec(s).

When a transaction is open, all new records use a temporary Record ID that features negative numbers. After the commit, they have a
permanent Record ID that uses with positive numbers.

114

Commit
For more information, see
Transactions
BEGIN
ROLLBACK

Console Commands

115

Config

Console - CONFIG
Displays the configuration information on the current database, as well as whether it is local or remote.
S yntax
CONFIG

Examples
Display the configuration of the current database:
orientdb>

CONFIG

REMOTE SERVER CONFIGURATION:
+------------------------------------+--------------------------------+
| NAME

| VALUE

|

+------------------------------------+--------------------------------+
| treemap.lazyUpdates

| 300

|

| db.cache.enabled

| false

|

| file.mmap.forceRetry

| 5

|

| treemap.optimizeEntryPointsFactor

| 1.0

|

| storage.keepOpen

| true

|

| treemap.loadFactor

| 0.7

|

| file.mmap.maxMemory

| 110000000

|

| network.http.maxLength

| 10000

|

| storage.cache.size

| 5000

|

| treemap.nodePageSize

| 1024

|

| ...

| ...

|

| treemap.entryPoints

| 30

|

+------------------------------------+--------------------------------+

You can change configuration variables displayed here using the
configuration variable, use the

CONFIG GET

CONFIG SET

command. To display the value set to one

command.

For more information on other commands, see Console Commands.

116

Config Get

Console - CONFIG GET
Displays the value of the requested configuration variable.
S yntax
CONFIG GET 



Defines the configuration variable you want to query.

Examples
Display the value to the
orientdb>

tx.log.fileType

configuration variable:

CONFIG GET tx.log.fileType

Remote configuration: tx.log.fileType = classic

You can display all configuration variables using the

CONFIG

command. To change the values, use the

CONFIG SET

command.

For more information on other commands, see Config Commands.

117

Config Set

Console - CONFIG SET
Updates a configuration variable to the given value.
S yntax
CONFIG SET  




Defines the configuration variable you want to change.

Defines the value you want to set.

Example
Display the current value for
orientdb>

tx.autoRetry

:

CONFIG GET tx.autoRetry

Remote configuration: tx.autoRetry = 1

Change the

tx.autoRetry

orientdb>

value to

5

:

CONFIG SET tx.autoRetry 5

Remote configuration value changed correctly.

Display new value:
orientdb>

CONFIG GET tx.autoRetry

Remote configuration: tx.autoRetry = 5

You can display all configuration variables with the
using the

CONFIG GET

CONFIG

command. You can view the current value on a configuration variable

command.

For more information on other commands, see Console Commands

118

Connect

Console - CONNECT
Opens a database.
S yntax
CONNECT   



Defines the URL of the database you want to connect to. It uses the format



Defines the mode you want to use in connecting to the database. It can be



Defines the path to the database.



:

plocal

or

remote

.

Defines the user you want to connect to the database with.



Defines the password needed to connect to the database, with the defined user.

Examples:
Connect to a local database as the user
orientdb>

admin

, loading it directly into the console:

CONNECT plocal:../databases/GratefulDeadConcerts admin my_admin_password

Connecting to database [plocal:../databases/GratefulDeadConcerts]...OK

Connect to a remote database:
orientdb>

CONNECT remote:192.168.1.1/GratefulDeadConcerts admin my_admin_password

Connecting to database [remote:192.168.1.1/GratefulDeadConcerts]...OK

For more information on other commands, see Console Commands.

119

Create Cluster

Console - CREATE CLUSTER
Creates a new cluster in the current database. The cluster you create can either be physical or in memory. OrientDB saves physical
clusters to disk. M emory clusters are volatile, so any records you save to them are lost, should the server be stopped.
S yntax
CREATE CLUSTER     []



Defines the name of the cluster.



Defines whether the cluster is



Defines the data segment you want to use.

DEFAULT

PHYSICAL

or

LOGICAL

.

Sets the cluster to the default data segment.



Defines the location for new cluster files, if applicable. Use



Defines where to add new cluster. Use

APPEND

DEFAULT

to save these to the database directory.

to create it as the last cluster. Leave empty to replace.

Example
Create a new cluster
orientdb>

documents

:

CREATE CLUSTER documents PHYSICAL DEFAULT DEFAULT APPEND

Creating cluster [documents] of type 'PHYSICAL' in database demo as last one...
PHYSICAL cluster created correctly with id #68

You can display all configured clusters in the current database using the
the

DROP CLUSTER

CLUSTERS

command. To delete an existing cluster, use

command.

For more information on other commands, see Console Commands

120

Create Database

Console - CREATE DATABASE
Creates and connects to a new database.
S yntax
CREATE DATABASE  [   []] [-restore=]



Defines the URL of the database you want to connect to. It uses the format



Defines the mode you want to use in connecting to the database. It can be



Defines the path to the database.



:

or

PLOCAL

REMOTE

.

Defines the user you want to connect to the database with.



Defines the password needed to connect to the database, with the defined user.




Defines the storage type that you want to use. You can choose between

Defines the database type. You can choose between

GRAPH

and

DOCUMENT

PLOCAL

and

. The default is

MEMORY
GRAPH

.

.

Examples
Create a local database
orientdb>

demo

:

CREATE DATABASE PLOCAL:/usr/local/orientdb/databases/demo

Creating database [plocal:/usr/local/orientdb/databases/demo]...
Connecting to database [plocal:/usr/local/orientdb/databases/demo]...OK
Database created successfully.
Current database is: plocal:/usr/local/orientdb/databases/demo
orientdb {db=demo}>

Create a remote database
orientdb>

trick

:

CREATE DATABASE REMOTE:192.168.1.1/trick root

E30DD873203AAA245952278B4306D94E423CF91D569881B7CAD7D0B6D1A20CE9 PLOCAL

Creating database [remote:192.168.1.1/trick ]...
Connecting to database [remote:192.168.1.1/trick ]...OK
Database created successfully.
Current database is: remote:192.168.1.1/trick
orientdb {db=trick}>

To create a static database to use from the server, see
To remove a database, see

DROP DATABASE

Server pre-configured storage types

.

. To change database configurations after creation, see

ALTER DATABASE

.

For more information on other commands, see Console Commands.
Incremental restore option
You can execute an incremental restore at creation time through the option

-restore

specifying as value the path where your backup is

placed. Let's suppose we want create a new fresh database "mydb" and restore data from a backup, located in

/tmp/backup

, performed

from another database in one shot. In this case we can type:

121

Create Database
orientdb> create database remote:localhost/mydb root root plocal graph -restore=/tmp/backup
Creating database [remote:localhost/mydb] using the storage type [plocal]...
Connecting to database [remote:localhost/mydb] with user 'admin'...OK
Database created successfully.
Current database is: remote:localhost/mydb

For further details on incremental backup and restore you can refer to the page Incremental Backup and Restore.

122

Create Index

Console - CREATE INDEX
Create an index on a given property. OrientDB supports three index algorithms and several index types that use these algorithms.
S B-Tree Algorithm
Does not allow duplicate keys, fails when it encounters duplicates.

UNIQUE

Does allow duplicate keys.

NOTUNIQUE

Indexes to any single word of text.

FULLTEXT

Does not allow duplicate keys, overwrites when it encounters duplicates.

DICTIONARY

Hash Index Algorithm
UNIQUE_HASH_INDEX

Does not allow duplicate keys, it fails when it encounters duplicates.

NOTUNIQUE_HASH_INDEX
FULLTEXT_HASH_INDEX

Does allow duplicate keys.
Indexes to any single word.

Does not allow duplicate keys, it overwrites when it encounters duplicates.

DICTIONARY

Lucene Engine
Full text index type using the Lucene Engine.

LUCENE
SPATIAL

Spatial index using the Lucene Engine.

For more information on indexing, see Indexes.
S yntax
CREATE INDEX  [ON  ()]  []



Defines a logical name for the index. Optionally, you can use the format

.

, to create

an automatic index bound to the schema property.
NOTE Because of this feature, index names cannot contain periods.


Defines the class to index. The class must already exist in the database schema.



Defines a comma-separated list of properties that you want to index. These properties must already exist in the

database schema.



Defines the index type that you want to use.

Defines the key that you want to use. On automatic indexes, this is auto-determined by reading the target schema

property where you create the index. When not specified for manual indexes, OrientDB determines the type at run-time during the
first insertion by reading the type of the class.
Examples
Create an index that uses unique values and the SB-Tree index algorithm:
orientdb>

The SQL

CREATE INDEX jobs.job_id UNIQUE

CREATE INDEX

page provides more information on creating indexes. M ore information on indexing can be found under

Indexes. Further SQL information can be found under

SQL Commands

.

For more information on other commands, see Console Commands

123

Create Link

Console - CREATE LINK
Creates a link between two or more records of the Document type.
S yntax
CREATE LINK  FROM . TO .



Defines the logical name of the property for the link. When not expressed, it overwrites the



field.


Defines the source class for the link.




Defines the source property for the link.

Defines the target class for the link.



Defines the target property for the link.

Examples
Create a 1-n link connecting comments to posts:
orientdb>

CREATE LINK comments FROM Comments.!PostId TO Posts.Id INVERSE

Understanding Links
Links are useful when importing data from a Relational database. In the Relational world, the database resolves relationships as foreign
keys. For instance, consider the above example where you need to show instances in the class
instances in class

Comment

. That is,

Post 1 ---> * Comment

Post

as having a 1-n relationship to

.

In a Relational database, where classes are tables, you might have something like this:
reldb>

SELECT * FROM Post;

+----+----------------+
| Id | Title

|

+----+----------------+
| 10 | NoSQL movement |
| 20 | New OrientDB

|

+----+----------------+
2 rows in (0.01 sec)
reldb>

SELECT * FROM Comment;

+----+--------+--------------+
| Id | PostId | Text

|

+----+--------+--------------+
|

0 |

10

| First

|

|

1 |

10

| Second

|

| 21 |

10

| Another

|

| 41 |

20

| First again

|

| 82 |

20

| Second Again |

+----+--------+--------------+
5 rows in sec (0.03 sec)

In OrientDB, you have a direct relationship in your object model. Navigation runs from
the Relational database model). For this reason, you need to create a link as

INVERSE

Post

to

Comment

and not vice versa, (as in

.

124

Create Link
For more information on SQL commands, see SQL Commands.
For more information on other commands, see Console Commands.

125

Create Property

Console - CREATE PROPERTY
Creates a new property on the given class. The class must already exist.
S yntax
CREATE PROPERTY .  [][ ]



Defines the class you want to create the property in.



Defines the logical name of the property.



Defines the type of property you want to create. Several options are available:




Defines the container type, used in container property types.
Defines the container class, used in container property types.

NOTE: There are several property and link types available.
Examples
Create the property
orientdb>

name

on the class

tags

in the class

Profile

, using an embedded list of the string type.

CREATE PROPERTY Profile.tags EMBEDDEDLIST STRING

Create the embedded map property
orientdb>

, of the string type:

CREATE PROPERTY User.name STRING

Create a list of strings as the property
orientdb>

User

friends

in the class

Profile

, link it to the class

Profile

.

CREATE PROPERTY Profile.friends EMBEDDEDMAP Profile

This forms a circular reference.
To remove a property, use the

DROP PROPERTY

command.

Property Types
When creating properties, you need to define the property type, so that OrientDB knows the kind of data to expect in the field. There
are several standard property types available:

BOOLEAN

INTEGER

SHORT

LONG

FLOAT

DATE

STRING

EMBEDDED

LINK

BYTE

BINARY

DOUBLE

In addition to these, there are several more property types that function as containers. These form lists, sets and maps. Using container
property types requires that you also define a link type or class.

EMBEDDEDLIST

EMBEDDEDSET

EMBEDDEDMAP

LINKLIST

LINKSET

LINKMAP

Link Types
The link types available are the same as those available as the standard property types:

126

Create Property

BOOLEAN

INTEGER

SHORT

LONG

FLOAT

DOUBLE

DATE

STRING

BINARY

EMBEDDED

LINK

BYTE

For more information, see SQL Commands and Console Commands.

127

Declare Intent

Console - DECLARE INTENT
Declares an intent for the current database. Intents allow you to tell the database what you want to do.
S yntax
DECLARE INTENT 


NULL

Defines the name of the intent. OrientDB supports three intents:

Removes the current intent.

MASSIVEINSERT
MASSIVEREAD

Examples
Declare an intent for a massive insert:
orientdb>

DECLARE INTENT MASSIVEINSERT

After the insert, clear the intent:
orientdb>

DECLARE INTENT NULL

For more information on other commands, see Console Commands.

128

Delete

Console - DELETE
Remove one or more records from the database. You can determine which records get deleted using the

WHERE

clause.

S yntax
DELETE FROM  [LOCK ] [RETURN ]
[WHERE *] [LIMIT ] [TIMEOUT ]

Defines the target from which you want to delete records. Use one of the following target names:





Determines what class you want to delete from.

CLUSTER:
INDEX:
LOCK 
DEFAULT
RECORD

Defines how the record locks between the load and deletion. It takes one of two types:

Operation uses no locks. In the event of concurrent deletions, the M VCC throws an exception.
Locks the record during the deletion.

RETURN 
COUNT
BEFORE

Defines what the Console returns. There are two supported return types:

Returns the number of deleted records. This is the default return type.
Returns the records before the deletion.

WHERE 
LIMIT

Determines what cluster you want to delete from.

Determines what index you want to delete from.

Defines the condition used in selecting records for deletion.

Defines the maximum number of records to delete.

TIMEOUT

Defines the time-limit to allow the operation to run before it times out.

NOTE: When dealing with vertices and edges, do not use the standard SQL
integrity. Instead, use the

DELETE VERTEX

or the

DELETE EDGE

DELETE

command. Doing so can disrupt graph

commands.

Examples
Remove all records from the class
orientdb>

Profile

, where the surname is unknown, ignoring case:

DELETE FROM Profile WHERE surname.toLowerCase() = 'unknown'

For more information on other commands, see SQL Commands and Console Commands.

129

Dictionary Get

Console - DICTIONARY GET
Displays the value of the requested key, loaded from the database dictionary.
S yntax
DICTIONARY GET 



Defines the key you want to access.

Example
In a dictionary of U.S. presidents, display the entry for Barack Obama:
orientdb>

DICTIONARY GET obama

------------------------------------------------------------------------Class: Person id: 5:4 v.1
------------------------------------------------------------------------parent: null
children : [Person@5:5{parent:Person@5:4,children:null,name:Malia Ann,
surname:Obama,city:null}, Person@5:6{parent:Person@5:4,
children:null,name:Natasha,surname:Obama,city:null}]
name : Barack
surname : Obama
city : City@-6:2{name:Honolulu}
-------------------------------------------------------------------------

You can display all keys stored in a database using the

DICTIONARY KEYS

command. For more information on indexes, see

Indexes.
For more information on other commands, see Console Commands.

130

Dictionary Keys

Console - DICTIONARY KEYS
Displays all the keys stored in the database dictionary.
S yntax
DICTIONARY KEYS

Example
Display all the keys stored in the database dictionary:
orientdb>

DICTIONARY KEYS

Found 4 keys:
#0: key-148
#1: key-147
#2: key-146
#3: key-145

To load the records associated with these keys, use the

DICTIONARY GET

command. For more information on indexes, see

Indexes.
For more information on other commands, see Console Commands.

131

Dictionary Put

Console - DICTIONARY PUT
Binds a record to a key in the dictionary database, making it accessible to the

DICTIONARY GET

command.

S yntax
DICTIONARY PUT  



Defines the key you want to bind.



Defines the ID for the record you want to bind to the key.

Example
In the database dictionary of U.S. presidents, bind the record for Barack Obama to the key
orientdb>

obama

:

DICTIONARY PUT obama 5:4

-----------------------------------------------------------------------Class: Person

id: 5:4

v.1

-----------------------------------------------------------------------parent : null
children : [Person@5:5{parent:Person@5:4,children:null,name:Malia Ann,
surname:Obama,city:null}, Person@5:6{parent:Person@5:4,
children:null,name:Natasha,surname:Obama,city:null}]
name : Barack
surname : Obama
city : City@-6:2{name:Honolulu}
-----------------------------------------------------------------------The entry obama=5:4 has been inserted in the database dictionary

To see all the keys stored in the database dictionary, use the

DICTIONARY KEYS

command. For more information on dictionaries

and indexes, see Indexes.
For more information on other commands, see Console Commands.

132

Dictionary Remove

Console - DICTIONARY REMOVE
Removes the association from the database dictionary.
S yntax
DICTIONARY REMOVE 



Defines the key that you want to remove.

Example
In a database dictionary of U.S. presidents, remove the key for Barack Obama:
orientdb>

DICTIONARY REMOVE obama

Entry removed from the dictionary. Last value of entry was:
-----------------------------------------------------------------------Class: Person

id: 5:4

v.1

-----------------------------------------------------------------------parent : null
children : [Person@5:5{parent:Person@5:4,children:null,name:Malia Ann,
surname:Obama,city:null}, Person@5:6{parent:Person@5:4,
children:null,name:Natasha,surname:Obama,city:null}]
name : Barack
surname : Obama
city : City@-6:2{name:Honolulu}
------------------------------------------------------------------------

You can display information for all keys stored in the database dictionary using the

DICTIONARY KEY

command. For more

information on dictionaries and indexes, see Indexes.
For more information on other commands, see Console Commands.

133

Disconnect

Console - DISCONNECT
Closes the currently opened database.
S yntax
DISCONNECT

Example
Disconnect from the current database:
orientdb>

DISCONNECT

Disconnecting from the database [../databases/petshop/petshop]...OK

To connect to a database, see

CONNECT

. For more information on other commands, see Console Commands.

134

Display Record

Console - DISPLAYS RECORD
Displays details on the given record from the last returned result-set.
S yntax
DISPLAY RECORD 



Defines the relative position of the record in the last result-set.

Example
Query the database on the class
orientdb>

Person

to generate a result-set:

SELECT FROM Person

---+-----+--------+----------+-----------+-----------+-----# | RID | PARENT | CHILDREN | NAME

| SURNAME

| City

---+-----+--------+----------+-----------+-----------+-----0 | 5:0 | null

| null

| Giuseppe

| Garibaldi | -6:0

1 | 5:1 | 5:0

| null

| Napoleon

| Bonaparte | -6:0

2 | 5:2 | 5:3

| null

| Nicholas

| Churchill | -6:1

3 | 5:3 | 5:2

| null

| Winston

| Churchill | -6:1

4 | 5:4 | null

| [2]

| Barack

| Obama

| -6:2

5 | 5:5 | 5:4

| null

| Malia Ann | Obama

| null

6 | 5:6 | 5:4

| null

| Natasha

| null

| Obama

---+-----+--------+----------+-----------+-----------+-----7 item(s) found. Query executed in 0.038 sec(s).

With the result-set ready, display record number four in the result-set, (for M alia Ann Obama):
orientdb>

DISPLAY RECORD 5

-----------------------------------------------------------------------Class: Person

id: 5:5

v.0

-----------------------------------------------------------------------parent : Person@5:4{parent:null,children:[Person@5:5, Person@5:6],
name:Barack,surname:Obama,city:City@-6:2}
children : null
name : Malia Ann
surname : Obama
city : null
------------------------------------------------------------------------

For more information on other commands, see Console Commands.

135

Display Raw Record

Console - DISPLAYS RAW RECORD
Displays details on the given record from the last returned result-set in a binary format.
S yntax
DISPLAY RAW RECORD 



Defines the relative position of the record in the last result-set.

Example
Query the database on the class

V

to generate a result-set:

orientdb {db=GratefulDeadConcerts}>

SELECT song_type, name, performances FROM V LIMIT 6

-----+-------+--------+----------+-------------------------+-------------#

| @RID

| @CLASS | song_type | name

| performances

-----+-------+--------+----------+-------------------------+-------------0

| #9:1

| V

| cover

| HEY BO DIDDLEY

| 5

1

| #9:2

| V

| cover

| IM A MAN

| 1

2

| #9:3

| V

| cover

| NOT FADE AWAY

| 531

3

| #9:4

| V

| original

| BERTHA

| 394

4

| #9:5

| V

| cover

| GOING DOWN THE ROAD... | 293

5

| #9:6

| V

| cover

| MONA

| 1

6

| #9:7

| V

| null

| Bo_Diddley

| null

-----+-------+--------+-----------+------------------------+------------LIMIT EXCEEDED: resultset contains more items not displayed (limit=6)
6 item(s) found. Query executed in 0.136 sec(s).

Display raw record on the song "Hey Bo Diddley" from the result-set:
orientdb {db=GratefulDeadConcerts}>

DISPLAY RAW RECORD 0

Raw record content. The size is 292 bytes, while settings force to print first 150
bytes:
Vsong_typenametypeperformancesout_followed_byout_written_byout_sung_byin_followed_byco
verHEY BO D

For more information on other commands available, see Console Commands.

136

Drop Cluster

Console - DROP CLUSTER
Removes a cluster from the database completely, deleting it with all records and caches in the cluster.
S yntax
DROP CLUSTER 



Defines the name of the cluster you want to drop.

NOTE: When you drop a cluster, the cluster and all records and caches in the cluster are gone. Unless you have made backups,
there is no way to restore the cluster after you drop it.
Examples
Drop a cluster
orientdb>

person

from the current, local database:

DROP CLUSTER person

This removes both the cluster

Person

You can create a new cluster using the

and all records of the
CREATE CLUSTER

Person

class in that cluster.

command.

For information on other commands, see SQL and Console commands.

137

Drop Database

Console - DROP DATABASE
Removes a database completely. If the database is open and a database name not given, it removes the current database.
S yntax
DROP DATABASE [  ]



Defines the server user. This user must have the privileges to drop the database.



Defines the password for the server user.

NOTE: When you drop a database, it deletes the database and all records, caches and schema information it contains. Unless you
have made backups, there is no way to restore the database after you drop it.
Examples
Remove the current local database:
orientdb>

DROP DATABASE

Remove the database
orientdb>

demo

at localhost:

DROP DATABASE REMOTE:localhost/demo root root_password

You can create a new database using the
DATABASE

CREATE DATABASE

command. To make changes to an existing database, use the

ALTER

command.

For more information on other commands, see SQL and Console commands.

138

Drop Server User

Console - DROP SERVER USER
Removes a user from the server. In order to do so, the current system user running the Console, must have permissions to write to the
$ORIENTDB_HOME/config/orientdb-server-config.xmL

configuration file.

S yntax
DROP SERVER USER 



Defines the user you want to drop.

NOTE: For more information on server users, see OrientDB Server Security.
This feature was introduced in version 2.2.
Example
Remove the user
orientdb>

editor

from the Server:

DROP SERVER USER editor

Server user 'editor' dropped correctly

To view the current server users, see the
USER

LIST SERVER USERS

command. To create or update a server user, see the

SET SERVER

command.

For more information on other commands, see Console Commands.

139

Export Database

Console - EXPORT
Exports the current database to a file. OrientDB uses a JSON-based Export Format. By default, it compresses the file using the GZIP
algorithm.
With the

IMPORT

command, this allows you to migrate the database between different versions of OrientDB without losing data.

If you receive an error about the database version, export the database using the same version of OrientDB that has generated the
database.
Bear in mind, exporting a database browses it, rather than locking it. While this does mean that concurrent operations can execute during
the export, it also means that you cannot create an exact replica of the database at the point when the command is issued. In the event
that you need to create a snapshot, use the

BACKUP

You can restore a database from an export using the

command.
IMPORT

.

NOTE: While the export format is JSON, there are some constraints in the field order. Editing this file or adjusting its indentation
may cause imports to fail.
S yntax
By default, this command exports the full database. Use its options to disable the parts you don't need to export.
EXPORT DATABASE 
[-excludeAll]
[-includeClass=*]
[-excludeClass=*]
[-includeCluster=*]
[-excludeCluster=*]
[-includeInfo=]
[-includeClusterDefinitions=]
[-includeSchema=]
[-includeSecurity=]
[-includeRecords=]
[-includeIndexDefinitions=]
[-includeManualIndexes=]
[-compressionLevel=<0-9>]
[-compressionBuffer=]

Defines the path to the output file.


-excludeAll

Sets the export to exclude everything not otherwise included through command options
Export includes certain classes, specifically those defined by a space-separated list. In case you specify multiple

-includeClass

class names, you have to wrap the list between quotes, eg.

-includeClass="Foo Bar Baz"

Export excludes certain classes, specifically those defined by a space-separated list.

-excludeClass

-includeCluster

Export includes certain clusters, specifically those defined by a space-separated list.

-excludeCluster

Export excludes certain clusters, specifically those defined by a space-separated list.

-includeInfo

Defines whether the export includes database information.

-includeClusterDefinitions
-includeSchema

Defines whether the export includes the database schema.
Defines whether the export includes database security parameters.

-includeSecurity
-includeRecords

Defines whether the export includes cluster definitions.

Defines whether the export includes record contents.

-includeIndexDefinitions
-includeManualIndexes
-compressionLevel

Defines whether the export includes the database index definitions.

Defines whether the export includes manual index contents.

Defines the compression level to use on the export, in a range between

(maximum compression). The default is
-compressionBuffer

1

0

(no compression) and

9

. (Feature introduced in version 1.7.6.)

Defines the compression buffer size in bytes to use in compression. The default is 16kb. (Feature introduced

in version 1.7.6.)
Examples
Export the current database, including everything:

140

Export Database

orientdb>

EXPORT DATABASE C:\temp\petshop.export

Exporting current database to: C:\temp\petshop.export...
Exporting database info...OK
Exporting dictionary...OK
Exporting schema...OK
Exporting clusters...
- Exporting cluster 'metadata' (records=11) -> ...........OK
- Exporting cluster 'index' (records=0) -> OK
- Exporting cluster 'default' (records=779) -> OK
- Exporting cluster 'csv' (records=1000) -> OK
- Exporting cluster 'binary' (records=1001) -> OK
- Exporting cluster 'person' (records=7) -> OK
- Exporting cluster 'animal' (records=5) -> OK
- Exporting cluster 'animalrace' (records=0) -> OK
- Exporting cluster 'animaltype' (records=1) -> OK
- Exporting cluster 'orderitem' (records=0) -> OK
- Exporting cluster 'order' (records=0) -> OK
- Exporting cluster 'city' (records=3) -> OK
Export of database completed.

Export the current database, including only its functions:
orientdb>

EXPORT DATABASE functions.gz -includeClass=OFunction -includeInfo=FALSE

-includeClusterDefinitions=FALSE -includeSchema=FALSE
-includeIndexDefinitions=FALSE -includeManualIndexes=FALSE

Alternatively, you can simplify the above by excluding all, then including only those features that you need. For instance, export
the current database, including only the schema:
orientdb>

EXPORT DATABASE schema.gz -excludeALL -includeSchema=TRUE

Export API
In addition to the Console, you can also trigger exports through Java and any other language that runs on the JVM , by using the
ODatabaseExport class.
For example:
ODatabaseDocumentTx db = new ODatabaseDocumentTx("plocal:/temp/mydb");
db.open("admin", "admin");
try{
OCommandOutputListener listener = new OCommandOutputListener() {
@Override
public void onMessage(String iText) {
System.out.print(iText);
}
};
ODatabaseExport export = new ODatabaseExport(db, "/temp/export", listener);
export.exportDatabase();
export.close();
} finally {
db.close();
}

141

Export Database
For more information on backups and restores, imports and exports, see the following commands:
IM PORT DATABASE
BACKUP DATABASE
RESTORE DATABASE
as well as the following pages:
Export File Format
ODatabaseExport

Java Class

For more information on other commands, see Console Commands.

142

Export Record

Console - EXPORT RECORD
Exports the current record, using the requested format. In the event that you give a format that OrientDB does not support, it provides
a list of supported formats.
S yntax
EXPORT RECORD 



Defines the export format you want to use.

Examples
Use

SELECT

to create a record for export:

orientdb>

SELECT name, surname, parent, children, city FROM Person WHERE

name='Barack' AND surname='Obama'

---+-----+--------+---------+--------+------------+-----# | RID | name

| surname | parent | children

| city

---+-----+--------+---------+--------+------------+-----0 | 5:4 | Barack | Obama

| null

| [5:5, 5:6] | -6:2

---+-----+--------+---------+--------+------------+------

Export JSON data from this record:
orientdb>

EXPORT RECORD JSON

{
'name': 'Barack',
'surname': 'Obama',
'parent': null,
'children': [5:5, 5:6],
'city': -6:2
}

Use a bad format value to determine what export formats are available on your database:

orientdb>

EXPORT RECORD GIBBERISH

ERROR: Format 'GIBBERISH' was not found.
Supported formats are:
- json
- ORecordDocument2csv

For more information on other commands, see Console Commands.

143

Freeze DB

Console - FREEZE DATABASE
Flushes all cached content to disk and restricts permitted operations to read commands. With the exception of reads, none of the
commands made on a frozen database execute. It remains in this state until you run the

RELEASE

command.

Executing this command requires server administration rights. You can only execute it on remote databases. If you would like to freeze or
release a local database, use the

ODatabase.freeze()

and

ODatabase.release()

methods directly through the OrientDB API.

You may find this command useful in the event that you would like to perform backups on a live database. To do so, freeze the
database, perform a file system snapshot, then release the database. You can now copy the snapshot anywhere you want.
This works best when the backup doesn't take very long to run.
S yntax
FREEZE DATABASE

Example
Freezes the current database:
orientdb>

FREEZE DATABASE

To unfreeze a database, use the

RELEASE DATABASE

command.

For more information on other commands, see SQL and Console commands.

144

Get

Console - GET
Returns the value of the requested property.
S yntax
GET 

Defines the name of the property.



Example
Find the default limit on your database:
orientdb>

GET LIMIT

limit = 20

To display all available properties configured on your database, use the

PROPERTIES

command.

For more information on other commands, see Console Commands.

145

Gremlin

Console - GREMLIN
Executes commands in the Gremlin language from the Console.
Gremlin is a graph traversal language. OrientDB supports it from the Console, API and through a Gremlin shell launched from
$ORIENTDB_HOME/bin/gremlin.sh

.

S yntax
GREMLIN 



Defines the commands you want to know.

NOTE: OrientDB parses Gremlin commands as multi-line input. It does not execute the command until you type
mind, the

end

end

. Bear in

here is case-sensitive.

Examples
Create a vertex using Gremlin:
orientdb>

gremlin

[Started multi-line command.
orientdb>

v1 = g.addVertex();

orientdb>

end

Type just 'end' to finish and execute.]

v[#9:0]
Script executed in 0,100000 sec(s).

For more information on the Gremlin language, see Gremlin. For more information on other commands, see Console Commands.

146

Import Database

Console - IMPORT
Imports an exported database into the current one open. Import process doesn't lock the database, so any concurrent operations are
allowed, but they could interfer in the import process causing errors.
The input file must use the JSON Export Format, as generated by the

EXPORT

command. By default, this file is compressed using the

GZIP algorithm.
With

EXPORT

, this command allows you to migrate between releases without losing data, by exporting data from the old version and

importing it into the new version.
S yntax
IMPORT DATABASE  [-format = ]
[-preserveClusterIDs = ]
[-deleteRIDMapping = ]
[-merge = ]
[-migrateLinks = ]
[-rebuildIndexes = ]



Is the input file format. If not specified, OrientDB tries to recognize it. The available formats are (since v2.2.8):

orientdb, the OrientDB export file format
graphml, for Graph XM L
graphson, for Graph JSON


Defines the path to the file you want to import.

-preserveClusterIDs

Defines whether you want to preserve cluster ID's during the import. When turned off, the import creates

temporary cluster ID's, which can sometimes fail. This option is only valid with PLocal storage.
Defines whether you want to preserve the dictionary index used by the import to map old RIDs to new RIDs.

-deleteRIDMapping

The index name is
-merge

___exportImportRIDMap

and you could use in your application. By default the index is removed after the import.

Defines whether you want to merge the import with the data already in the current database. When turned off, the default,

the import overwrites current data, with the exception of security classes, (

ORole

,

OUser

,

OIdentity

), which it always

preserves. This feature was introduced in version 1.6.1.
-migrateLinks

Defines whether you want to migrate links after the import. When enabled, this updates all references from the old

links to the new Record ID's. By default, it is enabled. Advisable that you only turn it off when merging and you're certain no other
existent records link to those you're importing. This feature was introduced in version 1.6.1.
-rebuildIndexes

Defines whether you want to rebuild indexes after the import. By default, it does. You can set it to false to

speed up the import, but do so only when you're certain the import doesn't affect indexes. This feature was introduced in version
1.6.1.
Example
Import the database

petshop.export

:

147

Import Database

orientdb>

IMPORT DATABASE C:/temp/petshop.export -preserveClusterIDs=true

Importing records...
- Imported records into the cluster 'internal': 5 records
- Imported records into the cluster 'index': 4 records
- Imported records into the cluster 'default': 1022 records
- Imported records into the cluster 'orole': 3 records
- Imported records into the cluster 'ouser': 3 records
- Imported records into the cluster 'csv': 100 records
- Imported records into the cluster 'binary': 101 records
- Imported records into the cluster 'account': 1005 records
- Imported records into the cluster 'company': 9 records
- Imported records into the cluster 'profile': 9 records
- Imported records into the cluster 'whiz': 1000 records
- Imported records into the cluster 'address': 164 records
- Imported records into the cluster 'city': 55 records
- Imported records into the cluster 'country': 55 records
- Imported records into the cluster 'animalrace': 3 records
- Imported records into the cluster 'ographvertex': 102 records
- Imported records into the cluster 'ographedge': 101 records
- Imported records into the cluster 'graphcar': 1 records

For more information on backups, restores, and exports, see:
ODatabaseImport

BACKUP

,

RESTORE

and

EXPORT

commands, and the

Java class. For the JSON format, see Export File Format.

For more information on other commands, see Console Commands.

Import API
In addition to the Console, you can also manage imports through the Java API, and with any language that runs on top of the JVM ,
using the

ODatabaseImport

class.

ODatabaseDocumentTx db = new ODatabaseDocumentTx("plocal:/temp/mydb");
db.open("admin", "admin");
try{
OCommandOutputListener listener = new OCommandOutputListener() {
@Override
public void onMessage(String iText) {
System.out.print(iText);
}
};
ODatabaseImport import = new ODatabaseImport(db, "/temp/export/export.json.gz", listener);
import.importDatabase();
import.close();
} finally {
db.close();
}

Troubleshooting
Validation Errors
Occasionally, you may encounter validation errors during imports, usually shown as an
with version 2.2, you can disable validation at the database-level using the

OValidationException

ALTER DATABASE

exception. Beginning

command, to allow the import to go

through.
1. Disable validation for the current database:

148

Import Database

orientdb>

ALTER DATABASE validation false

2. Import the exported database:
orientdb>

IMPORT DATABASE /path/to/my_data.export -preserveClusterIDs=TRUE

3. Re-enable validation:
orientdb>

ALTER DATABASE validation true

Cluster ID's
During imports you may occasionally encounter an error that reads:

Imported cluster 'XXX' has id=6 different from the original: 5

Typically occurs in databases that were created in much older versions of OrientDB. You can correct it using the
class

ORIDs

DROP CLASS

.

on the

, then attempting the import again.

1. Import the database:
orientdb>

IMPORT DATABASE /path/to/old_data.export

Importing records...
- Creating cluster 'company'...Error on database import happened just before line
16, column 52 com.orientechnologies.orient.core.exception.OConfigurationException:
Imported cluster 'company has id=6 different from the original: 5 at
com.orientechnologies.orient.core.db.tool.ODatabaseImport.importClusters(
ODatabaseImport.java:500) at
com.orientechnologies.orient.core.db.tool.ODatabaseIMport.importDatabase(
ODatabaseImport.java:121)

2. Drop the

class:

ORIDs

orientdb>

DROP CLASS ORIDs

3. Import the database:
orientdb>

IMPORT DATABASE /path/to/old_data.export

The database now imports without error.

149

Indexes

Console - INDEXES
Displays all indexes in the current database.
S yntax
INDEXES

Example
Display indexes in the current database:
orientdb {db=GratefulDeadConcerts}>

INDEXES

INDEXES
--------------+------------+-------+--------+--------NAME

| TYPE

| CLASS | FIELDS | RECORDS

--------------+------------+-------+--------+--------dictionary

|

0

Group.Grp_Id | UNIQUE

| DICTIONARY |

| Group | Grp_Id |

|

1

ORole.name

| UNIQUE

| ORole | name

|

3

OUser.name

| UNIQUE

| OUser | name

|

4

--------------+------------+----------------+--------TOTAL = 4

8

------------------------------------------------------

For more information on other commands, see Console Commands.

150

Info

Console - INFO
Displays all information on the current database.
S yntax
INFO

Example
Display information on database

petshop

orientdb {db=petshop}>

:

INFO

Current database: ../databases/petshop/petshop
CLUSTERS:
------------+------+----------+---------NAME

|

ID

| TYPE

| ELEMENTS

------------+------+----------+---------metadata

|

0 | Physical |

11

index

|

1 | Physical |

0

default

|

2 | Physical |

779

csv

|

3 | Physical |

1000

binary

|

4 | Physical |

1001

person

|

5 | Physical |

7

animal

|

6 | Physical |

5

animalrace |

-2 | Logical

|

0

animaltype |

-3 | Logical

|

1

orderitem

|

-4 | Logical

|

0

order

|

-5 | Logical

|

0

city

|

-6 | Logical

|

3

------------+------+----------+---------TOTAL

2807

----------------------------------------CLASSES:
------------+----+------------+---------NAME

| ID | CLUSTERS

| ELEMENTS

------------+----+------------+---------Person

|

0 | person

|

7

Animal

|

1 | animal

|

5

AnimalRace |

2 | AnimalRace |

0

AnimalType |

3 | AnimalType |

1

OrderItem

|

4 | OrderItem

|

0

Order

|

5 | Order

|

0

City

|

6 | City

|

3

------------+----+------------+---------TOTAL

16

-----------------------------------------

For more information on other commands, see Console Commands.

151

Info Class

Console - INFO CLASS
Displays all information on givne class.
S yntax
INFO CLASS 



Defines what class you want information on.

Example
Display information on class
orientdb>

Profile

INFO CLASS Profile

Default cluster......: profile (id=10)
Supported cluster ids: [10]
Properties:
--------+----+----------+-----------+---------+-----------+----------+-----+---NAME

| ID | TYPE

| LINK TYPE | INDEX

| MANDATORY | NOT NULL | MIN | MAX

--------+----+----------+-----------+---------+-----------+----------+-----+---nick

|

3 | STRING

| null

|

| false

| false

| 3

| 30

name

|

2 | STRING

| null

|NOTUNIQUE| false

| false

| 3

| 30

surname|

1 | STRING

| null

|

| false

| false

| 3

| 30

| ...

| ...

| ...

| ...

| ...

|...

| ...

|

| false

| false

|

|

...

|

photo

|

0 | TRANSIENT| null

--------+----+----------+-----------+---------+-----------+----------+-----+----

For more information on other commands, see Console Commands.

152

Info Property

Console - INFO PROPERTY
Displays all information on the given property.
S yntax
INFO PROPERTY .



Defines the class to which the property belongs.



Defines the property you want information on.

Example
Display information on the property
orientdb>

name

in the class

OUser

:

INFO PROPERTY OUser.name

PROPERTY 'OUser.name'
Type.................: STRING
Mandatory............: true
Not null.............: true
Read only............: false
Default value........: null
Minimum value........: null
Maximum value........: null
REGEXP...............: null
Collate..............: {OCaseInsensitiveCollate : name = ci}
Linked class.........: null
Linked type..........: null
INDEXES (1 altogether)
--------------------+-----------NAME

| PROPERTIES

--------------------+-----------OUser.name

| name

--------------------+------------

For more information on other commands, see Console Commands.

153

Insert

Console - INSERT
Inserts a new record into the current database. Remember, OrientDB can work in schema-less mode, meaning that you can create any
field on the fly.
S yntax
INSERT INTO <|CLUSTER:> () VALUES (  )



Defines the class you want to create the record in.

CLUSTER:



Defines the cluster you want to create the record in.

Defines the fields you want to add the records to, in a comma-separated list.
Defines the values you want to insert, in a comma-separated list.

Examples
Insert a new record into the class
orientdb>

Profile

, using the name

Jay

and surname

Miner

:

INSERT INTO Profile (name, surname) VALUES ('Jay', Miner')

Inserted record in 0,060000 sec(s).

Insert a new record into the class
orientdb>

Employee

, while defining a relationship:

INSERT INTO Employee (name, boss) VALUES ('Jack', 11:99)

Insert a new record, adding a collection of relationships:
orientdb>

INSERT INTO Profile (name, friends) VALUES ('Luca', [10:3, 10:4])

For more information on other commands, see SQL and Console commands.

154

Js

Console - JS
Executes commands in the Javascript language from the Console. Look also Javascript Command.
S yntax
JS 



Defines the commands you want to execute.

Interactive Mode You can execute a command in just one line (
executing

JS

JS print('Hello World!')

) or enable the interactive input by just

and then typing the Javascript expression as multi-line inputs. It does not execute the command until you type

Bear in mind, the

end

end

.

here is case-sensitive.

Examples
Execute a query and display the result:
orientdb>

js

[Started multi-line command.

Type just 'end' to finish and execute.]

orientdb>

var r = db.query('select from ouser');

orientdb>

for(var i=0;i

orientdb> print( r[i] );
orientdb> }
orientdb> end
OUser#5:0{roles:[1],status:ACTIVE,password:{PBKDF2WithHmacSHA256}C08CE0F5160EA4050B8F10EDBB86F06EB0A2EE82DF73A340:BC1B604
0727C1E11E3A961A1B2A49615C96938710AF17ADD:65536,name:admin} v1
OUser#5:1{name:reader,password:{PBKDF2WithHmacSHA256}41EF9B675430D215E0970AFDEB735899B6665DF44A29FE98:5BC48B2D20752B12B5E
32BE1F22C6C85FF7CCBEFB318B826:65536,status:ACTIVE,roles:[1]} v1
OUser#5:2{name:writer,password:{PBKDF2WithHmacSHA256}FA0AD7301EA2DB371355EB2855D63F4802F13858116AB82E:18B8077E1E63A45DB0A
3347F91E03E4D2218EA16E5100105:65536,status:ACTIVE,roles:[1]} v1
Client side script executed in 0.142000 sec(s). Value returned is: null

For more information on the Javascript execution, see Javascript Command. For more information on other commands, see
Console Commands.

155

Jss

Console - JSS
Executes commands on OrientDB Server in the Javascript language from the Console. Look also Javascript Command.
S yntax
JSS 



Defines the commands you want to execute.

Interactive Mode You can execute a command in just one line (
executing

JSS

JSS print('Hello World!')

) or enable the interactive input by just

and then typing the Javascript expression as multi-line inputs. It does not execute the command until you type

Bear in mind, the

end

end

.

here is case-sensitive.

Examples
Execute a query and display the result:
orientdb>

jss

[Started multi-line command.

Type just 'end' to finish and execute.]

orientdb>

var r = db.query('select from ouser');

orientdb>

for(var i=0;i

orientdb> print( r[i] );
orientdb> }
orientdb> end
Server side script executed in 0.146000 sec(s). Value returned is: null

In this case the output will be displayed on the server console.
For more information on the Javascript execution, see Javascript Command. For more information on other commands, see
Console Commands.

156

List Databases

Console - LIST DATABASES
Displays all databases hosted on the current server. Note that this command requires you connect to the OrientDB Server.
S yntax
LIST DATABASES

Example
Connect to the server:
orientdb>

CONNECT REMOTE:localhost admin admin_password

List the databases hosted on the server:
orientdb {server=remote:localhost/}>

LIST DATABASES

Found 4 databases:
* ESA (plocal)
* Napster (plocal)
* Homeland (plocal)
* GratefulDeadConcerts (plocal)

For more information on other commands, see Console Commands.

157

List Connections

Console - LIST CONNECTIONS
Displays all active connections to the OrientDB Server. Command introduced in version 2.2. The connections as per server, so you
should connect to the server, not to the database.
S yntax
LIST CONNECTIONS

Example
List the current connections to the OrientDB Server:
orientdb {server=remote:localhost/}>

LIST CONNECTIONS

---+----+--------------+------+-------------------+--------+-----+--------+-------# | ID |REMOTE_ADDRESS|PROTOC|LAST_OPERATION_ON

|DATABASE|USER |COMMAND |TOT_REQS

---+----+--------------+------+-------------------+--------+-----+--------+-------0 | 17 |/127.0.0.1

|binary|2015-10-12 19:22:34|-

|-

|info

| 1

1 | 16 |/127.0.0.1

|binary|1970-01-01 01:00:00|-

|-

|-

| 0

5 | 1

|http

|admin|Listen

| 32

|/127.0.0.1

|1970-01-01 00:59:59|pokec

---+----+--------------+------+-------------------+--------+-----+--------+--------

For more information on other commands, see Console Commands.

158

Load Record

Console - LOAD RECORD
Loads a record the given Record ID from the current database.
S yntax
LOAD RECORD 



#5:5

:

LOAD RECORD #5:5

-------------------------------------------------------------------------------Class: Person

id: #5:5

v.0

-------------------------------------------------------------------------------parent : Person@5:4{parent:null,children:[Person@5:5, Person@5:6],name:Barack,
surname:Obama,city:City@-6:2}
children : null
name : Malia Ann
surname : Obama
city : null
--------------------------------------------------------------------------------

For more information on other commands, see Console Commands.

159

Load Script

Console - LOAD SCRIPT (from 2.2.18)
Loads a sql script from the given path and executes it.
S yntax
LOAD SCRIPT 





 

Navigation menu