CRUD Document Operations Using the PHP SDK with Couchbase Server
Operation Basics
Operations use basic PHP data types and most of the PHP data types that can be serialized via the JSON functions are supported by default. Recursive structures cannot be serialized. You may alternatively implement your own transcoders which modify the method by which your documents are serialized to Couchbase. See Transcoders for more details.
If an operation is successful, it will return CouchbaseMetaDoc
that contains the value
of the document (if returned by operation) as well as the cas
value.
If an operation fails, a CouchbaseException
is thrown, which may then be caught.
Creating and Updating Full Documents
You can create documents by using the insert()
or upsert()
methods and update them using the replace()
method.
See Primitive Key-Value Operations for more details.
The following example shows how to create a new document with the insert()
method:
$res = $myBucket->insert('document_name', array('some'=>'value'));
You can specify additional options as a third argument to the insert
, upsert
, and replace
functions.
The options are specified as an associative array:
$bucket->upsert($key, $doc, array("expiry" => 300));
Allowed options are:
-
cas
: The CAS value for the document. If the CAS on the server does not match the CAS supplied to the method, the operation will fail with aCouchbaseException
with a code ofCOUCHBASE_KEY_EEXISTS
error. See Concurrent Document Mutations for more information on using the CAS values. Keep in mind that this case applies only toreplace()
-
expiry
: Specifies the expiry time for the document. If specified, the document will expire and no longer exist after the given number of seconds. See Expiration Overview for more information. -
persist_to
,replicate_to
: Specifies durability requirements for the operations.
Retrieving Documents
You can retrieve documents by using the get()
method.
var_dump($bucket->get("new_document"));
Sample output from the example is as follows:
object(CouchbaseMetaDoc)#6 (4) { ["error"]=> NULL ["value"]=> object(stdClass)#5 (1) { ["foo"]=> string(3) "bar" } ["flags"]=> int(33554438) ["cas"]=> string(9) "eh5m98g0k" }
The get()
method returns a CouchbaseMetaDoc
object.
To get the actual value, use the object’s value
property.
The CAS value is encoded as a string and accessible through cas
property.
Items stored as associative arrays (such as $bucket->upsert(docid, array("prop1" => "value1")) are retrieved as PHP stdObject objects; you must reference fields using $result->value->property rather than $result->value["property"]
|
In some instances you may wish to read from a replica node when the active node is unavailable.
This can be done using the getFromReplica()
.
Removing Documents
You can delete documents by using the remove()
method.
$bucket->remove('document_name');
You may pass a second argument containing options to the remove()
method.
This is passed as an array with the option name as the key and the option value as the array value.
Recognized options are:
-
cas
: Specify the CAS value to use. This will ensure that the document is not removed if the CAS value differs. You may obtain the CAS value fromCouchbaseMetaDoc::cas
, as a return value of a successful operation. -
persist_to
,replicate_to
: Specify durability requirements. In this case, the SDK will check that the items have been properly deleted from the replicas.
Modifying the Expiration
Setting Document expiration can be performed using the touch()
and getAndTouch
methods.
These methods accept an expiry value as their second parameter:
$cb->touch('expires', array("expiry" => 5));
sleep(6)
$cb->get('expires');
PHP Fatal error: Uncaught exception 'CouchbaseException' with message 'LCB_KEY_ENOENT: The key does not exist on the server' in [CouchbaseNative]/CouchbaseBucket.class.php:196 Stack trace: #0 [CouchbaseNative]/CouchbaseBucket.class.php(196): _CouchbaseBucket->get('expires', Array) #1 /private/tmp/dummy.php(7): CouchbaseBucket->get('expires') #2 {main} thrown in [CouchbaseNative]/CouchbaseBucket.class.php on line 196
Document expiration can also be set using the upsert
family of methods which accept an optional expiry
key in their options arrays.
$cb->upsert('expires', "i'm getting old...", array("expiry" => 5));
Batching Operations
Bulk operations may help you perform operations more efficiently and quicker by optimizing how commands are sent on the network.
Bulk operations may be performed by passing an array as the first argument to one of the get()
, upsert()
, insert()
, replace()
and other key-value methods.
When these methods are passed an array as input, they return an array as output, with the array containing document IDs as its keys and their respective CouchbaseMetaDoc
objects as values.
This method works identically to its singular counterpart but instead accepts an array of keys to retrieve and returns an object where the object key matches your document ID and the object value is the result that you would normally expect to see from a singular operation.
For the upsert()
family of methods, the top-level array value is a container for options.
The most important option is value
which contains the actual value to be used as the document.
The following example shows how to insert and retrieve multiple documents. The structure of each document is:
{
"email": <....>
}
$results = $bucket->upsert(array(
'foo' => array('value' => array('email' => 'foo@foo.com')),
'bar' => array('value' => array('email' => 'bar@bar.com')),
'baz' => array('value' => array('email' => 'baz@baz.com'))
));
foreach ($results as $docid => $metadoc) {
echo("$docid => $metadoc->cas\n");
}
foo => 2gywu3yq6s bar => 2hcxy0srv8 baz => 2hcxy0srv8
$results = $bucket->get(array("foo", "bar", "baz"));
foreach ($results as $docid => $metadoc) {
// Each document itself has a 'propname'
echo "Result for $docid\n";
var_dump($metadoc->value);
echo "\n";
}
Result for foo object(stdClass)#7 (1) { ["email"]=> string(11) "foo@foo.com" } Result for bar object(stdClass)#9 (1) { ["email"]=> string(11) "bar@bar.com" } Result for baz object(stdClass)#11 (1) { ["email"]=> string(11) "baz@baz.com" }
Atomic Operations
The PHP Couchbase SDK supports several operations that allow one-step, atomic changes to documents.
These operations include counter
, prepend
, and append
functions.
The counter()
method enables you to use an atomic counter.
The first argument is the document ID, and the second argument is the delta indicating by what amount the counter should be changed.
You may also pass an array of options as the third argument:
-
initial
: Initialize the counter to this value if the counter does not yet exist -
expiry
: Set the document expiration time -
persist_to
,replicate_to
: Specify durability requirements
$result = $bucket->counter('counterId', 50, array('initial' => 100));
echo 'Current counter value is ' . $result->value . "\n";
Atomic byte concatenations can be performed using the append()
and prepend()
methods.
These operations are potentially destructive.
Refer to the API documentation for more information.
Operating with sub-documents
Sub-Document API is available starting Couchbase Server version 4.5. See Sub-Document Operations for an overview. |
Sub-document operations save network bandwidth by allowing you to specify paths of a document to be retrieved or updated.
The document is parsed on the server and only the relevant sections (indicated by paths) are transferred between client and server.
You can execute sub-document operations in the PHP SDK using the retrieveIn
, lookupIn
, and mutateIn
methods.
Each of these methods accepts an id
as its mandatory first argument and return builders CouchbaseLookupInBuilder
and CouchbaseMutateInBuilder
The builders have API to accumulate command specifications and run the full pipeline by the execute()
call.
$res = $bucket->lookupIn('docid')
->get('path.to.get')
->exists('check.path.exists')
->execute();
$res = $bucket->mutateIn('docid')
->upsert('path.to.upsert', $value, true)
->remove('path.to.del')
->execute();
For simply retrieving a list of paths, you may use the retrieveIn
convenience method:
$res = $bucket->retrieveIn('docid', 'path1', 'path2', 'path3')
All sub-document operations return a special CouchbaseDocumentFragment
object.
In contrast with a normal CouchbaseMetaDoc
object, a CouchbaseDocumentFragment
object contains multiple results with multiple statuses, one result/status pair for every input operation.
You can access an individual result/status pair by addressing the value
of CouchbaseDocumentFragment
object as a mapping, and then using index position of the operation as the key:
$res = $bucket->lookupIn('docid')
->get('foo')
->exists('bar')
->exists('baz')
->execute();
# First result
$res->value[0]
Non-JSON Documents and Transcoders
See Non-JSON Documents for a general overview of using non-JSON documents with Couchbase |
All PHP objects which can be represented as JSON may be passed unmodified to a storage function, and be received via the get method without any additional modifications, with only note that by default JSON encoder configured to produce stdClass
instances instead of arrays.
This behavior can be changed by modifying $COUCHBASE_DEFAULT_DECOPTS
:
echo("default JSON decoder options: ");
var_dump($COUCHBASE_DEFAULT_DECOPTS);
$res = $bucket->get('foo');
var_dump($res->value);
echo("setting 'jsonassoc' to true\n");
$COUCHBASE_DEFAULT_DECOPTS['jsonassoc'] = true;
$res = $bucket->get('foo');
var_dump($res->value);
Output:
default JSON decoder options: array(1) { ["jsonassoc"]=> bool(false) } object(stdClass)#4 (1) { ["email"]=> string(11) "foo@foo.com" } setting 'jsonassoc' to true array(1) { ["email"]=> string(11) "foo@foo.com" }
You can modify the default JSON encoders used by the PHP SDK using the setTranscoders
function.
This function accepts a pair of encode and decode functions which are expected transform the raw document depending on the document flags.
The following is an example of a transcoder which will unconditionally transcode all documents as UTF-8 encoded JSON documents.
$bucket->setTranscoders(
function($value) {
return array(json_encode($value), 0, 0);
},
function($value, $flags, $datatype) {
return json_decode($value, true);
}
);
To make migration from 1.x SDK easier, use the JSON serializer.
You may do this with settings in
Also, the serializer may be selected programmatically:
|