こんな人におすすめ
- railsアプリケーションをMySQLで利用している。
- 用途に応じてNoSQLやGraphDBも利用したい。
- でもMySQLをやめて完全に移行するのは都合が悪い。
なぜこんなことをしたくなったのか?
- 大量のグラフデータを扱う上でMySQL(RDB)でさばくのに無理が生じてきた
- 大規模なログ取得&分析ができる仕組みまではいらないけど、さくっとログ取得と分析がしたい
実際にやったこと
- MySQLで動いているrailsアプリケーションにNoSQLとGraphDBも使えるようにする。
※今回は、NoSQLはMongoDB、GraphDBはneo4jを利用しました。
①MongoDBをMySQLと共存して動くようにしてみる
rubyでMongoDBを利用できるmongoidというgemを入れます。
Gemfile
gem 'mongoid', '~> 5.0.0'
config/application.rb
#以下のどちらかの設定を記載
#model生成時にデフォルトでactive_record(mysql)にしたい場合
config.generators do |g|
g.orm :active_record
end
#model生成時にデフォルトでMongoDBにしたい場合
config.generators do |g|
g.orm :mongoid
end
config/mongoid.yml
development:
clients:
default:
database: "database_name"
hosts:
- "domain":"port"
# The name of the user for authentication.
user: "username"
# The password of the user for authentication.
password: "password"
console
rails g model mysql_model name:string age:integer #active_recordを使ってmodelが生成される
rails g mongoid:model mongo_model name:string age:integer #mongoidを使ってmodelが生成される
mongoidを使って生成されたmodelは以下のようになります。
mongoidを使ったmodelの場合migrationファイルは生成されずmigrationをかけずともactive_recordで生成したmodelと近い形で利用することができます。
app/models/mongo_model.rb
class MysqlModel
include Mongoid::Document
field :name, type: String
field :age, type: Integer
end
実際にconsoleを立ち上げてmodelを叩いてみると、
console
MongoModel.new
=> #<MongoModel _id: 565e81bed23812485f000001, name: nil, age: nil>
MongoModel.create(name: "Toshiyuki Oka", age: 31)
=> #<MongoModel _id: 565e81bed23812485f000002, name: "Toshiyuki Oka", age: 31>
MongoModel.first
=> #<MongoModel _id: 565e81bed23812485f000002, name: "Toshiyuki Oka", age: 31>
こいつは便利ですね。
②Neo4jをMySQLと共存して動くようにしてみる
Gemfile
gem 'neo4j', '~> 6.0.0'
config/application.rb
#mongoのときと同様に以下のどちらかの設定を記載
#model生成時にデフォルトでactive_record(mysql)にしたい場合
config.generators do |g|
g.orm :active_record
end
#model生成時にデフォルトでNeo4jにしたい場合
config.generators do |g|
g.orm :neo4j
end
config/neo4j.yml
development:
type: server_db
url: http://localhost:7474
console
rails g neo4j:model neo4j_model name:string age:integer
↑で作ったモデルは以下のようになります。
app/models/neo4j_model.rb
class Neo4jModel
include Neo4j::ActiveNode
property :name, type: String
property :age, type: Integer
index :age #indexも張れます
end
実際にconsoleを立ち上げてmodelを叩いてみると、
console
Neo4jModel.new
=> #<Neo4jModel uuid: nil, age: nil, name: nil>
Neo4jModel.create(name: "Toshiyuki Oka", age: 31)
=> CYPHER 97ms CREATE (n:`Neo4jModel` {props}) RETURN ID(n) | {:props=>{:uuid=>"5a54380d-1160-44eb-9680-7757f4bc4a74", :name=>"Toshiyuki Oka", :age=>31}}
=> #<Neo4jModel uuid: "5a54380d-1160-44eb-9680-7757f4bc4a74", age: 31, name: "Toshiyuki Oka">
Neo4jModel.first
=> CYPHER 50ms MATCH (n:`Neo4jModel`) RETURN n ORDER BY n.uuid LIMIT {limit_1} | {:limit_1=>1}
=> #<Neo4jModel uuid: "24caf736-918c-4d60-9e3e-5ec916252919", age: 31, name: "Toshiyuki Oka">
こいつも便利ですね!
最終的な利用イメージ
- 基本的なアプリケーションのデータベースはRDBで扱う。
- ログ系のデータで色々な分析や効果検証をしたいデータはMongoDBに保存して更新や分析を行う。
- 規模の大きなグラフデータは、neo4jに保存して探索や関係性、距離の問題などを扱う。