SlideShare una empresa de Scribd logo
1 de 47
Descargar para leer sin conexión
Esti Álvarez @esti
Conferencia Rails 2010
viernes 5 de noviembre de 2010
Relational DatabasesDocumental Databases
Schema-free Document
Oriented Database
viernes 5 de noviembre de 2010
Key Features
• Completely dynamic schema
• Key-value store in JSON format with B-
Tree indexing
• Append-only (all or nothing)
• Concurrent reads and writes
• Very reliable (Erlang)
viernes 5 de noviembre de 2010
Replication
• Bidirectional replication with built in
conflict resolution
• Offline by default
• Incremental replication
viernes 5 de noviembre de 2010
Database interaction
• Data is stored and returned in JSON
format
• Queried via HTTP RESTful API
• Index building language: Javascript
viernes 5 de noviembre de 2010
Database interaction
• Data is stored and returned in JSON
format
• Queried via HTTP RESTful API
• Index building language: Javascript
“Django may be built for theWeb, but CouchDB is built of the Web. I’ve never
seen software that so completely embraces the philosophies behind HTTP.“
Creator of Django
viernes 5 de noviembre de 2010
When should I use
CouchDB?
• Concurrent Distributed systems
• Systems where data consistency is
important
• Offline by default
viernes 5 de noviembre de 2010
Futon. http://localhost:5984
viernes 5 de noviembre de 2010
Learn by example
viernes 5 de noviembre de 2010
JSON data storage
{
"name": "Homer",
"last_names": ["Simpson", "Duff"],
"phone_numbers": {
"mobile": "555-666-777",
"work": "666-777-555"
},
"interests": ["beer", "donuts", "couches"]
}
viernes 5 de noviembre de 2010
JSON data storage
{
"name": "Homer",
"last_names": ["Simpson", "Duff"],
"phone_numbers": {
"mobile": "555-666-777",
"work": "666-777-555"
},
"interests": ["beer", "donuts", "couches"]
}
viernes 5 de noviembre de 2010
JSON data storage
{
"name": "Homer",
"last_names": ["Simpson", "Duff"],
"phone_numbers": {
"mobile": "555-666-777",
"work": "666-777-555"
},
"interests": ["beer", "donuts", "couches"]
}
viernes 5 de noviembre de 2010
Schema-less
{
"_id": "debd7e7385464f4874dd2a38043f7825",
"_rev": "3-839e43865b653a1ed73c3d21cc17c5dd",
"name": "Homer",
"last_names": ["Simpson", "Duff"],
"phone_numbers": {
"mobile": "555-666-777",
"work": "666-777-555",
"bar": "777-666-555"
},
"interests": ["beer", "donuts", "couches"]
}
viernes 5 de noviembre de 2010
JSON data storage
{
"_id": "debd7e7385464f4874dd2a38043f7825",
"_rev": "3-839e43865b653a1ed73c3d21cc17c5dd",
"name": "Homer",
"last_names": ["Simpson", "Duff"],
"phone_numbers": {
"mobile": "555-666-777",
"work": "666-777-555"
},
"interests": ["beer", "donuts", "couches"]
}
viernes 5 de noviembre de 2010
HTTP RESTful API
$ curl http://localhost:5984/ypages
HTTP/1.1 404 Object Not Found
{"error":"not_found","reason":"no_db_file"}
viernes 5 de noviembre de 2010
Creating the Database
$ curl -X PUT http://localhost:5984/ypages
HTTP/1.1 201 Created
{"ok":true}
viernes 5 de noviembre de 2010
Creating a Document
$curl -v -X PUT http://localhost:5984/ypages/homer -d
'{"name": "Homer",
"last_names": ["Simpson", "Duff"],
"phone_numbers": { "mobile": "555-666-777",
"work": "666-777-555"},
"interests": ["beer", "donuts", "couches"]}'
HTTP/1.1 201 Created
Etag: "1-4a9c28dc2e4227cac13872c89a7875d8"
{"ok":true,"id":"homer","rev":"1-4a9c..."}
viernes 5 de noviembre de 2010
Getting a Document
$ curl -X GET http://localhost:5984/ypages/homer
HTTP/1.1 200 OK
Etag: "1-4a9c28dc2e4227cac13872c89a7875d8"
{"_id":"homer","_rev":"1-4a9c...","name":"Homer"...}
viernes 5 de noviembre de 2010
Updating a Document
$ curl -v -X PUT http://localhost:5984/ypages/homer -d
'{"_rev": "1-4a9c...",
"name": "Marge",
...}'
HTTP/1.1 201 Created
Etag: "2-ca3a39967947f974ac021d9f1bdafd1a"
{"ok":true,"id":"homer","rev":"2-ca3a39..."}
viernes 5 de noviembre de 2010
Querying the database
• Views: the way to arrange data to answer
our questions
• Method to build views:
Incremental MapReduce using Javascript
viernes 5 de noviembre de 2010
Find by name
function(doc) {
if (doc.name) {
emit(doc.name, null);
}
}
viernes 5 de noviembre de 2010
Find by name
$ curl '/ypages/_design/app/_view/by_name'
{"total_rows":4,"offset":0,
"rows":[
{"key":"Bart","value":null},
{"key":"Homer","value":null},
{"key":"Lisa","value":null},
{"key":"Marge","value":null}
]}
viernes 5 de noviembre de 2010
Find by name
$curl '.../by_name?key="Homer"&include_docs=true'
{"total_rows":4,"offset":2,
"rows":[
{"id":"homer",
"key":"Homer",
"value":1,
"doc": {"_id":"debd", "_rev":"3-839", "name":"Homer",
"last_names":["Simpson","Duff"],
"phone_numbers":{"mobile":"555-666-777",
"work":"666-777-555"},
"interests":["beer","donuts","couches"]
}
}
]
}
viernes 5 de noviembre de 2010
Find by phone type
Map:
function (doc) {
var type;
if (doc.name && doc.phone_numbers) {
for (type in doc.phone_numbers) {
emit(type, 1);
}
}
}
viernes 5 de noviembre de 2010
Count by phone type
Reduce:
function (keys, values, rereduce) {
return sum(values);
}
viernes 5 de noviembre de 2010
Count by phone type
$ curl '/ypages/_design/app/_view/by_phone'
{"rows":[{"key":null,"value":9}]}
(reduced by default)
viernes 5 de noviembre de 2010
Find by phone type
$ curl '.../by_phone?group=true'
{"rows":[
{"key":"home","value":1},
{"key":"mobile","value":4},
{"key":"work","value":4}
]}
viernes 5 de noviembre de 2010
Find by phone type
$ curl '.../by_type?key="work"&reduce=false'
{"total_rows":9,"offset":5,"rows":[
{"key":"work","value":1,"id":"..."},
{"key":"work","value":1,"id":"..."},
{"key":"work","value":1,"id":"..."},
{"key":"work","value":1,"id":"..."}
]}
viernes 5 de noviembre de 2010
Many more options
• startkey, endkey, order, limit...
• View’s keys can be anything you like.
Ej. birthdate:
{"total_rows":4,"offset":0,
"rows":[
{"key":[2000, 10, 10], "value":"Bart"},
{"key":[1998, 07, 13], "value":"Lisa"},
{"key":[1950, 05, 10], "value":"Homer"},
{"key":[1950, 02, 12], "value":"Marge"}
]}
viernes 5 de noviembre de 2010
viernes 5 de noviembre de 2010
CouchRest
• A RESTful CouchDB client based on
Heroku's RestClient and Couch.js
• http://github.com/couchrest/couchrest
viernes 5 de noviembre de 2010
CouchRest
• dbr=CouchRest.database("http://localhost:5984/ypages")
• record = dbr.get("homer")
=> {"name"=>"Homer", "_rev"=>"3-b87d", "_id"=>"homer"}
• record['name'] = "Moo"
=> "Moo"
• record.save
=> true
viernes 5 de noviembre de 2010
viernes 5 de noviembre de 2010
Couch Potato
• http://github.com/langalex/couch_potato
• ActiveRecord-like syntax
viernes 5 de noviembre de 2010
Couch Potato
class Contact
include CouchPotato::Persistence
property :name
property :last_names
property :phone_numbers
validates_presence_of :name
view :all, :key => :name
view :by_phone, :map => "function(doc) {
var phone_type;
if (doc.name && doc.phone_numbers) {
for (phone_type in doc.phone_numbers) {
emit(phone_type, 1);
}
}
}"
viernes 5 de noviembre de 2010
Couch Potato
contacts = CouchPotato.database.view Contact.by_phone
:key => “work”, :include_docs => true
=> [#<Contact _id: "8f4aa”...>, ...]
contacts.each do |contact|
contact.name = “Dr. #{contact.name}”
CouchPotato.database.save_document contact
end
viernes 5 de noviembre de 2010
Couch Potato
• Validations
• Callbacks
• Test suite
• ...
viernes 5 de noviembre de 2010
Simply Stored
• http://github.com/peritor/simply_stored
• Built on top of Couch Potato
• Associations: has_many, belongs_to
• Sintactic sugar: find_by_name
viernes 5 de noviembre de 2010
CouchRest Model
• http://github.com/couchrest/couchrest_model
• For Rails 3
viernes 5 de noviembre de 2010
Where?
• Ubuntu CouchDesktop (Ubuntu 9.10)
• BBC: fault tolerant, scalable, multi-data
center key-value store.
• 32 nodes in two datacenters.
• A terabyte of data/day
• ~ 5 billion of reqs/year. 150 million reqs/day
viernes 5 de noviembre de 2010
Our use case
Tracking the activity on a website during a
live-broadcasted twitter-interview.
viernes 5 de noviembre de 2010
Video streaming server logs
(Flash media server)
{
"_id": "ffb297816c756289188ca61dc66d61c7",
"_rev": "1-b78bc6ddfbb1f27259c333694d16ba6a",
"type": "streaming",
"datetime": "2010-03-26 18:15:56",
"x-event": "pause",
"c-client-id": "872845283",
...
}
http://www.irekia.euskadi.net
viernes 5 de noviembre de 2010
Web server logs (Apache)
{
"_id": "fde06b5ecd70736e0deb6a22effff25a",
"_rev": "1-f496524ccba837b529426e0ad2177524",
"type": "web",
"datetime": "2010-10-29 08:32:01",
"path": "es/web_tv/agentes-sociales-economicos-suscriben-pacto-social-vivienda",
"user-agent": "Mozilla/4.0 ...",
...
}
viernes 5 de noviembre de 2010
Questions made by citizens via Twitter
{
"_id": "219d1d871ad0b9a31b5f10302c8ac03e",
"_rev": "1-a4466ffd843164f0f538532aca7d10c6",
"datetime": "2010-10-26 18:24:37",
"text": "#patxilopez Yo queria preguntar sobre un tema de
actualidad q se esta hablando mucho en la calle: Cuando
tendremos Bob Esponja en Euskera?",
"type": "tweet"
...
}
viernes 5 de noviembre de 2010
viernes 5 de noviembre de 2010
I want more!
• Get it! http://couchdb.apache.org/
• The Definitive Guide:
http://guide.couchdb.org/
• Case studies:
http://www.couchone.com/case-studies
viernes 5 de noviembre de 2010
Questions?
Sparktography - http://flickr.com/photos/sparktography/65005867/
viernes 5 de noviembre de 2010

Más contenido relacionado

La actualidad más candente

10 more-things-you-can-do-with-python
10 more-things-you-can-do-with-python10 more-things-you-can-do-with-python
10 more-things-you-can-do-with-pythonDaniel Greenfeld
 
Web scraping 1 2-3 with python + scrapy (Summer BarCampHK 2012 version)
Web scraping 1 2-3 with python + scrapy (Summer BarCampHK 2012 version)Web scraping 1 2-3 with python + scrapy (Summer BarCampHK 2012 version)
Web scraping 1 2-3 with python + scrapy (Summer BarCampHK 2012 version)Sammy Fung
 
Terms of endearment - the ElasticSearch Query DSL explained
Terms of endearment - the ElasticSearch Query DSL explainedTerms of endearment - the ElasticSearch Query DSL explained
Terms of endearment - the ElasticSearch Query DSL explainedclintongormley
 
Document-Oriented Databases: Couchdb Primer
Document-Oriented Databases: Couchdb PrimerDocument-Oriented Databases: Couchdb Primer
Document-Oriented Databases: Couchdb Primerjsiarto
 
PostgreSQL FTS Solutions FOSDEM 2013 - PGDAY
PostgreSQL FTS Solutions FOSDEM 2013 - PGDAYPostgreSQL FTS Solutions FOSDEM 2013 - PGDAY
PostgreSQL FTS Solutions FOSDEM 2013 - PGDAYEmanuel Calvo
 
Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon B...
Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon B...Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon B...
Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon B...Alina Dolgikh
 
The Internet Is Your New Database: An Introduction To The Semantic Web
The Internet Is Your New Database: An Introduction To The Semantic WebThe Internet Is Your New Database: An Introduction To The Semantic Web
The Internet Is Your New Database: An Introduction To The Semantic WebWill Strinz
 
Coffee, Danish & Search: Presented by Alan Woodward & Charlie Hull, Flax
Coffee, Danish & Search: Presented by Alan Woodward & Charlie Hull, FlaxCoffee, Danish & Search: Presented by Alan Woodward & Charlie Hull, Flax
Coffee, Danish & Search: Presented by Alan Woodward & Charlie Hull, FlaxLucidworks
 
Building Your First App: An Introduction to MongoDB
Building Your First App: An Introduction to MongoDBBuilding Your First App: An Introduction to MongoDB
Building Your First App: An Introduction to MongoDBMongoDB
 
New approaches to hypertext and REST in a mobile-first world
New approaches to hypertext and REST in a mobile-first worldNew approaches to hypertext and REST in a mobile-first world
New approaches to hypertext and REST in a mobile-first worldIsrael Shirk
 
龍華大學前端技術分享 Part1
龍華大學前端技術分享 Part1龍華大學前端技術分享 Part1
龍華大學前端技術分享 Part1Jia-Long Yeh
 
03. ElasticSearch : Data In, Data Out
03. ElasticSearch : Data In, Data Out03. ElasticSearch : Data In, Data Out
03. ElasticSearch : Data In, Data OutOpenThink Labs
 
Search Engine-Building with Lucene and Solr, Part 2 (SoCal Code Camp LA 2013)
Search Engine-Building with Lucene and Solr, Part 2 (SoCal Code Camp LA 2013)Search Engine-Building with Lucene and Solr, Part 2 (SoCal Code Camp LA 2013)
Search Engine-Building with Lucene and Solr, Part 2 (SoCal Code Camp LA 2013)Kai Chan
 

La actualidad más candente (13)

10 more-things-you-can-do-with-python
10 more-things-you-can-do-with-python10 more-things-you-can-do-with-python
10 more-things-you-can-do-with-python
 
Web scraping 1 2-3 with python + scrapy (Summer BarCampHK 2012 version)
Web scraping 1 2-3 with python + scrapy (Summer BarCampHK 2012 version)Web scraping 1 2-3 with python + scrapy (Summer BarCampHK 2012 version)
Web scraping 1 2-3 with python + scrapy (Summer BarCampHK 2012 version)
 
Terms of endearment - the ElasticSearch Query DSL explained
Terms of endearment - the ElasticSearch Query DSL explainedTerms of endearment - the ElasticSearch Query DSL explained
Terms of endearment - the ElasticSearch Query DSL explained
 
Document-Oriented Databases: Couchdb Primer
Document-Oriented Databases: Couchdb PrimerDocument-Oriented Databases: Couchdb Primer
Document-Oriented Databases: Couchdb Primer
 
PostgreSQL FTS Solutions FOSDEM 2013 - PGDAY
PostgreSQL FTS Solutions FOSDEM 2013 - PGDAYPostgreSQL FTS Solutions FOSDEM 2013 - PGDAY
PostgreSQL FTS Solutions FOSDEM 2013 - PGDAY
 
Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon B...
Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon B...Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon B...
Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon B...
 
The Internet Is Your New Database: An Introduction To The Semantic Web
The Internet Is Your New Database: An Introduction To The Semantic WebThe Internet Is Your New Database: An Introduction To The Semantic Web
The Internet Is Your New Database: An Introduction To The Semantic Web
 
Coffee, Danish & Search: Presented by Alan Woodward & Charlie Hull, Flax
Coffee, Danish & Search: Presented by Alan Woodward & Charlie Hull, FlaxCoffee, Danish & Search: Presented by Alan Woodward & Charlie Hull, Flax
Coffee, Danish & Search: Presented by Alan Woodward & Charlie Hull, Flax
 
Building Your First App: An Introduction to MongoDB
Building Your First App: An Introduction to MongoDBBuilding Your First App: An Introduction to MongoDB
Building Your First App: An Introduction to MongoDB
 
New approaches to hypertext and REST in a mobile-first world
New approaches to hypertext and REST in a mobile-first worldNew approaches to hypertext and REST in a mobile-first world
New approaches to hypertext and REST in a mobile-first world
 
龍華大學前端技術分享 Part1
龍華大學前端技術分享 Part1龍華大學前端技術分享 Part1
龍華大學前端技術分享 Part1
 
03. ElasticSearch : Data In, Data Out
03. ElasticSearch : Data In, Data Out03. ElasticSearch : Data In, Data Out
03. ElasticSearch : Data In, Data Out
 
Search Engine-Building with Lucene and Solr, Part 2 (SoCal Code Camp LA 2013)
Search Engine-Building with Lucene and Solr, Part 2 (SoCal Code Camp LA 2013)Search Engine-Building with Lucene and Solr, Part 2 (SoCal Code Camp LA 2013)
Search Engine-Building with Lucene and Solr, Part 2 (SoCal Code Camp LA 2013)
 

Destacado

HamidHamed-Twitter
HamidHamed-TwitterHamidHamed-Twitter
HamidHamed-Twitterrulyeta
 
Jan Lehnardt Couch Db In A Real World Setting
Jan Lehnardt Couch Db In A Real World SettingJan Lehnardt Couch Db In A Real World Setting
Jan Lehnardt Couch Db In A Real World SettingGeorge Ang
 
Couch Db In 60 Minutes
Couch Db In 60 MinutesCouch Db In 60 Minutes
Couch Db In 60 MinutesGeorge Ang
 
CouchDB Mobile - From Couch to 5K in 1 Hour
CouchDB Mobile - From Couch to 5K in 1 HourCouchDB Mobile - From Couch to 5K in 1 Hour
CouchDB Mobile - From Couch to 5K in 1 HourPeter Friese
 
Aws, play! couch db scaling soa in the cloud
Aws, play! couch db  scaling soa in the cloudAws, play! couch db  scaling soa in the cloud
Aws, play! couch db scaling soa in the cloudChristophe Marchal
 
Laravel - back-end framework in persian language
Laravel - back-end framework in persian languageLaravel - back-end framework in persian language
Laravel - back-end framework in persian languageOmid Khosrojerdi
 
Couch db@nosql+taiwan
Couch db@nosql+taiwanCouch db@nosql+taiwan
Couch db@nosql+taiwanKenzou Yeh
 
Python-CouchDB Training at PyCon PL 2012
Python-CouchDB Training at PyCon PL 2012Python-CouchDB Training at PyCon PL 2012
Python-CouchDB Training at PyCon PL 2012Stefan Kögl
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on AndroidSven Haiges
 
اسلايد آموزشي هوش تجاري
اسلايد آموزشي هوش تجارياسلايد آموزشي هوش تجاري
اسلايد آموزشي هوش تجاريAli Masoombeigi
 

Destacado (19)

No sql Database
No sql DatabaseNo sql Database
No sql Database
 
Couchdb
CouchdbCouchdb
Couchdb
 
HamidHamed-Twitter
HamidHamed-TwitterHamidHamed-Twitter
HamidHamed-Twitter
 
Jan Lehnardt Couch Db In A Real World Setting
Jan Lehnardt Couch Db In A Real World SettingJan Lehnardt Couch Db In A Real World Setting
Jan Lehnardt Couch Db In A Real World Setting
 
Couch Db In 60 Minutes
Couch Db In 60 MinutesCouch Db In 60 Minutes
Couch Db In 60 Minutes
 
Couch db and_the_web
Couch db and_the_webCouch db and_the_web
Couch db and_the_web
 
Couch db
Couch dbCouch db
Couch db
 
CouchDB Mobile - From Couch to 5K in 1 Hour
CouchDB Mobile - From Couch to 5K in 1 HourCouchDB Mobile - From Couch to 5K in 1 Hour
CouchDB Mobile - From Couch to 5K in 1 Hour
 
Aws, play! couch db scaling soa in the cloud
Aws, play! couch db  scaling soa in the cloudAws, play! couch db  scaling soa in the cloud
Aws, play! couch db scaling soa in the cloud
 
Laravel - back-end framework in persian language
Laravel - back-end framework in persian languageLaravel - back-end framework in persian language
Laravel - back-end framework in persian language
 
Couch db@nosql+taiwan
Couch db@nosql+taiwanCouch db@nosql+taiwan
Couch db@nosql+taiwan
 
Python-CouchDB Training at PyCon PL 2012
Python-CouchDB Training at PyCon PL 2012Python-CouchDB Training at PyCon PL 2012
Python-CouchDB Training at PyCon PL 2012
 
Couch db skillsmatter-prognosql
Couch db skillsmatter-prognosqlCouch db skillsmatter-prognosql
Couch db skillsmatter-prognosql
 
MongoDB
MongoDBMongoDB
MongoDB
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
اسلايد آموزشي هوش تجاري
اسلايد آموزشي هوش تجارياسلايد آموزشي هوش تجاري
اسلايد آموزشي هوش تجاري
 
Intro To Couch Db
Intro To Couch DbIntro To Couch Db
Intro To Couch Db
 
Couch db
Couch dbCouch db
Couch db
 
معماری جاری نرم افزار های شرکت
معماری جاری نرم افزار های شرکتمعماری جاری نرم افزار های شرکت
معماری جاری نرم افزار های شرکت
 

Similar a Meet Couch DB

Mastering ElasticSearch with Ruby and Tire
Mastering ElasticSearch with Ruby and TireMastering ElasticSearch with Ruby and Tire
Mastering ElasticSearch with Ruby and TireLuca Bonmassar
 
elasticsearch basics workshop
elasticsearch basics workshopelasticsearch basics workshop
elasticsearch basics workshopMathieu Elie
 
Elasticsearch in 15 minutes
Elasticsearch in 15 minutesElasticsearch in 15 minutes
Elasticsearch in 15 minutesDavid Pilato
 
Elasticsearch – mye mer enn søk! [JavaZone 2013]
Elasticsearch – mye mer enn søk! [JavaZone 2013]Elasticsearch – mye mer enn søk! [JavaZone 2013]
Elasticsearch – mye mer enn søk! [JavaZone 2013]foundsearch
 
Best Practices - Mobile Developer Summit
Best Practices - Mobile Developer SummitBest Practices - Mobile Developer Summit
Best Practices - Mobile Developer Summitwolframkriesing
 
Rapid Prototyping with Solr
Rapid Prototyping with SolrRapid Prototyping with Solr
Rapid Prototyping with SolrErik Hatcher
 
Neo4j for Ruby and Rails
Neo4j for Ruby and RailsNeo4j for Ruby and Rails
Neo4j for Ruby and RailsPablo Delgado
 
Opening up the Social Web - Standards that are bridging the Islands
Opening up the Social Web - Standards that are bridging the Islands Opening up the Social Web - Standards that are bridging the Islands
Opening up the Social Web - Standards that are bridging the Islands Bastian Hofmann
 
Rapid Prototyping with Solr
Rapid Prototyping with SolrRapid Prototyping with Solr
Rapid Prototyping with SolrErik Hatcher
 
Distributed Social Networking
Distributed Social NetworkingDistributed Social Networking
Distributed Social NetworkingBastian Hofmann
 
Large problems, Mostly Solved
Large problems, Mostly SolvedLarge problems, Mostly Solved
Large problems, Mostly Solvedericholscher
 
Happy Go Programming
Happy Go ProgrammingHappy Go Programming
Happy Go ProgrammingLin Yo-An
 
Distributed percolator in elasticsearch
Distributed percolator in elasticsearchDistributed percolator in elasticsearch
Distributed percolator in elasticsearchmartijnvg
 
The Not Java That's Not Scala
The Not Java That's Not ScalaThe Not Java That's Not Scala
The Not Java That's Not ScalaJustin Lee
 
Seattle hug 2010
Seattle hug 2010Seattle hug 2010
Seattle hug 2010Abe Taha
 
ElasticSearch - DevNexus Atlanta - 2014
ElasticSearch - DevNexus Atlanta - 2014ElasticSearch - DevNexus Atlanta - 2014
ElasticSearch - DevNexus Atlanta - 2014Roy Russo
 

Similar a Meet Couch DB (20)

Mastering ElasticSearch with Ruby and Tire
Mastering ElasticSearch with Ruby and TireMastering ElasticSearch with Ruby and Tire
Mastering ElasticSearch with Ruby and Tire
 
Plone on RelStorage
Plone on RelStoragePlone on RelStorage
Plone on RelStorage
 
06 data
06 data06 data
06 data
 
elasticsearch basics workshop
elasticsearch basics workshopelasticsearch basics workshop
elasticsearch basics workshop
 
Elasticsearch in 15 minutes
Elasticsearch in 15 minutesElasticsearch in 15 minutes
Elasticsearch in 15 minutes
 
Elasticsearch – mye mer enn søk! [JavaZone 2013]
Elasticsearch – mye mer enn søk! [JavaZone 2013]Elasticsearch – mye mer enn søk! [JavaZone 2013]
Elasticsearch – mye mer enn søk! [JavaZone 2013]
 
Best Practices - Mobile Developer Summit
Best Practices - Mobile Developer SummitBest Practices - Mobile Developer Summit
Best Practices - Mobile Developer Summit
 
Rapid Prototyping with Solr
Rapid Prototyping with SolrRapid Prototyping with Solr
Rapid Prototyping with Solr
 
Neo4j for Ruby and Rails
Neo4j for Ruby and RailsNeo4j for Ruby and Rails
Neo4j for Ruby and Rails
 
Opening up the Social Web - Standards that are bridging the Islands
Opening up the Social Web - Standards that are bridging the Islands Opening up the Social Web - Standards that are bridging the Islands
Opening up the Social Web - Standards that are bridging the Islands
 
noSQL @ QCon SP
noSQL @ QCon SPnoSQL @ QCon SP
noSQL @ QCon SP
 
Rapid Prototyping with Solr
Rapid Prototyping with SolrRapid Prototyping with Solr
Rapid Prototyping with Solr
 
Distributed Social Networking
Distributed Social NetworkingDistributed Social Networking
Distributed Social Networking
 
Large problems, Mostly Solved
Large problems, Mostly SolvedLarge problems, Mostly Solved
Large problems, Mostly Solved
 
Happy Go Programming
Happy Go ProgrammingHappy Go Programming
Happy Go Programming
 
Apache solr
Apache solrApache solr
Apache solr
 
Distributed percolator in elasticsearch
Distributed percolator in elasticsearchDistributed percolator in elasticsearch
Distributed percolator in elasticsearch
 
The Not Java That's Not Scala
The Not Java That's Not ScalaThe Not Java That's Not Scala
The Not Java That's Not Scala
 
Seattle hug 2010
Seattle hug 2010Seattle hug 2010
Seattle hug 2010
 
ElasticSearch - DevNexus Atlanta - 2014
ElasticSearch - DevNexus Atlanta - 2014ElasticSearch - DevNexus Atlanta - 2014
ElasticSearch - DevNexus Atlanta - 2014
 

Último

How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 

Último (20)

How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 

Meet Couch DB

  • 1. Esti Álvarez @esti Conferencia Rails 2010 viernes 5 de noviembre de 2010
  • 2. Relational DatabasesDocumental Databases Schema-free Document Oriented Database viernes 5 de noviembre de 2010
  • 3. Key Features • Completely dynamic schema • Key-value store in JSON format with B- Tree indexing • Append-only (all or nothing) • Concurrent reads and writes • Very reliable (Erlang) viernes 5 de noviembre de 2010
  • 4. Replication • Bidirectional replication with built in conflict resolution • Offline by default • Incremental replication viernes 5 de noviembre de 2010
  • 5. Database interaction • Data is stored and returned in JSON format • Queried via HTTP RESTful API • Index building language: Javascript viernes 5 de noviembre de 2010
  • 6. Database interaction • Data is stored and returned in JSON format • Queried via HTTP RESTful API • Index building language: Javascript “Django may be built for theWeb, but CouchDB is built of the Web. I’ve never seen software that so completely embraces the philosophies behind HTTP.“ Creator of Django viernes 5 de noviembre de 2010
  • 7. When should I use CouchDB? • Concurrent Distributed systems • Systems where data consistency is important • Offline by default viernes 5 de noviembre de 2010
  • 9. Learn by example viernes 5 de noviembre de 2010
  • 10. JSON data storage { "name": "Homer", "last_names": ["Simpson", "Duff"], "phone_numbers": { "mobile": "555-666-777", "work": "666-777-555" }, "interests": ["beer", "donuts", "couches"] } viernes 5 de noviembre de 2010
  • 11. JSON data storage { "name": "Homer", "last_names": ["Simpson", "Duff"], "phone_numbers": { "mobile": "555-666-777", "work": "666-777-555" }, "interests": ["beer", "donuts", "couches"] } viernes 5 de noviembre de 2010
  • 12. JSON data storage { "name": "Homer", "last_names": ["Simpson", "Duff"], "phone_numbers": { "mobile": "555-666-777", "work": "666-777-555" }, "interests": ["beer", "donuts", "couches"] } viernes 5 de noviembre de 2010
  • 13. Schema-less { "_id": "debd7e7385464f4874dd2a38043f7825", "_rev": "3-839e43865b653a1ed73c3d21cc17c5dd", "name": "Homer", "last_names": ["Simpson", "Duff"], "phone_numbers": { "mobile": "555-666-777", "work": "666-777-555", "bar": "777-666-555" }, "interests": ["beer", "donuts", "couches"] } viernes 5 de noviembre de 2010
  • 14. JSON data storage { "_id": "debd7e7385464f4874dd2a38043f7825", "_rev": "3-839e43865b653a1ed73c3d21cc17c5dd", "name": "Homer", "last_names": ["Simpson", "Duff"], "phone_numbers": { "mobile": "555-666-777", "work": "666-777-555" }, "interests": ["beer", "donuts", "couches"] } viernes 5 de noviembre de 2010
  • 15. HTTP RESTful API $ curl http://localhost:5984/ypages HTTP/1.1 404 Object Not Found {"error":"not_found","reason":"no_db_file"} viernes 5 de noviembre de 2010
  • 16. Creating the Database $ curl -X PUT http://localhost:5984/ypages HTTP/1.1 201 Created {"ok":true} viernes 5 de noviembre de 2010
  • 17. Creating a Document $curl -v -X PUT http://localhost:5984/ypages/homer -d '{"name": "Homer", "last_names": ["Simpson", "Duff"], "phone_numbers": { "mobile": "555-666-777", "work": "666-777-555"}, "interests": ["beer", "donuts", "couches"]}' HTTP/1.1 201 Created Etag: "1-4a9c28dc2e4227cac13872c89a7875d8" {"ok":true,"id":"homer","rev":"1-4a9c..."} viernes 5 de noviembre de 2010
  • 18. Getting a Document $ curl -X GET http://localhost:5984/ypages/homer HTTP/1.1 200 OK Etag: "1-4a9c28dc2e4227cac13872c89a7875d8" {"_id":"homer","_rev":"1-4a9c...","name":"Homer"...} viernes 5 de noviembre de 2010
  • 19. Updating a Document $ curl -v -X PUT http://localhost:5984/ypages/homer -d '{"_rev": "1-4a9c...", "name": "Marge", ...}' HTTP/1.1 201 Created Etag: "2-ca3a39967947f974ac021d9f1bdafd1a" {"ok":true,"id":"homer","rev":"2-ca3a39..."} viernes 5 de noviembre de 2010
  • 20. Querying the database • Views: the way to arrange data to answer our questions • Method to build views: Incremental MapReduce using Javascript viernes 5 de noviembre de 2010
  • 21. Find by name function(doc) { if (doc.name) { emit(doc.name, null); } } viernes 5 de noviembre de 2010
  • 22. Find by name $ curl '/ypages/_design/app/_view/by_name' {"total_rows":4,"offset":0, "rows":[ {"key":"Bart","value":null}, {"key":"Homer","value":null}, {"key":"Lisa","value":null}, {"key":"Marge","value":null} ]} viernes 5 de noviembre de 2010
  • 23. Find by name $curl '.../by_name?key="Homer"&include_docs=true' {"total_rows":4,"offset":2, "rows":[ {"id":"homer", "key":"Homer", "value":1, "doc": {"_id":"debd", "_rev":"3-839", "name":"Homer", "last_names":["Simpson","Duff"], "phone_numbers":{"mobile":"555-666-777", "work":"666-777-555"}, "interests":["beer","donuts","couches"] } } ] } viernes 5 de noviembre de 2010
  • 24. Find by phone type Map: function (doc) { var type; if (doc.name && doc.phone_numbers) { for (type in doc.phone_numbers) { emit(type, 1); } } } viernes 5 de noviembre de 2010
  • 25. Count by phone type Reduce: function (keys, values, rereduce) { return sum(values); } viernes 5 de noviembre de 2010
  • 26. Count by phone type $ curl '/ypages/_design/app/_view/by_phone' {"rows":[{"key":null,"value":9}]} (reduced by default) viernes 5 de noviembre de 2010
  • 27. Find by phone type $ curl '.../by_phone?group=true' {"rows":[ {"key":"home","value":1}, {"key":"mobile","value":4}, {"key":"work","value":4} ]} viernes 5 de noviembre de 2010
  • 28. Find by phone type $ curl '.../by_type?key="work"&reduce=false' {"total_rows":9,"offset":5,"rows":[ {"key":"work","value":1,"id":"..."}, {"key":"work","value":1,"id":"..."}, {"key":"work","value":1,"id":"..."}, {"key":"work","value":1,"id":"..."} ]} viernes 5 de noviembre de 2010
  • 29. Many more options • startkey, endkey, order, limit... • View’s keys can be anything you like. Ej. birthdate: {"total_rows":4,"offset":0, "rows":[ {"key":[2000, 10, 10], "value":"Bart"}, {"key":[1998, 07, 13], "value":"Lisa"}, {"key":[1950, 05, 10], "value":"Homer"}, {"key":[1950, 02, 12], "value":"Marge"} ]} viernes 5 de noviembre de 2010
  • 30. viernes 5 de noviembre de 2010
  • 31. CouchRest • A RESTful CouchDB client based on Heroku's RestClient and Couch.js • http://github.com/couchrest/couchrest viernes 5 de noviembre de 2010
  • 32. CouchRest • dbr=CouchRest.database("http://localhost:5984/ypages") • record = dbr.get("homer") => {"name"=>"Homer", "_rev"=>"3-b87d", "_id"=>"homer"} • record['name'] = "Moo" => "Moo" • record.save => true viernes 5 de noviembre de 2010
  • 33. viernes 5 de noviembre de 2010
  • 34. Couch Potato • http://github.com/langalex/couch_potato • ActiveRecord-like syntax viernes 5 de noviembre de 2010
  • 35. Couch Potato class Contact include CouchPotato::Persistence property :name property :last_names property :phone_numbers validates_presence_of :name view :all, :key => :name view :by_phone, :map => "function(doc) { var phone_type; if (doc.name && doc.phone_numbers) { for (phone_type in doc.phone_numbers) { emit(phone_type, 1); } } }" viernes 5 de noviembre de 2010
  • 36. Couch Potato contacts = CouchPotato.database.view Contact.by_phone :key => “work”, :include_docs => true => [#<Contact _id: "8f4aa”...>, ...] contacts.each do |contact| contact.name = “Dr. #{contact.name}” CouchPotato.database.save_document contact end viernes 5 de noviembre de 2010
  • 37. Couch Potato • Validations • Callbacks • Test suite • ... viernes 5 de noviembre de 2010
  • 38. Simply Stored • http://github.com/peritor/simply_stored • Built on top of Couch Potato • Associations: has_many, belongs_to • Sintactic sugar: find_by_name viernes 5 de noviembre de 2010
  • 39. CouchRest Model • http://github.com/couchrest/couchrest_model • For Rails 3 viernes 5 de noviembre de 2010
  • 40. Where? • Ubuntu CouchDesktop (Ubuntu 9.10) • BBC: fault tolerant, scalable, multi-data center key-value store. • 32 nodes in two datacenters. • A terabyte of data/day • ~ 5 billion of reqs/year. 150 million reqs/day viernes 5 de noviembre de 2010
  • 41. Our use case Tracking the activity on a website during a live-broadcasted twitter-interview. viernes 5 de noviembre de 2010
  • 42. Video streaming server logs (Flash media server) { "_id": "ffb297816c756289188ca61dc66d61c7", "_rev": "1-b78bc6ddfbb1f27259c333694d16ba6a", "type": "streaming", "datetime": "2010-03-26 18:15:56", "x-event": "pause", "c-client-id": "872845283", ... } http://www.irekia.euskadi.net viernes 5 de noviembre de 2010
  • 43. Web server logs (Apache) { "_id": "fde06b5ecd70736e0deb6a22effff25a", "_rev": "1-f496524ccba837b529426e0ad2177524", "type": "web", "datetime": "2010-10-29 08:32:01", "path": "es/web_tv/agentes-sociales-economicos-suscriben-pacto-social-vivienda", "user-agent": "Mozilla/4.0 ...", ... } viernes 5 de noviembre de 2010
  • 44. Questions made by citizens via Twitter { "_id": "219d1d871ad0b9a31b5f10302c8ac03e", "_rev": "1-a4466ffd843164f0f538532aca7d10c6", "datetime": "2010-10-26 18:24:37", "text": "#patxilopez Yo queria preguntar sobre un tema de actualidad q se esta hablando mucho en la calle: Cuando tendremos Bob Esponja en Euskera?", "type": "tweet" ... } viernes 5 de noviembre de 2010
  • 45. viernes 5 de noviembre de 2010
  • 46. I want more! • Get it! http://couchdb.apache.org/ • The Definitive Guide: http://guide.couchdb.org/ • Case studies: http://www.couchone.com/case-studies viernes 5 de noviembre de 2010