OrientJSとOrientDBの併用方法

このチュートリアルでは、**Alibaba Cloud**上で**OrientDB**を設定し、**OrientDB**と一緒にOrientJSの使い方を探っていきます。

*本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/learning-how-to-use-orientdbs-intuitive-module-orientjs_595408)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。*

#前提条件
このチュートリアルは中程度の難易度と言えます。そのため、このチュートリアルでは、いくつかの関連する背景知識が必要となります。また、このチュートリアルを進める前に、いくつかの設定をしておくことも大前提となります。具体的には、以下のものが必要です。

1、[Linuxのコマンドラインインターフェース](https://www.linux.com/training-tutorials/how-use-linux-command-line-basics-cli/?spm=a2c65.11461447.0.0.4e462b3eZyH0hD)の機能についての一般的な理解。
2、Alibaba Cloud の [ECS セキュリティグループ](https://www.alibabacloud.com/help/doc-detail/25387.htm?spm=a2c65.11461447.0.0.4e462b3eZyH0hD)の一般的な理解。
3、[Java](https://www.java.com/en/?spm=a2c65.11461447.0.0.4e462b3eZyH0hD)（具体的には1.7以降）がインストールされており、関連する環境変数も設定されていること。
4、[JavaScript](https://www.javascript.com/?spm=a2c65.11461447.0.0.4e462b3eZyH0hD)の一般的な理解。

#Alibaba Cloud ECSへのOrientDBのインストール
このチュートリアルの最初のステップとして、Alibaba Cloud [Elastic Compute Service](https://www.alibabacloud.com/ja/product/ecs) (ECS) インスタンスを[作成する](https://www.alibabacloud.com/help/ja/doc-detail/25424.htm#task_zjx_p1f_5db)必要があります。このチュートリアルでは、Ubuntuがインストールされ、ワンコアプロセッサと512MBのメモリを持つECSインスタンスを作成します。次に、SSHを使用するか、Alibaba Cloudコンソールを介してインスタンスにログオンします。その方法については、まだ知らない場合は、この[ガイド](https://www.alibabacloud.com/help/ja/doc-detail/25425.htm)をチェックしてください。

次に、適切なバイナリパッケージをインストールする必要があります。まず、[OrientDB](https://orientdb.com/orientdb-enterprise/?spm=a2c65.11461447.0.0.4e462b3eZyH0hD)の最新の安定版リリースをダウンロードします。あるいは、ウェブサイトから手動でダウンロードするのではなく、以下のコマンドを使って OrientDB [3.0.21](https://orientdb.com/download-previous/?spm=a2c65.11461447.0.0.4e462b3eZyH0hD) をダウンロードしてみることもできます。

```
curl  https://s3.us-east-2.amazonaws.com/orientdb3/releases/3.0.21/orientdb-3.0.21.tar.gz
```

ダウンロードが完了すると、最初に curl コマンドを入力したディレクトリに `orientdb-3.0.21.tar.gz` という名前の zip ファイルが存在します。その後、zip ファイルの内容を展開し、環境変数 `ORIENTDB_HOME` の下の適切なディレクトリに移動します。現在のバージョンに応じた対応するコマンドは以下の通りです。

- `tar -xvzf orientdb-3.0.21.tar.gz`: フォルダを解凍します。
- `cp -r orientdb-3.0.21 /opt`: フォルダ全体を/optディレクトリにコピーするために使用します。
`/etc/environment`の内容は以下のようにします。

```
JAVA_HOME=/usr/lib/jvm/java-8-oracle
ORIENTDB_HOME=/opt/orientdb-3.0.21
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games :$ORIENTDB_HOME/bin" 
```

このチュートリアルの前提条件であるJava 1.7以降がインストールされていること、およびUbuntuでインストールされたインスタンスにスワップ領域が追加されていること、つまり、新しいインスタンスサーバーであり、まだインストールされていない場合です。

注: OrientDB を更新した後、必要であれば、このファイルをソースにして、新しい OrientDB の実行ファイルがターミナルで利用できるようにする必要があります。これに使用するコマンドは次のとおりです: source /etc/environment.

ここで、`ORIENTDB_DIR` の代わりに `ORIENTDB_HOME` の OrientDB ディレクトリの場所（もちろん `ORIENTDB_HOME`）と、`USER_YOU_WANT_ORIENTDB_RUN_WITH` の代わりに使用したいシステムユーザを入力して、`ORIENTDB_HOME/bin` にある `orientdb.sh` ファイルを編集する必要があります。

OrientDBのインストールが完全に機能している状態で、以下のコマンドでOirentDBサーバを制御することができます。

- `orientdb.sh status`: サーバが稼働しているかどうかをチェックするために使用します。
- `orientdb.sh start`: OrientDB サーバを起動するために使用します。
- `orientdb.sh stop`: OrientDB をシャットダウンするために使用します。

ほとんどの場合、本番環境では非常に安全なインストールが必要です。つまり、どのユーザーも自分の意思でデータベースを起動したり停止したりする権限を持たないような、安全なOrientDBのインストールが必要になります。そのため、`OrientDB bin/orientdb.sh`ファイルでは、`USER_YOU_WANT_ORIENTDB_RUN_WITH`の代わりに管理ユーザーを入力することができます。そうすることで、管理者としてOriendDBの最も賢明なコマンドの完全な権利を持つ唯一のユーザーになることを意味します。

この種のことをもっと知りたい方は、[OrientDBのドキュメント](http://orientdb.com/docs/3.0.x/?spm=a2c65.11461447.0.0.4e462b3eZyH0hD)を見てください。

さて、これでこれらのことはすべて完了しましたので、次に進みましょう。`orientdb.sh start`コマンドを実行してインストールをテストすることができます。次のスクリーンショットに示すように、ポータル、特にOrientDB Studioには、`http://our_ecs_ip:2480` または `http://localhost:2480` のいずれかのアドレスからアクセスすることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/27e8230d-eedc-7378-2ad9-8881ed11a3a0.png)


OrientDB に接続してダッシュボードにアクセスするためには、[ここ](https://orientdb.com/docs/2.0/orientdb.wiki/Security.html?spm=a2c65.11461447.0.0.4e462b3eZyH0hD#orientdb-server-security)で説明したように `$ORIENTDB_HOME/config/oritdenb-server-config.xml` ファイルの最後にユーザーを定義する必要があります。

次に、2480番ポート（OrientDB Studioのポート）にインスタンスセキュリティグループを設定することを忘れないでください。

注: 外部からアクセスできるように設定する必要があります。

以下は、テスト用インスタンスの設定の出力です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/1b0b94d5-6444-9255-06ef-aa373d5d6554.png)

#OrientJsの設定
OrientDBのOrientJSモジュールは、JavaScriptプロジェクトのための公式のOrientDBドライバとして記述することができます。これは、NodeJSの開発者の間で広く使われています。もちろん、他のパッケージと同様に、[node package manager](https://www.npmjs.com/?spm=a2c65.11461447.0.0.4e462b3eZyH0hD)を使ってインストールするには、たった一つのコマンドが必要です。具体的には、ローカルにインストールするには、`npm install orientjs`コマンドを実行します。

そして、OrientJSがインストールされて初期化されると、以下のようなことができるようになります。

- [Server API](http://orientdb.com/docs/last/OrientJS-Server.html?spm=a2c65.11461447.0.0.4e462b3eZyH0hD)
- [Database API](http://orientdb.com/docs/last/OrientJS-Database.html?spm=a2c65.11461447.0.0.4e462b3eZyH0hD)
- [Class API](http://orientdb.com/docs/last/OrientJS-Class.html?spm=a2c65.11461447.0.0.4e462b3eZyH0hD)
- [Index API](http://orientdb.com/docs/last/OrientJS-Index.html?spm=a2c65.11461447.0.0.4e462b3eZyH0hD)
- [Function API](http://orientdb.com/docs/last/OrientJS-Functions.html?spm=a2c65.11461447.0.0.4e462b3eZyH0hD)
- [Queries](http://orientdb.com/docs/last/OrientJS-Query.html?spm=a2c65.11461447.0.0.4e462b3eZyH0hD)
- [Transactions](http://orientdb.com/docs/last/OrientJS-Transactions.html?spm=a2c65.11461447.0.0.4e462b3eZyH0hD)
- [Events](http://orientdb.com/docs/last/OrientJS-Events.html?spm=a2c65.11461447.0.0.4e462b3eZyH0hD)

#OrientJSの初期化
OrientJSとOrientDBを相互に連携させるための最初のステップは、サーバーAPIを初期化することです。これを行うことは、OreintJSがOrientDBのサーバーAPIと対話できるようにするために重要です。なぜなら、OrientDBサーバーのホストとそのポートにデータベースユーザーが接続されている必要があるからです。

```
// Initializing the Server API
var server = OrientDB({
  host:       'localhost',
  port:       2424,
  username:   'admin',
  password:   'admin'
});
```

注: この場合、ユーザー資格情報には `admin:admin` を使用しています。しかし、これはOrientDB設定ファイルに設定した対応する資格情報に変更する必要があります。

#データベースのリスト
このチュートリアルの次のステップは、OrientJSを使って単一のクエリを実行して、ここまでに作成したすべてのデータベースを一覧表示することです。これに続いて、通常はDBオブジェクトを返すように、各データベースの名前とタイプを表示しています。

```
// Databases listing
server.list()
  .then(list => {
    console.log(list.length + ' databases created so far');

    list.forEach(db => {
      console.log(db.name + ' - ' + db.type);
    });
  });
```

#データベースの作成
それでは、サーバーAPIからデータベースを作成する作業に移りましょう。これは比較的簡単です。この操作は、先ほど作成したデータベースオブジェクトとの約束を返す単一のコマンドでも行うことができます。

以下は、Create関数に関連するOrientJsの型の内容です。

```
/**
 * Create a database with the given name / config.
 *
 * @param  config The database name or configuration object.
 * @promise {Db}                  The database instance
 */
create(name: string | DbConfig): Promise<Db>;
```

この関数にコンフィギュレーション・オブジェクトまたは単にデータベース名を提供することで作成操作が完了することが明記されています。しかし、以下に示す2つ目のケースでは、デフォルト値は欠落しているフィールドのために選択されることになります。ここでは、設定オブジェクトを使ってデータベースを作成する方法を説明します。

```
// Creating a database
server.create({
    name:     'NewDatabase',
    type:     'graph',
    storage:  'plocal',
  }).then(dbCreated => {
    console.log('Database ' + dbCreated.name + ' created successfully');
  });
```

#既存のデータベースを使用
データベースが作成された後は、後からインスタンスを取得して、より多くの操作を行うことができます。データベースのインスタンスを初期化するには、以下のメソッドを使用します。

```
var db = server.use('NewDatabase');
```

バージョン2.1.11からは、ODatabaseクラスを使ってServer APIを初期化し、すぐにデータベースに接続することも可能になりました。そのための構文は以下の通りです。

```
var ODatabase = require('orientjs').ODatabase;
var db = new ODatabase({
  host:     'localhost',
  port:     2424,
  username: 'admin',
  password: 'admin',
  name:     'NewDatabase'
});

console.log('Connected to: ' + db.name);
```

#レコードAPI
データベースインスタンスが初期化されると、保存されたレコード、つまりデータベースに保存された情報を、データベースの[レコードID（RID）]()を使用して取得したり操作したりすることができます。

注意: レコード ID は一意の値なので、一般的な SQL ベースのリレーショナル・データベースのように、主キーを参照するフィールドをもう 1 つ作成する必要はありません。

レコードIDの構文は以下の通りです。`#<cluster>:<position>`となります。このコードの場合

- `cluster`：クラスタ識別子として機能します。これはクラスタが属するクラスタレコードを直接参照します。このパラメータの値は、正の値は永続的なレコードを示し、負の値は一時的なレコードを示します。
- `position`：クラスタへのレコードの絶対位置を指定します。
ここでは、レコードの `RID` を指定して 1 つのレコードを取得してみましょう。

```
db.record.get('#1:1')
  .then(
    function(article) {
        console.log('Loaded article:', article);
      }
  );
```

レコードを取得したので、いくつかの操作について説明します。まず、削除操作です。一般的には、レコードの削除は比較的簡単で、以下のコードで行うことができます。

```
db.record.delete('#1:1');
```

次に、更新操作です。レコードの更新は少し複雑ですが、それでも私の中では問題ありません。更新したい対応するデータが読み込まれた後に行うことができます。以下に、更新関数の実装方法を示します。

```
db.record.get('#1:1')
  .then(function(article) {
    article.title = 'New Title';
    db.record.update(article)
      .then(function() {
        console.log("Article updated successfully");
      });
  });
```

注意：このコードを使用する際には、以下のことを考慮してください。

```
- The an asterisk (#) prefix is required to recognize a Record ID.
- When creating a new record, OrientDB selects the cluster to store it using a configurable strategy, which can be the default strategy, the round-robin one, or a balanced or local strategy.
- Also, note that, in our example, #1:1 represents the RID. 
```

#クラスAPI
データベースの派生オブジェクトは、クラスにアクセスしたり、作成したり、操作したりするために特別に使用されます。具体的には、"クラス "と言うと`db.class`のことを指します。例えば、ここにクラスを作成するためのメソッドがあります。


```
// Creating a new class(Article) using the Class API
var Article = db.class.create('Article');
```

既存のクラスを取得するには、以下のようにします。

```
var Article = db.class.get('Article');
```

これらはすべてプロミスを返していることに注意しましょう。プロミスが解決したら、さらにアクションを実行することを意識したスタイルになります。現在接続しているデータベースに保存されているすべてのクラスのリストを返すには、次のコードを適用します。

```
// List all the database classes
db.class.list()
  .then(
    function(classes){
      console.log(classes.length + ' existing classes into ' + db.name);

      classes.forEach(cl => {
        console.log(cl.name);
      });
    }
  );
```

次に、作成操作があります。クラスを作成することは、データベース構造を完全に設計する前に知っておいた方が良いことです。私たちは、プロパティを操作する前に作業するクラスを正しくロードしなければなりません。

Articleのクラスのプロパティのリストは次のようになります。

```
db.class.get('Article').then(function(Article) {
  Article.property.list()
  .then(
    function(properties) {
       console.log(Article.name + ' has the properties: ', properties);
    }
 );
});
```

プロパティの作成は、ほぼ同じ構文で行われます。

```
db.class.get('Article').then(function(Article) {
  Article.property.create([{
    name: 'title',
    type: 'String'
  },{
    name: 'content',
    type: 'String'
  }]).then(
    function(properties) {
      console.log("Successfully created properties");
    }
  );
});

```

クラスには1つのプロパティを設定するだけです。多くのプロパティを設定する必要はありません。では、いくつかのアクションを実行してみましょう。

まず、プロパティを名前で削除してみましょう。

```
db.class.get('Article').then(function(Article) {
  Article.property.drop('peroperty_to_drop').then(function(){
    console.log('Property deleted successfully.');
 });
});

```

続いて、プロパティ名を変更してみましょう。

```
db.class.get('Article').then(function(Article) {
  Article.property.rename('old_name', 'new_name').then(function(p) {
    console.log('Property renamed successfully');
 });
});
```

Class API の詳細については、[こちらのドキュメント](https://orientdb.com/docs/last/OrientJS-Class-Classes.html?spm=a2c65.11461447.0.0.4e462b3eZyH0hD)を参照してください。

#OrientDB でのクエリ
クエリは、データをより良く管理するために、データベースエンジンが提供する最も重要な操作の一つであり、OrientDBでは2つの方法のいずれかでクエリを実行することができます。直接SQLリクエストを発行するか、[Query Builder](https://querybuilder.js.org/?spm=a2c65.11461447.0.0.4e462b3eZyH0hD)を使用してNodeJsで暗黙的にクエリを構築するかのどちらかです。

```
// Find articles viewed 200 times
var numberViews = 200;
db.query(
   'SELECT title, content FROM Article '
   + 'WHERE number_views = :numberViews,
   { params: { numberViews: numberViews, } }
).then(function(articles) {
   console.log(articles);
});
```

上のクエリでは、200回閲覧された記事を探しています。このクエリは比較的簡単に実行できます。この可能性を利用してエンジンに命令を出す方法は、AND, OR, LIKEなどの演算子を使って、より面白いSQL構文を使うことができます。リクエストのサブストリングとパラメータを連結してSQL文字列を完全に構築するのではなく、パラメトリック化されたリクエストを使用するこの可能性（より簡単）。OrientDBのSQL構文についての詳細はこちらを参照してください。

SQL クエリを完全に記述する代わりに、代わりに Query Builder を使用することができます。[クエリビルダ](https://querybuilder.js.org/?spm=a2c65.11461447.0.0.4e462b3eZyH0hD)は、データベースAPIアクションを通じて内部的にクエリを実行している特定のメソッドを呼び出すことができるように機能します。ここでは、SQL で行ったのと同じクエリを Query Builder で実行しています。

```
var numberViews = 200;
var query = db.select('title, content').from('Article')
  .where({ "number_views": numberViews })
  .all();
```

#イベント情報
OrientDBでは、イベントはコールバックメソッドとして機能し、クエリの終了時や開始時に実行することができます。イベントは、クエリのデバッグや、ログの記録、プロファイリング、データを調整するための特別なタスクの実行に便利です。イベントはデータベースに依存します。つまり、各イベントは単一のデータベースにアタッチされ、その作成には Database API を使用する必要があります。このAPIを使用する場合は、`db.on()`関数を使用します。以下の例では、`BeginQuery`イベントを使用して、OrientDBサーバに送信された全てのクエリをログに記録しています。(クエリの終了には `endQuery` を使用することもできます)。

```
db.on("beginQuery", function(queryObj) {
  console.log('DEBUG: ', queryObj);
});
```

#結論
このチュートリアルでは、Alibaba Cloud ECSインスタンス上でOrientDBを設定する方法を見てきましたが、OrientDBと一緒にOrientJSを使用する方法も探ってきました。


*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)*