basho/riak-php-client — pull request #17 by MightyE (2011-11-23 14:44:17+00:00)
Title: Support for secondary indexes & Meta Data

This patch includes support for the following:

* Secondary Index Querying
* Adding Secondary Indexes
* "Auto Indexes" (more on that below)
* User meta data
* Two bug fixes:
* Using mt_rand() instead of rand(). Under load, rand() is not particularly random; mt_rand() is both faster and "more random" (if such a thing can be said of a deterministic algorithm)
* Links are not properly URL decoded when read, causing corruption when an object is ->get()->store()d if keys or buckets contain special characters.

## Auto Indexes ##
The notion of 'auto indexes' in this patch may be controversial. We have many hands in various pots here, and several different applications and application layers touching the same objects. A concern for us is that two applications which work against the same data store might not adequately keep each other's indexes up to date. The majority of the time our indexes are a convenient way to search out a piece of data found inside the object, and the two ought to be bound together.

That's not to say that loosely coupled indexes are without value - they certainly are. So this patch includes support for traditional indexes, plus an alternate API for auto indexes.

As an example, imagine we have a CRM system, an eCommerce system, and a customer-accessible API. All three read and modify customer records. The customer may change their shipping address from the website, or an employee might do so through CRM, or the customer's own management system might do so through the API. Let's say CRM decides they want a secondary index on ZIP code, so they add this. With a traditional index, the website and API now also need to be updated to keep this index fresh, while with an auto index, the website will notice this is an auto index and keep it fresh without a code change.

# Documentation #

## Meta Data ##
You can provide meta data on objects using RiakObject::getMeta() and RiakObject::setMeta()

# Set some new meta data
$object->setMeta("some-meta", "some-value");

# Get some meta data (returns null if not found)
$object->getMeta("some-meta");

# Get all meta data (an array keyed by meta name)
$object->getAllMeta()

Remove existing metadata

# Remove a single value
$object->removeMeta("some-meta");

# Remove all meta data
$object->removeAllMeta();

## Adding Secondary Indexes ##
Secondary indexes can be added using the RiakObject::addIndex() and RiakObject::addAutoIndex() methods.

Auto indexes are kept fresh with the associated field automatically, so if you read an object, modify its data, and write it back, the auto index will reflect the new value from the object. Traditional indexes are fixed and must be manually managed. *NOTE* that auto indexes are a function of the Riak PHP client, and are not part of native Riak functionality. Other clients writing the same object must manage the index manually.

# Create some test data
$bucket = $client->bucket("indextest");
$bucket
->newObject("one", array("some_field"=>1, "bar"=>"red"))
->addIndex("index_name", "int", 1)
->addIndex("index_name", "int", 2)
->addIndex("text_index", "bin", "apple")
->addAutoIndex("some_field", "int")
->addAutoIndex("bar", "bin")
->store();

You can remove a specific value from an index, all values from an index, or all indexes:

# Remove just a single value
$object->removeIndex("index_name", "int", 2);

# Remove all values from an index
$object->removeAllIndexes("index_name", "int");

# Remove all index types for a given index name
$object->removeAllIndexes("index_name");

# Remove all indexes
$object->removeAllIndexes();

Likewise you can remove auto indexes:

# Just the "foo" index
$object->removeAutoIndex("foo", "int");

# All auto indexes
$object->removeAllAutoIndexes("foo", "int");

# All auto indexes
$object->removeAllAutoIndexes();

Mass load indexes, or just replace an existing index:

$object->setIndex("index_name", "int", array(1, 2, 3));
$object->setIndex("text_index", "bin", "foo");

## Querying Secondary Indexes ##
Secondary indexes can be queried using the RiakBucket::indexSearch() method. This returns an array of RiakLink objects.

# Exact Match
$results = $bucket->indexSearch("index_name", "int", 1);
foreach ($results as $link) {
echo "Key: {$link->getKey()}
";
$object = $link->get();
}

# Range Search
$results = $bucket->indexSearch("index_name", "int", 1, 10);

Duplicate entries may be found in a ranged index search if a given index has multiple values that fall within the range. You can request that these duplicates be eliminated in the result.

$results = $bucket->indexSearch("index_name", "int", 1, 10, true);