Skip to content

Instantly share code, notes, and snippets.

@omegahm
Created May 21, 2015 13:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save omegahm/351468ac10530826cacc to your computer and use it in GitHub Desktop.
Save omegahm/351468ac10530826cacc to your computer and use it in GitHub Desktop.
Couch Presentation
<!DOCTYPE html>
<html>
<head>
<title>CouchDB presentation</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8">
<link rel="icon" href="http://couchdb.apache.org/favicon.ico">
<style>
@import url(http://fonts.googleapis.com/css?family=Nunito:100,100italic,300italic,300,400,400italic,700,700italic);
@import url(https://fonts.googleapis.com/css?family=Source+Code+Pro:400,700,400italic);
body {
font-family: 'Nunito';
}
.remark-code, .remark-inline-code {
font-family: 'Source Code Pro';
}
.remark-slide-content {
font-size: 25px;
background-position: 98% 98%;
background-size: 100px;
}
</style>
</head>
<body>
<script src="https://gnab.github.io/remark/downloads/remark-latest.min.js"></script>
<script>
var slideshow = remark.create({
ratio: '16:9',
navigation: {
scroll: false,
touch: false,
click: true,
},
sourceUrl: 'presentation.md'
});
</script>
</body>
</html>

class: center, middle

CouchDB

CouchDB


layout: true background-image: url(http://couchdb.apache.org/image/couch.png) background-position: right

Introduktion

Apache CouchDBTM er:

  • Database
  • Document Store
  • NoSQL
  • JSON documents
  • JavaScript
  • MapReduce
  • skrevet i Erlang
  • RELAX

Hvad kan jeg bruge det til?

Dokumenter, måske med forskellige skemaer, kan lægge i samme "tabel" i CouchDB.

Din data er bare JSON.

Man kan have mange databaser, men ingen tabeller.

En database indeholder derfor alt data om et emne. Man kan blande sin data, som man lyster.


Hvad kan jeg bruge det til?

F.eks. kan man have:

{
  type: 'mail',
  uuid: 'abcd1234',
  recipient: 'mads.ohm@gmail.com',
  subject: 'Hello, World!'
}

og

{
  type: 'mail_event',
  event: 'opened',
  mail_uuid: 'abcd1234'
}

Hvad kan jeg bruge det til?

Da det ikke er en relationel database, vil man dog normalt lave dem indlejret:

{
  type: 'mail',
  uuid: 'abcd1234',
  recipient: 'mads.ohm@gmail.com',
  subject: 'Hello, World!',
  events: ['opened']
}

Jamen, hvordan finder jeg min data?

Gennem views selvfølgelig. Hvad er et view? Javascript!

Et view består af en map-funktion og muligvis en reduce-funktion.

En map-funktion kan være:

function(doc) {
  if (doc['type'] == 'mail') {
    emit(doc._id, null);
  }
}

Jamen, hvordan finder jeg min data?

function(doc) {
  if (doc['type'] == 'mail') {
    emit(doc._id, null);
  }
}

emit-funktionen her er den specielle.

Vi emitter en grupperingsnøgle og en værdi. Grupperingsnøglen kan være én værdi eller et array.

Værdien vil blive sendt til reduce-funktionen.


Jamen, hvordan finder jeg min data?

function(doc) {
  if (doc['type'] == 'mail') {
    emit(doc._id, null);
  }
}

Ovenstående map-funktion vil blot emitte alle mail-dokumenters interne id.

Der er ingen værdi, så intet at reducrere på.


Jamen, hvordan finder jeg min data?

Vil vi i stedet blot tælle hvor mange dokumenter af hver type, som er i databasen, kan vi bruge:

function(doc) {
  emit(doc['type'], 1);
}

herefter kan vi summere værdier i vores reduce-funktion.


Jamen, hvordan finder jeg min data?

Vi hiver data ud gennem et HTTP API, f.eks. med:

$ curl -XGET https://couch.lokalebasen.dk/DATABASE/_design/DESIGN_NAME/_view/VIEW_NAME

Vores resultat vil således blot være f.eks.:

[
  {"id":"08d0de898bd50d10fb","key":"08d0de898bd50d10fb","value":null},
  {"id":"08d0de898bd50d1f47","key":"08d0de898bd50d1f47","value":null},
  {"id":"08d0de898bd5270695","key":"08d0de898bd5270695","value":null},
  {"id":"08d0de898bd52719af","key":"08d0de898bd52719af","value":null},
  {"id":"08d0de898bd5271d12","key":"08d0de898bd5271d12","value":null}
]

Jamen, hvordan finder jeg min data?

OBS. Det er ikke en relationel database.

Vi gør altså ikke ting som:

Article.find_by_id("abcde12345")

Det kan lade sig gøre, ved brug af key, men det tager linær tid, da den skal søge efter dit dokument.

Der er altså ikke indeks på sådanne ting.


Designdokument?

Vores map- og reduce-funktioner skal leve et sted.

De lever i et designdokument, som også blot er et dokument i databasen.

...
"views": {
  "all": {
    "map": "function(doc) {\n if (doc['type'] == 'MailDump') {\n emit(doc._id, null);\n }\n }"
  }
}
...

Reduce-funktion

Hvad kan jeg så med en reduce-funktion?

Mange gange vil man blot have summen af sine emitted værdier. Dette kan gøres med:

function(_key, values, _rereduce) {
  var i = 0;
  values.forEach(function(value) {
    i += value;
  });
  return value;
}

eller endnu nemmere:

_sum

Rereduce?

Vores reduce-funktion modtager værdier i klumper. Den kan således få f.eks. 10 værdier ad gangen ud af 100 værdier i alt. De 10 resultater det så vil give, vil blive smidt igennem reduce en gang også, men denne gang med rereduce sat til true.

Man kan således se om det er emitted værdier eller resultater, som man skal tage hånd om, men reduce-funktionen skal kunne håndtere begge dele.


Views

I stedet for tabeller, har man således forskellige views, hver med sin map- og reduce-funktion. På den måde kan man hente det data ud man vil.

Det smarte (og det som skiller CouchDB fra andre databaser) ved dette, er at disse er "cached". Når man læser fra et view kan man vælge om man er okay med stale data.

Stale kan have tre forskellige værdier: ok, update_after og false.


Views

Ved ok får man det cached resultat. Dette ligger på disk på CouchDB serveren.

Ved update_after får man igen det cached resultat, men man sætter også en worker igang, som læser ændringer siden sidste cache og kører dem igennem din MapReduce og tilføjer til det cached resultat, så du næste gang får "bedre" data.

Ved false venter du på at workeren har udført sit job og får derefter data. Dette er klart den langsomste måde at arbejde, men hvis man ikke kan bruge gammel data, bliver man selvfølgelig nød til dette.


Views

Hvis man skirver sine MapReduces, så man ikke skal lave mere arbejde på data efterfølgende, er det således rigtig hurtigt at hente data.

Views er dyre i form af diskplads, da alt data vil lægge på disken flere gange.


Attachments

Da alle dokumenter er, vel, dokumenter, kan man også gemme f.eks. HTML- eller andre slags filer.

Man kan vedhæfte disse til sine dokumenter, og således få et attachment.

Vi bruger dette til at gemme afsendte mails (f.eks. https://couch.lokalebasen.dk/lb_mailer/000d512dddbb0c735496fb2a93a85a99/body.html)


Og meget, meget mere...

Couch har også:

  • Futon, deres front-end
  • Temporary Views
  • Indlejret apps
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment