Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In the CouchDB _changes response, why are the "changes" elements arrays?

Tags:

couchdb

The response from CouchDB to a _changes request comes back in this format: {"seq":12,"id":"foo","changes":[{"rev":"1-23202479633c2b380f79507a776743d5"}]}

My question - why is the "changes" element an array? What scenario would return more than one item in the changes element? I have never seen an example online with more than one item, and in my own experience I have only seen one item.

I'm writing code that interacts with changes, and I'd like to understand what to do if, in fact, there were more than one item.

Thanks, Mike

like image 343
Mike Hedman Avatar asked Feb 13 '13 00:02

Mike Hedman


1 Answers

The changes element is an array to reflect all existed revision leafs for document. As you know, CouchDB doesn't deletes document completely, but sets gravestone instead to prevent his accidentally resurrection after replication from source that has his older revision that wasn't yet deleted. Also it's possible to have multiple leafs due to update conflicts that have occurs after replication. For example:

  1. Mike have created document in database A and replicated him to database B:

    {"results":[ {"seq":1,"id":"thing","changes":[{"rev":"1-967a00dff5e02add41819138abb3284d"}]} ], "last_seq":1}

  2. John have received your document and updated him in database B:

    {"results":[ {"seq":2,"id":"thing","changes":[{"rev":"2-7051cbe5c8faecd085a3fa619e6e6337"}]} ], "last_seq":2}

  3. But at the same Mike also made few changes (forgot to clean up data or add for something important) for him in database A :

    {"results":[ {"seq":2,"id":"thing","changes":[{"rev":"2-13839535feb250d3d8290998b8af17c3"}]} ], "last_seq":2}

  4. And replicated him again to database B. John receives document in conflict state and by looking at changes feed with query parameter style=all_docs see next result:

    {"results":[ {"seq":3,"id":"thing","changes":[{"rev":"2-7051cbe5c8faecd085a3fa619e6e6337"},{"rev":"2-13839535feb250d3d8290998b8af17c3"}]} ], "last_seq":3}

    While direct access to document returns his data from wining revision (with higher seq number or just latest) it's possible for him to have many of conflicted revisions (imagine concurrent writes for single document it within dozen databases that are replicated between each other)

  5. Now John had decided to resolve this conflict and update actual revision, but drop the other:

    {"results":[ {"seq":4,"id":"thing","changes":[{"rev":"3-2502757951d6d7f61ccf48fa54b7e13c"},{"rev":"2-13839535feb250d3d8290998b8af17c3"}]} ], "last_seq":4}

  6. Wait, the Mike's revision is still there? Why? John in panic removes his document:

    {"results":[ {"seq":5,"id":"thing","changes":[{"rev":"2-13839535feb250d3d8290998b8af17c3"}{"rev":"4-149c48caacb32c535ee201b6f02b027b"}]} ], "last_seq":5}

    Now his version of document is deleted, but he's able to access to Mike's one.

  7. Replicating John changes from database B to database A will all brings tombstone:

    {"results":[ {"seq":3,"id":"thing","changes":[{"rev":"3-2adcbbf57013d8634c2362630697aab6"},{"rev":"4-149c48caacb32c535ee201b6f02b027b"}]} ], "last_seq":3}

    Why so? Because this is the document history about his data "evolution": in real world your documents may have many intermediate leafs distributed among large number of databases and to prevent silent data overwrite due data replication process CouchDB keeps each leaf to help resolve such conflicts. More and probably better explanation you may found in CouchDB wiki about replication and conflicts. Changes feed query parameters are also described there as well.

like image 174
Kxepal Avatar answered Oct 29 '22 21:10

Kxepal