安装
Siblings 和 合并Siblings
第二索引(secondary indexes)
查找(Search)
计数器(Counters)
数据映射(MapReduce)
git submodule init
git submodule update
phpize
./configure
sudo make install
extension=riak.so
------------
; How many persistent connections pr. host:port so if you are connecting to 5 differenct servers there will be 20 persistent connections to each.
; If you do not want to reuse connections between request set this value to 0
riak.persistent.connections=20
; If a connection has not been active within this time frame, automatically reconnect before using it again
; (in seconds)
riak.persistent.timeout=1800
; Keep sockets alive (recommended)
riak.socket.keep_alive=1
; Socket receive timeout [ms]
riak.socket.recv_timeout=10000
; Socket send timeout [ms]
riak.socket.send_timeout=10000
; Number of retries if riak returns an error
riak.default.retries=1
------------
$connection = new \Riak\Connection('localhost', 8087);
---------
// Create a new bucket
$bucket = new \Riak\Bucket($connection, 'bucket_name');
// Create a new object
$obj = new \Riak\Object('object_name');
// Set the object data that will be saved to Riak
$obj->setContent("some content to save");
// Store the object in the bucket
$bucket->put($obj);
// Read back the object from Riak
$response = $bucket->get('object_name');
// Make sure we got an object back
if ($response->hasObject()) {
// Get the first returned object
$readdenObject = $response->getFirstObject();
echo "Object content: ".$readdenObject->getContent();
}
------------
use \Riak\Property\ReplicationMode as RM;
$bucket = new \Riak\Bucket($connection, 'bucket_props_ext');
// Create new bucket properties
$newProps = new \Riak\BucketPropertyList();
$newProps->setSearchEnabled(true) // Enable riak search on bucket
->setR(1) // Set R value
->setNValue(1) // Set N value
->setW(1) // Set W value
->setRW(1) // Set RW value
->setDW(1) // Set DW value
->setBigVClock(5000) // Set big vclock
->setReplicationMode(new RM\FullSyncOnly()); // Set replication mode to fullsync only
// Create some post commit hooks we can set on the bucket
$postCommitHooks = new \Riak\Property\CommitHookList();
$postCommitHooks[] = new \Riak\Property\CommitHook('module', 'function');
$postCommitHooks[] = new \Riak\Property\CommitHook('js_function_name');
$newProps->setPostCommitHookList($postCommitHooks);
// Apply the properties
$bucket->setPropertyList($newProps);
// Properties are now applied on the bucket
--------------
Siblings 和 合并Siblings
// Make sure allowMult = true on your bucket
// Create a conflict resolver
class SimpleMergeResolver implements \Riak\Output\ConflictResolver {
/**
* Resolve or merge the conflicting objects and return one that should be store back into riak.
* @param \Riak\ObjectList $objects
* @return Object|null
*/
public function resolve(\Riak\ObjectList $objects)
{
$result = null;
$mergedContent = "";
foreach ($objects as $object) {
if (!$object->isDeleted()) {
if (is_null($result)) {
// We just take the first object that is not deleted and use as base for our result
// that way we don't need to create a new object and copy the vclock, metadata and indexes etc.
$result = $object;
}
$mergedContent .= $object->getContent();
}
}
// If we actually found a result, set the content to the merged value.
if (isset($result)) {
$result->setContent($mergedContent);
}
return $result;
}
}
$bucket = new \Riak\Bucket($connection, 'siblings');
// Set our resolver on the bucket, to have it invoked automatically on conflicts
$bucket->setConflictResolver(new SimpleMergeResolver());
// Create an object with some data
$obj = new \Riak\Object('conflicting');
$obj->setContent('some data');
$bucket->put($obj);
// Now create a new object on same key, without reading the value first
$obj = new \Riak\Object('conflicting');
$obj->setContent('some other data');
$bucket->put($obj);
$getOutput = $bucket->get('conflicting');
// To make sure the resolver is called you should use the getObject on the output
$resolvedObject = $getOutput->getObject();
// Save back the object
$bucket->put($resolvedObject);
// Read back and ensure the sibling is now gone.
$getOutput = $bucket->get('conflicting');
echo var_export($getOutput->hasSiblings(), true).PHP_EOL;
echo var_export($getOutput->getObject()->getContent(), true).PHP_EOL;
---------------
第二索引(secondary indexes)
// Create 10 objects with indexes
for ($i=0; $i<10; $i++) {
$obj = new \Riak\Object("obj$i");
$obj->setContent('dummy data');
// Set a integer index num_int and a binary index text_bin
// remember secondary index should always end on _int or _bin
$obj->addIndex('num_int', $i);
$obj->addIndex('text_bin', "text$i");
// Store object
$bucket->put($obj);
}
// Query for all objects where num_int = 1
$result = $bucket->index("num_int", 1);
// Result is an array of keys, in this case obj1 should be the only entry
echo "First query returned key: ".$result[0].PHP_EOL;
// Now make a ranged query on the text_bin index
$result = $bucket->index("text_bin", "text4", "text6");
// This query will match objects which index is text4, text5 and text6
echo "Second query returned: ";
print_r($result);
--------------
查找(Search)
// Make sure search is enabled in both riak app.config and on the bucket
// Create some test data
$testDataArr[] = '{"name": "apple","price": 2.50, "tags": ["fruit"]}';
$testDataArr[] = '{"name": "potato","price": 1.50, "tags": ["veg", "something"]}';
$testDataArr[] = '{"name": "pineapple","price": 15, "tags": ["fruit"]}';
$testDataArr[] = '{"name": "cheese", "price": 45, "tags": ["cow", "dairy"]}';
$i = 0;
foreach ($testDataArr as $testData) {
$i++;
$obj = new \Riak\Object("id$i");
$obj->setContentType("application/json");
$obj->setContent($testData);
$bucket->put($obj);
}
// Perform the search
$search = new \Riak\Search\Search($connection);
$searchInput = new \Riak\Search\Input\ParameterBag();
// Search on the name field
$searchInput->setDefaultField('name');
// Now search in our search_ex_bucket after documents with the name apple
$searchResult = $search->search('search_ex_bucket', 'apple', $searchInput);
// Did we find something?
// Number of found documents:
echo 'Search found '.$searchResult->getNumFound().' with the name apple'.PHP_EOL;
$foundDocuments = $searchResult->getDocuments();
foreach ($foundDocuments as $document) {
var_dump($document);
}
-------------
计数器(Counters)
// Make sure allowMult is set to true on the bucket, as this is required for CRDT's to work.
// Counter can be constructed in two ways
// With new:
$counter1 = new \Riak\CRDT\Counter($bucket, "counter1");
// Or with Riak\Bucket's counter function
$counter2 = $bucket->counter("counter2");
// All counters start at 0
// All changes to the counter value is done using increment like this
$counter1->increment(10);
// Use negative values to decrement
$counter2->increment(-10);
// Increment can also return the updated value
echo "Counter1 value: ".$counter1->incrementAndGet(10).PHP_EOL;
// The Riak\Bucket->counter function can save some typing
// the counter function will always return a counter object or throw exception
$c2val = $bucket->counter("counter2")->get();
echo "Counter2 value: ".$c2val.PHP_EOL;
-----------
数据映射(MapReduce)
use \Riak\MapReduce\MapReduce;
use \Riak\MapReduce\Input\KeyListInput;
use \Riak\MapReduce\Phase\MapPhase;
use \Riak\MapReduce\Phase\ReducePhase;
use \Riak\MapReduce\Functions\JavascriptFunction;
use \Riak\Object;
include_once "connect.inc";
$alice1 = "Alice was beginning to get very tired of sitting by her sister on the ".
"bank, and of having nothing to do: once or twice she had peeped into the ".
"book her sister was reading, but it had no pictures or conversations in ".
"it, 'and what is the use of a book,' thought Alice 'without pictures or ".
"conversation?'";
$alice2 = "So she was considering in her own mind (as well as she could, for the ".
"hot day made her feel very sleepy and stupid), whether the pleasure ".
"of making a daisy-chain would be worth the trouble of getting up and ".
"picking the daisies, when suddenly a White Rabbit with pink eyes ran ".
"close by her.";
$alice3 = "The rabbit-hole went straight on like a tunnel for some way, and then ".
"dipped suddenly down, so suddenly that Alice had not a moment to think ".
"about stopping herself before she found herself falling down a very deep ".
"well.";
try {
$client = new \Riak\Connection($host, $port);
$alicebucket = new \Riak\Bucket($client, "test_alice");
$obj1 = new Object("alice1");
$obj1->setContent($alice1);
$alicebucket->put($obj1);
$obj2 = new Object("alice2");
$obj2->setContent($alice2);
$alicebucket->put($obj2);
$obj3 = new Object("alice3");
$obj3->setContent($alice3);
$alicebucket->put($obj3);
$mrinput = new KeyListInput(array("test_alice" => array("alice1", $obj2, $obj3)));
$jsmapfunc = JavascriptFunction::anon("function(v) {".
"var m = v.values[0].data.toLowerCase().match(/\w*/g);".
"var r = [];".
"for(var i in m) {".
" if(m[i] != '') {".
" var o = {};".
" o[m[i]] = 1;".
" r.push(o);".
" }".
"}".
"return r;".
"}");
$jsredfunc = JavascriptFunction::anon("function(v) {".
"var r = {};".
"for(var i in v) {".
" for(var w in v[i]) {".
" if(w in r) r[w] += v[i][w];".
" else r[w] = v[i][w];".
" }".
"}".
"return [r];".
"}");
$mr = new MapReduce($client);
$mr ->addPhase(new MapPhase($jsmapfunc))
->addPhase(new ReducePhase($jsredfunc))
->setInput($mrinput);
$json = $mr->toJson();
$result = $mr->run();
$res0val = $result[0]->getValue();
if ($res0val[0]["the"] !== 8) {
var_dump($result);
}
global $streamedsomething;
$streamedsomething = false;
// Now do the same but stream it
class MrStream implements \Riak\MapReduce\Output\StreamOutput {
public function receive($response) {
global $streamedsomething;
$streamedsomething = true;
}
};
$mr->run(new MrStream());
if ($streamedsomething) {
echo "success!".PHP_EOL;
}
} catch (Exception $e) {
echo $e->getMessage();
}
---------------