2013年10月20日 星期日

Riak實戰(4) - Secondary Indexes

NOSQL 不像 SQL,比較沒有 join 或針對某個 entry 的其中一個 attribute 做搜尋 (where) 的動作。通常都是以 key-value 的方式直接拿取資料,若遇到需要 join 的情況也往往是做多次的 query 拿到相關連的資料。反正概念上就是直接用 key 去對應 entry 或叫 document。
但是在使用 key 的過程中難免覺得彈性及可自定部分太少,使用起來不是這麼順手,於是 Riak 便有了 Second Indexes (2i) 的設計。

你可以將 2i 想成是 tag,讓你對特定的資料下標記,之後能更方便的 query 資料。例如我們可以從「engineers」這個 bucket 取出「language」設為「javascript」的資料。我們等等可以看看範例。


基本操作


新增並下 2i:

curl -X POST \
-H 'x-riak-index-twitter_bin: jsmith123' \
-H 'x-riak-index-email_bin: jsmith@basho.com' \
-d '...user data...' \
http://localhost:8098/buckets/users/keys/john_smith

然後這筆資料就有一個叫「twitter_bin」且值為「jsmith123」的secondary index;
以及一個叫「email_bin」且值為「jsmith@basho.com」的secondary index。


取資料 (Query):

取得特定 2i 的資料
curl http://localhost:8098/buckets/users/index/twitter_bin/jsmith123


進階操作


用範圍取資料 (Range) :

curl http://localhost:8098/buckets/users/index/field1_bin/val2/val4

範圍選取並回傳 2i (Range with terms):

curl 'http://localhost:10018/buckets/tweets/index/hashtags_bin/rock/rocl?return_terms=true'
當 return_terms=true 時,能夠連同被query到的 secondary index 一起返回


分頁 (Pagination):

相當好用,可以回傳一個token讓你再次取得下一頁的資料。
當 max_results 為 true 時,回傳結果會附上一個 continuation token,下一次的 query 只要附上這個 token,Riak 就知道要從什麼地方繼續提供資料給你。

curl 'http://localhost:10018/buckets/tweets/index/hashtags_bin/ri/ru?max_results=5&return_terms=true' | python -mjson.tool
{
    "continuation": "g2gCbQAAAAdyaXBqYWtlbQAAABIzNDkyMjA2ODcwNTcxMjk0NzM=",
    "results": [
        {
            "rice": "349222574510710785"
        },
        {
            "rickross": "349222868095217664"
        },
        {
            "ridelife": "349221819552763905"
        },
        {
            "ripjake": "349220649341952001"
        },
        {
            "ripjake": "349220687057129473"
        }
    ]
}

# Take the continuation value from the previous result set and feed it back into the query
curl 'http://localhost:10018/buckets/tweets/index/hashtags_bin/ri/ru?continuation=g2gCbQAAAAdyaXBqYWtlbQAAABIzNDkyMjA2ODcwNTcxMjk0NzM=&max_results=5&return_terms=true' | python -mjson.tool
{
    "continuation": "g2gCbQAAAAlyb2Jhc2VyaWFtAAAAEjM0OTIyMzcwMjc2NTkxMjA2NQ==",
    "results": [
        {
            "ripjake": "349221198774808579"
        },
        {
            "ripped": "349224017347100672"
        },
        {
            "roadtrip": "349221207155032066"
        },
        {
            "roastietime": "349221370724491265"
        },
        {
            "robaseria": "349223702765912065"
        }
    ]
}


效能問題

官網上有提到,當你的cluster超過512 partitions時,會有比較明顯的效能問題,這點必須注意一下。