# Working with documents

## What's a document?

PouchDB is a NoSQL database, meaning that you store unstructured documents rather than explicitly specifying a schema with rows, tables, and all that jazz.

A document might look like this:

    {
      "_id": "mittens",
      "name": "Mittens",
      "occupation": "kitten",
      "age": 3,
      "hobbies": [
        "playing with balls of yarn",
        "chasing laser pointers",
        "lookin' hella cute"
      ]
    }

If you come from a SQL background, this handy conversion chart may help:

SQL concept | PouchDB concept
--- | ---
table | no equivalent
row | document
column | field
primary key | primary key (`_id`)
index | view

We'll discuss these concepts later on.

## Storing a document

To store a document, you simply `put` it:

    var doc = {
      "_id": "mittens",
      "name": "Mittens",
      "occupation": "kitten",
      "age": 3,
      "hobbies": [
        "playing with balls of yarn",
        "chasing laser pointers",
        "lookin' hella cute"
      ]
    };
    db.put(doc);

Whenever you `put()` a document, it must have an `_id` field so that you can retrieve it later.

So now let's `get()` the document by using its `_id`:

    db.get('mittens').then(function (doc) {
      console.log(doc);
    });

You should see:

    {
      "name": "Mittens",
      "occupation": "kitten",
      "age": 3,
      "hobbies": [
        "playing with balls of yarn",
        "chasing laser pointers",
        "lookin' hella cute"
      ],
      "_id": "mittens",
      "_rev": "1-bea5fa18e06522d12026f4aee6b15ee4"
    }

You can see a live example of this code.

The document looks exactly the same as when we put it, except... aha! What is this? There is a new field, `_rev`, that contains what looks like garbage. PouchDB gots some 'splainin' to do.

## Understanding revisions (`_rev`)

The new field, `_rev` is the revision marker. It is a randomly-generated ID that changes whenever a document is created or updated.

Unlike most other databases, whenever you update a document in PouchDB or CouchDB, you must present the entire document along with its current revision marker.

For instance, to increment Mittens' age to 4, we would do:

    doc.age = 4;
    doc._rev = "1-bea5fa18e06522d12026f4aee6b15ee4";
    db.put(doc);

If you fail to include the correct `_rev`, you will get the following sad error:

    {
      "status": 409,
      "name": "conflict",
      "message": "Document update conflict"
    }

`HTTP 409` is a standard HTTP error message that indicates a conflict.

## Updating documents correctly

So to update Mittens' age, we will first need to fetch Mittens from the database, to ensure that we have the correct `_rev` before we put him back.

    // fetch mittens
    db.get('mittens').then(function (doc) {
      // update his age
      doc.age = 4;
      // put him back
      return db.put(doc);
    }).then(function () {
      // fetch mittens again
      return db.get('mittens');
    }).then(function (doc) {
      console.log(doc);
    });

You can see a live example of this code.

Don't worry if the structure of this code seems strange! It's using promises, which will be discussed in the next chapter.

Now you should see the following:

    {
      "name": "Mittens",
      "occupation": "kitten",
      "age": 4,
      "hobbies": [
        "playing with balls of yarn",
        "chasing laser pointers",
        "lookin' hella cute"
      ],
      "_id": "mittens",
      "_rev": "2-3e3fd988b331193beeeea2d4221b57e7"
    }

As you can see, we have successfully updated Mittens' age to 4 (they grow up so fast!), and his revision marker has also changed to `"2-3e3fd988b331193beeeea2d4221b57e7"`. If we wanted to increment his age to 5, we would need to supply this new revision marker.

## Related API documentation

- get()
- put()

## Next

Now that you understand a bit about how to create and update documents, let's take a small detour to talk about asynchronous code.

- ← Working with databases
- Asynchronous code →