Taste of Riak

Working with Records in Riak

With our data created, let's start doing some Riak. First, we'll need to connect to the database -- remember to use the IP address and port that yours is running on!

> (set `#(ok ,client-pid) (lric:start-link "172.16.4.164" 8087))
#(ok <0.32.0>)

Now let's prep some variables for use with Riak objects and buckets:

> (set customer-bucket (binary "customrs"))
#B(99 117 115 116 111 109 114 115)
> (set order-bucket (binary "orders"))
#B(111 114 100 101 114 115)
> (set order-summaries-bucket (binary "order summaries"))
#B(111 114 100 101 114 32 115 117 109 109 97 114 105 101 115)

Let's create a customer object:

> (set cust-obj
    (lrico:new
      customer-bucket
      (list_to_binary (integer_to_list (customer-id customer-1)))
      customer-1))
#(riakc_obj
  #B(99 117 115 116 111 109 114 115)
  #B(49)
  undefined () undefined
  #(customer 1
    "Alice Roberts"
    "123 Main Street"
    "Columbus"
    "Ohio"
    "43210"
    "+1 614 555 1212"
    #(#(2010 10 1) #(10 10 1))))

And store it:

> (lric:put client-pid cust-obj)
ok

Now we're going to iterate over each order, and perform a set of operations on them, so let's create a function for this:

(defun store-order (order)
  (let* ((order-id (list_to_binary (integer_to_list (order-id order))))
         (order-obj (lrico:new order-bucket order-id order)))
    (lric:put client-pid order-obj)))

The LFE REPL lets you define functions (unlike the Erlang shell), so you can go ahead and paste the above definition. Then let's use it:

> (lists:map #'store-order/1 orders)
(ok ok ok)

Now let's take care of the order summary:

> (set order-sum-obj
    (lrico:new
      order-summaries-bucket
      (list_to_binary
          (integer_to_list
            (order-summary-customer-id ord-sum)))
      ord-sum))
#(riakc_obj
  #B(111 114 100 101 114 32 115 117 109 109 97 114 105 101 115)
  #B(49)
  undefined () undefined
  #(order-summary 1
    (#(order-summary-entry 1 415.98 #(#(2015 1 14) #(14 42 24)))
     #(order-summary-entry 2 359.99 #(#(2015 1 24) #(12 42 24)))
     #(order-summary-entry 3 74.98 #(#(2015 2 1) #(22 24 42))))))
> (lric:put client-pid order-sum-obj)
ok

While individual Customer and Order objects don't change much (or shouldn't change), the OrderSummaries object will likely change often. It will do double duty by acting as an index for all a customer's orders, and also holding some relevant data such as the order total, etc. If we showed this information in our application often, it's only one extra request to get all the info.

> (set `#(ok ,fetched-customer)
       (lric:get client-pid customer-bucket (binary "1")))
#(ok
  #(riakc_obj
    #B(99 117 115 116 111 109 114 115)
    #B(49)
    #B(107 206 97 96 96 96 204 96 202 5 82 28 202 ...)
    (#(#(dict 3 16 16 8 80 48
         #(() () () () () () () () () () () () () () () ...)
         #(#(() () () () () () () () () () ((#B(99 ...) ...) (...)) () () ...)))
       #B(131 104 9 100 0 8 99 117 115 116 111 109 ...)))
    undefined undefined))
> (set `#(ok ,fetched-summary)
       (lric:get client-pid order-summaries-bucket (binary "1")))
#(ok
  #(riakc_obj
    #B(111 114 100 101 114 32 115 117 109 109 97 114 105 101 115)
    #B(49)
    #B(107 206 97 96 96 96 204 96 202 5 82 28 202 ...)
    (#(#(dict 3 16 16 8 80 48
         #(() () () () () () () () () () () () () () () ...)
         #(#(() () () () () () () () () () ((#B(99 ...) ...) (...)) () () ...)))
       #B(131 104 3 100 0 13 111 114 100 101 114 45 ...)))
    undefined undefined))

And we can batch these up with this:

> `#(,(binary_to_term (lrico:get-value fetched-customer))
     ,(binary_to_term (lrico:get-value fetched-summary)))
#(#(customer 1
    "Alice Roberts"
    "123 Main Street"
    "Columbus"
    "Ohio"
    "43210"
    "+1 614 555 1212"
    #(#(2010 10 1) #(10 10 1)))
  #(order-summary 1
    (#(order-summary-entry 1 415.98 #(#(2015 1 14) #(14 42 24)))
     #(order-summary-entry 2 359.99 #(#(2015 1 24) #(12 42 24)))
     #(order-summary-entry 3 74.98 #(#(2015 2 1) #(22 24 42))))))

While this pattern is very easy and extremely fast with respect to queries and complexity, it's up to the application to know about these intrinsic relationships.