Intro To Couch Db
-
Upload
shahar-evron -
Category
Technology
-
view
19.697 -
download
0
description
Transcript of Intro To Couch Db
Introduction to using CouchDB with PHP
By Shahahr EvronZend Technologies
2
Welcome!
I am:▶ A PHP programmer since 2002▶ At Zend since 2005▶ Technical Product Manager for Zend Server
Yes, I have a difficult name (at least for English speakers)
▶ Shachar (German, Dutch)
▶ Shajar (Spanish)
▶ Шахар (Russian)
▶ (Arabic) شخر
▶ (Hebrew) שחר
3
Agenda▶ What is CouchDB?
● What is a Document-Oriented Database?
▶ Basic Concepts & the REST API● Databases
● Documents
▶ Views● Map/Reduce functions● Understanding the view collation
▶ Where to go next?
4
What is Apache CouchDB?
5
CouchDB Is...▶ An Open-Source document-oriented database▶ An Apache project
▶ HTTP based API, uses JSON for data representation▶ Built-in replication / synchronization support▶ Written in Erlang
▶ Started in 2005 by Damien Katz▶ Became an Apache project in 2008▶ Currently in version 0.10▶ API is still changing!
6
A Document Oriented DatabaseData is stored in “documents”
...and not in “relations” like in an RDBMS
7
Relational Storage
ID Name Region Owner
001 Reynholm Industries UK Bob
002 Dunder Mifflin Inc. US Sally
003 MomCorp NNY Sally
ID Account ID Name Email
001 001 Dwight Schrute [email protected]
002 001 Michael Scott [email protected]
003 002 Maurice Moss [email protected]
ID Account ID From Subject Body
001 001 001 Defending from bear attack [CLOB]
002 002 003 FIRE! [CLOB]
8
Document Oriented Storage
{ "Name": "Reynholm Industries" "Region": "UK" "Owner": "Bob" "Contacts": [
{ "Name": "Maurice Moss" "Email": "[email protected]"}{ "Name": "Denholm Reynholm" "Email": "[email protected]"}]
}
{ "From": "Maurice Moss" "Subject": "FIRE!" "Message": "Dear Sir / Madam,
....
...."}
9
Data is indexed with Map/Reduce functionsNo SQL!
▶ Querying is done using “views”▶ Views are defined using map/reduce functions▶ Data is indexed using these views as it is stored in the DB
Map/Reduce functions are:▶ Map functions emit (key, value) interpretation of the data▶ Reduce functions aggregate data emitted by map functions
Map/Reduce functions are written in JavaScript
10
What is it good for?You should use it for...
▶ Storing documents – or any data which is document-like▶ Hosting entire applications!
Why?▶ Very easy to program with – no SQL, no schema, no ORM▶ Schema-less means very easy to deploy changes▶ Easy to administer, backup, replicate, can work offline
You should not use it for...▶ Storing data which is relational in nature▶ Be careful with data that needs to have unique values
11
Hello, CouchDBtime to relax!
12
Accessing CouchDB from PHPCouchDB is accessed using an HTTP based API
▶ You can use any good HTTP client from PHP to access CouchDB● PHP HTTP stream, cURL, pecl_http, Zend_Http_Client … ● We will use Zend_Http_Client in our examples (sorry, I'm biased!)
▶ You can create or use an existing dedicated client library● Wraps the HTTP calls with CouchDB-specific API
Data sent to / from CouchDB is serialized using JSON▶ You can use PHP's ext/json to easily work with it▶ You can use ZF's Zend_Json if you need a portable solution
13
Server APICheck the server status:
echo $client->setUri('http://localhost:5984/') ->request('GET') ->getBody();
{"couchdb":"Welcome","version":"0.9.1"}
Get list of all databases:
echo $client->setUri('http://localhost:5984/_all_dbs') ->request('GET') ->getBody();
["my_db","stoa","test_suite_db","test_suite_db_a"]
14
Database APICreate a new database:
$resp = $client->setUri('http://localhost:5984/mydb') ->request('PUT'); echo $resp->getStatus();
// Expected status is 201
Delete an existing database:$resp = $client->setUri('http://localhost:5984/mydb') ->request('DELETE'); echo $resp->getStatus();
// Expected status is 200
15
Creating DocumentsCreating a new document with a server-generated ID:
$doc = json_encode(array( 'title' => 'Speaking at ZendCon09!', 'tags' => array('speaking', 'php', 'zendcon', 'zend'), 'created_at' => 1255977324, 'published' => true, 'content' => "Yey! I'm speaking at ZendCon!" ));
$resp = $client->setUri('http://localhost:5984/mydb') ->setRawData($doc, 'text/json') ->request('POST');
// Response code should be 201
echo $resp->getBody();
// {"ok":true,"id":"b82d17579b9c901f6911727167a39987","rev":"1-190672822"}
16
The Futon Administration Interface
17
Creating DocumentsCreating a new document with a user defined ID:
$doc = json_encode(array( 'title' => 'Speaking at ZendCon09!', 'tags' => array('speaking', 'php', 'zendcon', 'zend'), 'created_at' => 1255977324, 'published' => true, 'content' => "Yey! I'm speaking at ZendCon!" ));
$resp = $client->setUri('http://localhost:5984/mydb/speaking-at-zendcon') ->setRawData($doc, 'text/json') ->request('PUT');
// Response code should be 201
echo $resp->getBody();
// {"ok":true,"id":"speaking-at-zendcon","rev":"1-2035733428"}
18
Accessing DocumentsAccess the current revision of a document:$docId = 'speaking-at-zendcon'; $resp = $client->setUri('http://localhost:5984/mydb/' . urlencode($docId)) ->request('GET'); var_export(json_decode($resp->getBody(), true));
▶ Expected output:array ( '_id' => 'speaking-at-zendcon', '_rev' => '1-2035733428', 'title' => 'Speaking at ZendCon09!', 'tags' => array ('speaking', 'php', 'zendcon', 'zend'), 'created_at' => 1255977324, 'published' => true, 'content' => 'Yey! I\'m speaking at ZendCon!', );
▶ You can access older revisions of the same document:'http://localhost:5984/mydb/speaking-at-zendcon?rev=' . $rev
19
Updating DocumentsDocuments are updated as a whole
▶ You can't “update” a single value inside the document▶ You must specify the current revision number when updating
$doc = json_encode(array( '_rev' => '1-2035733428', 'title' => 'Speaking at ZendCon!', 'tags' => array('speaking', 'php', 'zendcon', 'zend'), 'created_at' => 1255977324, 'published' => false, 'content' => "Yey! I'm speaking at ZendCon!" ));
$resp = $client->setUri('http://localhost:5984/mydb/speaking-at-zendcon') ->setRawData($doc, 'text/json') ->request('PUT'); // Expected code is 201, 409 means revision conflict // Expected body: {"ok":true,"id":"speaking-at-zendcon","rev":"2-2571024485"}
20
Deleting DocumentsDeleting is easy!
▶ Again, you must specify the revision number
$docId = 'speaking-at-zendcon';$rev = '1-2035733428';$url = "http://localhost:5984/mydb/$docId?rev=$rev";$resp = $client->setUri($url) ->request('DELETE');
echo $resp->getStatus();
// Expected status is 200
21
Introducing the Sopha client library...http://github.com/shevron/sopha
22
Sopha is...A CouchDB Client Library (being) written in PHP 5.2
▶ …except for the ViewServer component which is 5.3
Wraps the HTTP/JSON work in a simple API▶ Sopha_Http▶ Sopha_Json
Provides access to main CouchDB features▶ Sopha_Db▶ Sopha_Document▶ Sopha_View
23
Some Sopha API:
Sopha_Db::createDb('mydb', 'localhost', Sopha_Db::COUCH_PORT); $db = new Sopha_Db('mydb'); // when opening an existing DB
$doc = $db->retrieve($docId, 'MyDocumentClass', $revision); $doc->myparam = 'some new value'; $doc->save();
$doc->delete();
$phpValue = array( 'kak' => 'dila', 'ma' => 'nishma' ); $doc = $db->create($phpValue, 'myDocuemtnId');
24
Introducing the Stoa sample applicationhttp://github.com/shevron/stoa
25
Views and Map/Reduce Functions
26
What are views?A convenient way to query your documents
▶ Provide a way to access data based on more than the doc ID▶ Provide a way to aggregate data from several docs
Views are defined in design documents▶ Special URL: /<dbname>/_design/<viewname>▶ Each design document can define several views▶ Each view defines a map function, and can define a reduce
function▶ Documents inserted or updated are indexed using these functions
27
Creating a design document
$mapFunc = 'function(doc) { emit(doc.from, doc); }'; $designDoc = json_encode(array( 'language' => 'javascript', 'views' => array( 'bycontact' => array( 'map' => $mapFunc ) ) ));
$resp = $client->setUri('http://localhost:5984/mydb/_design/email') ->setRawData($designDoc, 'text/json') ->request('PUT');
Creating a design document is like creating a regular document, with special content and URL:
28
Map FunctionsMap functions emit interpretations of documents passed through them
▶ Can emit the entire document or a part of it▶ Can emit multiple results for a single document
Each emitted document has a key▶ The key can be any valid JSON value▶ Key is used for sorting and limiting the query scope
● You can query a view, and specify a single key or a key range
29
Understanding View CollationView results are ordered by key, according to the view collection
View collation order:▶ null▶ Booleans: false, true▶ Numbers▶ Strings, case sensitive (lower case, upper case)▶ Arrays
● Internal sorting by values
▶ Objects● Internal sorting by keys
30
Reduce FunctionsReduce functions reduce mapped values down to a single aggregated value
▶ Reduce is optional – a view can have a map function only▶ Reduce functions receive a set of keys and values
● Can be a set of values emitted by the map function● Can be an already-reduced value returned by a previous run of the
reduce function (rereduce)
▶ Reduce functions can group results according to their key● When not grouped, reduce will return a single value● Example: show count of all contacts vs. count of all contacts per
account
31
Calling views
$url = "_design/post/_view/by-tag";$resp = $client->setUri("http://localhost:5984/$url") ->request('GET');
Views are accessed like regular documents, with a special URL:
{"total_rows":6,"offset":0,"rows":[{"id":"e0a21a071103585d1c2e3e168b2cfe6b",
"key":["buzz",1256058429],"value":{...}},{"id":"f03ddef93502092218cb39c25be47937",
"key":["buzz",1256058469],"value":{...}},{"id":"e0a21a071103585d1c2e3e168b2cfe6b",
"key":["leveraging",1256058429],"value":{...}},{"id":"f03ddef93502092218cb39c25be47937",
"key":["meta",1256058469],"value":"value":{...}},{"id":"f03ddef93502092218cb39c25be47937",
"key":["post",1256058469],"value":"value":{...}},{"id":"e0a21a071103585d1c2e3e168b2cfe6b",
"key":["stuff",1256058429],"value":"value":{...}},]}
32
Query ParametersYou can add the following parameters to the query when calling a view:
▶ key=keyvalue▶ startkey=keyvalue▶ endkey=keyvalue▶ limit=...▶ descending=true▶ skip=...▶ group=true (when calling a reduce view)▶ grouplevel=... (when calling a reduce view)
33
Epilogue
34
Last Advice...
▶ Forget what you know about relational databases!
▶ …but don't try to force data that should not be in CouchDB in to it – you can use both an RDBMS and a document DB!
▶ Understand Map/Reduce
▶ Understand the view collation, and use it creatively
▶ Ask questions!
35
Some things not covered here...But you should probably know about:
▶ Bulk queries
▶ Document attachments
▶ Authentication & access control model
▶ Utilizing HTTP-level caching
▶ Replication model & conflict resolution
▶ In-DB applications
▶ Lucene Integration
▶ Replacing the view server (yes, you can use PHP!)
36
Want to learn more?
Google: http://www.google.com ;)
Docs & Wiki: http://couchdb.apache.org
IRC: #couchdb @ FreeNode
Mailing List : [email protected]
Upcoming Book: http://books.couchdb.org/relax/
37
Thank You!Feedback: [email protected], http://joind.in/890, @shevronSlides will be available at http://arr.gr/
This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.