SlideNow 建立記錄 - (3) Riak-js 測試

Riak 預設存取方式是用REST API
因為SlideNow會以Node.js為主,所以我使用Riak-js這個package來存取Riak
首先可以使用下面指令開始設定你的連線資訊

var db = require('riak-js').getClient({host: "106.186.118.168", port: "49162"});

上面是npm install下來的操作方法,但是我從github上clone下來的未包裝成package的版本使用法方不一樣(2014.06.04)

var db = require('riak-js')({host: "106.186.118.168", port: "49162"});

然後用下面方式即可以取得id的資料

db.get('[bucket-name]',[id],function(err,data,meta){
    if(err)
        console.error(err.statusCode)
    else
        console.dir(data)
})

這邊我做了Riak-js的方法與REST API的對應

HTTP List Buckets

GET /riak?buckets=true       # Old format
GET /buckets?buckets=true    # New format
db.buckets(function(err,data,meta){
    console.dir(data)
})

HTTP List Keys

GET /riak/[bucket-name]?keys=true            # List all keys, old format
GET /buckets/[bucket-name]/keys?keys=true    # List all keys, new format
GET /riak/[bucket-name]?keys=stream          # Stream keys to the client, old format
GET /buckets/[bucket-name]/keys?keys=stream  # Stream keys to the client, new format

這邊要說明一下,因為Key可能很長,所以riak-js只有stream的取法,db.keys([bucket-name])會回傳EventEmiter,你可以用on('keys')取得stream的key的資料,用on('end')知道結束了

db.keys('[bucket-name]')
.on('keys',function(d){
    console.log(d)
})
.on('end',function(){
    console.log('end');
})
.start()

HTTP Get Bucket Properties

GET /riak/[bucket-name]                # Old format
GET /buckets/[bucket-name]/props       # New format
db.getBucket('[bucket-name]', function(err, properties) {
  console.log(properties.pw)
})

HTTP Set Bucket Properties

PUT /riak/[bucket-name]                # Old format
PUT /buckets/[bucket-name]/props       # New format
db.saveBucket('[bucket-name]', {[attribute]: [value]})

HTTP Reset Bucket Properties

DELETE /buckets/bucket/props

這個我沒有找到對應方法

HTTP Fetch Object

GET /riak/[bucket-name]/[id]            # Old format
GET /buckets/[bucket-name]/keys/[id]    # New format
db.get('[bucket-name]',[id],function(err,data,meta){
    if(err)
        console.error(err.statusCode)
    else
        console.dir(data)
})

HTTP Store Object

POST /riak/[bucket-name]               # Riak-defined key, old format
POST /buckets/[bucket-name]/keys       # Riak-defined key, new format
PUT /riak/[bucket-name]/[id]           # User-defined key, old format
PUT /buckets/[bucket-name]/keys/[id]   # User-defined key, new format
db.save('[bucket-name]', '[id]', data , function(err,data,meta){
    if(err)
        console.error(err.statusCode)
    else
        console.dir(data)
})

HTTP Delete Object

DELETE /riak/[bucket-name]/[id]           # Old format
DELETE /buckets/[bucket-name]/keys/[id]   # New format
db.remove('[bucket-name]', '[id]')

HTTP Link Walking(類似GraphDB操作)


Riak的一個我蠻喜歡的特性,如果你使用Relation Database,在設計DB Schema時,常常會做正規化,如果要做我的朋友,一般會做兩個table,一個存user資料,一個存朋友的對應,所以如果要取得我的朋友,必須要做Join,要找我的朋友的朋友,就要Join兩次,但Join的效能並不好,如果你想找到多層的話,會很麻煩,所以會有GraphDB(Neo4j、Titan、Infinite)的出現。
Riak的link walk就是要實現這樣的功能
比如你想要找到朋友的朋友,就可以如下這樣使用

GET localhost:8091/buckets/people/casear/_,friends,_/_,friends,1/
  • 從casear的link中找出friend tag的並不回傳
  • 再從friend tag的找出所有的friend 並回傳
  • 第一個參數是指定link到的bucket,第二個參數是指定tag,第三個參數是指定是否回傳
GET /riak/[bucket-name]/[id]/[bucket],[tag],[keep]            # Old format
GET /buckets/[bucket-name]/keys/[id]/[bucket],[tag],[keep]    # New format
  • [bucket] : link 限制的 bucket,使用'_'為全部
  • [tag] : link 限制的 tag,使用'_'為全部
  • [keep] : 是否要回傳值,使用'_'為0
db.walk('[bucket-name]', '[id]', [{bucket: '[bucket]', tag: '[tag]', keep:'[keep]'}])

HTTP MapReduce

POST /mapred

POST的資料格式

{"inputs":[...inputs...],"query":[...query...],"timeout": 90000} 
  • inputs : 要查詢的bucket,或bucket跟Key,例:['bucket-name'] or [["bucket1","key1"],["bucket2","key2"],["bucket3","key3"] ]
  • query : 要使用的map或reduce的資訊,例如:{ "map":{"language":"javascript","source":"function(v) { return [v]; }","keep":true} }
db.mapreduce.add('[bucket-name]').map(function (value, keyData, arg) { /* do something with arg == { cancelled: true } */ }, { cancelled: true })

HTTP Secondary Indexes

Exact Match

GET /buckets/[bucket_name]/index/[property]/value
db.query('[bucket_name]', {[property]: value});

Range Query

GET /buckets/[bucket_name]/index/[property]/start/end
db.query('[bucket_name]', {[property]: [start, end]});

另外Secondary Indexes可以在Save的時候一起加進去
範例如下

db.save('airlines', 'KLM', {country: 'NL', established: 1919}, {index: {country: 'NL', established: 1919}});

Pagination跟Stream我也沒有找到對應

HTTP Ping

GET /ping
db.ping()

HTTP Status

GET /stats
db.stats()

HTTP List Resources

GET /

沒有找到對應

對照大概如下,有問題再問我吧...

comments powered by Disqus