Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>You are using the common pattern of a real number for user control of sorting. That is a fine technique, recommended by Damien Katz. To move between adjacent documents <code>A</code> and <code>B</code>, then you set your <code>sort</code> field to the average of <code>A.sort</code> and <code>B.sort</code>.</p> <p>This question has several parts.</p> <h2>What about floating point precision?</h2> <p>Javascript <code>Number</code>s are double-precision IEEE-754 floating point numbers. They have limited precision.</p> <p>Doubles have a lot of precision. If this is human-initiated activity then it will be a very long time before dragging and dropping hits the limit. But you have two choices:</p> <h3>1. Re-normalize the sort values in the background</h3> <p>Remember rewriting your line numbers in BASIC? Same thing.</p> <p>Have a cron job or some other task (<a href="http://nodejs.org" rel="noreferrer">NodeJS</a> is getting popular) to check for unacceptably close sort values and space them out. This could use sophisticated heuristics such as:</p> <ul> <li>Wait until the site is under low activity to fix the <code>sort</code>s</li> <li>Wait until a specific user to be inactive for X time before fixing his <code>sort</code>s</li> <li>Only make modifications which space out <code>sort</code> values but which never change the view result. In other words, if you have <code>0.001</code>, <code>0.002</code>, and <code>0.003</code>, move the <code>0.003</code> first to e.g. <code>0.100</code>, then change <code>0.002</code> to <code>0.005</code>. That may have a slight helpful effect in the UI but remember, replication may not copy these in the same order so the benefit is marginal, perhaps not worth the complexity.</li> </ul> <h3>2. Use a decimal data type with unlimited precision</h3> <p>Instead of <code>sort</code> storing a Javascript <code>Number</code>, it could store a string from <em>but not including</em> <code>"0.0"</code> through <code>"1.0"</code> (say, to 100 digits). Then a string sort is also a numeric sort. (You have "anchors" at 0.0 and 1.0 which are invalid for documents. To insert a document in the first position, set <code>sort</code> to the average of 0.0 and the current first document. For the last position, <code>sort</code> is the average of the last document and 1.0.)</p> <p>Next, your client (whoever calculates the <code>sort</code> value) needs arbitrary-precision real number types. Java, Ruby, Python, pretty much all the languages have them. This post even inspired me to make a quick project, <a href="http://github.com/jhs/bigdecimal.js" rel="noreferrer">BigDecimal for Javascript</a> which is the <code>BigDecimal</code> code from Google Web Toolkit (which itself came from Apache Harmony). But there are other implementations too.</p> <p>I personally like <code>BigDecimal</code>. In your case however you would have to change your code to use a string for <code>sort</code>. However the benefit is, you never have to re-normalize the <code>sort</code>s to work around the precision.</p> <h2>What about collisions from concurrent activity?</h2> <p>CouchDB is Relaxed. What will happen is what users expect. CouchDB documents mimic the real world. As Chris Anderson says, "there are no transactions in real life."</p> <p>For three elements in a UI:</p> <ul> <li>ItemA</li> <li>ItemB</li> <li>ItemC</li> </ul> <p>What if I move <code>A</code> after <code>C</code> and you move <code>B</code> after C? Clearly, the list will either be <code>C B A</code> or <code>C A B</code>. Which should it be? That depends on your application?</p> <p>Either, <strong>it doesn't matter</strong>: Great! CouchDB will order <code>A</code> and <code>B</code> arbitrarily and you will be fine. Users will infer (or see if your UI is good) that somebody else moved the other item.</p> <p>Or,<strong>B must come before A because [some reason]</strong>: Well then, your <code>sort</code> value is wrong. It should include all relevant data to decide sub-sorts. For example, you can <code>emit([120.000, doc.userLastName], doc)</code>. When users move docs to the same place, the sort becomes alphabetical.</p> <p>If you say, <strong>A cannot be moved so soon after B moved</strong> then that is also application code that must be implemented regardless of the data store. In other words, it's not a transactional thing, it is software logic. For dragging and dropping UI elements, my feeling is, it's not worth it and the "it doesn't matter" solution is best.</p>
 

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