Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>As a response to the OP's problem, Couch is probably not the best choice here. Using views is a great way to keep track of inventory, but clamping to 0 is more or less impossible. The problem being the race condition when you read the result of a view, decide you're ok to use a "hammer-1" item, and then write a doc to use it. The problem is that there's no atomic way to only write the doc to use the hammer if the result of the view is that there are > 0 hammer-1's. If 100 users all query the view at the same time and see 1 hammer-1, they can all write a doc to use a hammer 1, resulting in -99 hammer-1's. In practice, the race condition will be fairly small - really small if your DB is running localhost. But once you scale, and have an off site DB server or cluster, the problem will get much more noticeable. Regardless, it's unacceptable to have a race condition of that sort in a critical - money related system.</p> <p>An update to MrKurt's response (it may just be dated, or he may have been unaware of some CouchDB features)</p> <p>A view is a good way to handle things like balances / inventories in CouchDB.</p> <p>You don't need to emit the docid and rev in a view. You get both of those for free when you retrieve view results. Emitting them - especially in a verbose format like a dictionary - will just grow your view unnecessarily large.</p> <p>A simple view for tracking inventory balances should look more like this (also off the top of my head)</p> <pre><code>function( doc ) { if( doc.InventoryChange != undefined ) { for( product_key in doc.InventoryChange ) { emit( product_key, 1 ); } } } </code></pre> <p>And the reduce function is even more simple</p> <pre><code>_sum </code></pre> <p>This uses a <a href="http://wiki.apache.org/couchdb/Built-In_Reduce_Functions" rel="nofollow">built in reduce function</a> that just sums the values of all rows with matching keys.</p> <p>In this view, any doc can have a member "InventoryChange" that maps product_key's to a change in the total inventory of them. ie.</p> <pre><code>{ "_id": "abc123", "InventoryChange": { "hammer_1234": 10, "saw_4321": 25 } } </code></pre> <p>Would add 10 hammer_1234's and 25 saw_4321's.</p> <pre><code>{ "_id": "def456", "InventoryChange": { "hammer_1234": -5 } } </code></pre> <p>Would burn 5 hammers from the inventory.</p> <p>With this model, you're never updating any data, only appending. This means there's no opportunity for update conflicts. All the transactional issues of updating data go away :)</p> <p>Another nice thing about this model is that ANY document in the DB can both add and subtract items from the inventory. These documents can have all kinds of other data in them. You might have a "Shipment" document with a bunch of data about the date and time received, warehouse, receiving employee etc. and as long as that doc defines an InventoryChange, it'll update the inventory. As could a "Sale" doc, and a "DamagedItem" doc etc. Looking at each document, they read very clearly. And the view handles all the hard work.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload