Professional Documents
Culture Documents
will leinweber
will@bitfission.com
acts_as_conference 2009
1
2
this talk: why & how
3
what is couchdb?
4
document database
no schema
5
erlang
concurrent
scalable
6
built for the web
restful
json
7
json
{ "title": "A Brief History of Slinkies",
"chapters": [
{ "title": "Sorta like a spring",
"text": "Round and metal..." },
{ "title": "Stairs",
"text": "They can go down, but not up" }],
"_id": "4b859...",
"_rev": "3280991488"
}
8
multi version concurrency control
no locking
locking mvcc
write reads
9
add only
never in a bad state
10
incremental replication
eventual consistency
winning documents
11
couchdb only apps
javascript + html
12
multiple databases
for a single app
13
integrate with full text search
14
file attachment
15
views
(not queries)
16
stored as design documents
17
view server
javascript (spidermonkey)
ruby and python too
18
map
reduce (optional)
19
goes through each document
very slow
20
map step
emits keys value pairs
21
persisted index
keeps track of changes
22
keep your views fresh
23
http benefits
24
cacheable
load balancers
25
easy interface
understand and implement
26
getting started
27
install couch from svn head
get erlang, spidermonkey, icu
28
gem install jchris-couchrest
lightweight api wrapper
29
db = CouchRest.database!("http://localhost:5984/books")
response = db.save(:title => "recipes") # =>
{"rev"=>"2351730874", "id"=>"07cb62...",
"ok"=>true}
30
$ curl http://localhost:5984/books/07cb6232593b61dd022d1c05b1c7deac
{"_id":"07cb6232593b61dd022d1c05b1c7deac","_rev":"2351730874",
"title":"recipes"}
31
doc["title"] = "cook book"
doc.save # => true
db.get response["id"] # => {"title"=>"cook book",
"_id"=>"07cb623...", "_rev"=>"3767210759"}
32
33
simple view
function(doc) {
if (doc.type == "book") {
emit(null, doc);
}
db.view("books/all")
}
34
view with keys
function(doc) {
emit(doc.type, doc);
}
db.view("books/all" )['rows'].size # => 10
db.view("all/by_type" )['rows'].size # => 30
db.view("all/by_type",
:key => "book")['rows'].size # => 10
35
map reduce
// map // reduce
function(doc) { function(keys,values) {
emit(doc.type, doc); return(values.length);
} }
36
versioning
{
"title": "Slinkies!",
"version": 4,
"master_id": "3de0c...",
"_id": "af322...",
"chapters": [...]
}
37
versioning
// map // reduce
function(doc) { function(keys, values) {
emit( doc.master_id, var max = 0;
doc );
} for(i in values) {
if( values[i].version >
values[max].version ) {
max = i;
}
}
return(values[max]);
}
38
view collation
{ "_id": "abc012", { "_id": "def345",
"_rev": "2387", "_rev": "2387",
"type": "post", "type": "comment",
"data": "..." } "data": "..." }
{ "_id": "r2d2c3",
"_rev": "2653",
"type": "comment",
"data": "..." }
39
view collation
function(doc) {
if (doc.type == "post") {
emit([doc._id, 0], doc);
} else if (doc.type == "comment") {
emit([doc.post, 1], doc);
}
}
40
CouchRest::Model
being removed from couchrest
class Book < CouchRest::Model
key_accessor :title, :text, :author
cast :author, :as => "User"
timestamps!
end
# config/environment.rb
CouchRest::Model.default_database =
CouchRest.database!("appname-#{ENV['RAILS_ENV']}")
41
others
langalex-couch_potato
active couch
42
downsides
43
moving target
44
arbitrary queries are slow
45
lack of supporting tools
46
loss of intuition
47
what you should do next
48
thanks!
49