Pouch DB 数据未按排序顺序插入

Pouch DB data is not inserted in sorted order

我正在使用 electron 和 pouchdb 开发小型表格。

当向数据库中插入数据时,直到第 9 个文档它插入完美,但在第 10 个文档上它插入到文档的第二个位置而不是插入到最后一个

插入第 10 个文档之前

{
  "total_rows": 9,
  "offset": 0,
    "rows": [
    { "id": "1", "key": "1", "value": {...} },
    { "id": "2", "key": "2", "value": {...} },   
    { "id": "3", "key": "3", "value": {...} },
    { "id": "4", "key": "4", "value": {...} }    
    { "id": "5", "key": "5", "value": {...} },
    { "id": "6", "key": "6", "value": {...} },   
    { "id": "7", "key": "7", "value": {...} },
    { "id": "8", "key": "8", "value": {...} },
    { "id": "9", "key": "9", "value": {...} }
  ]
}

插入第 10 个文档后

{
  "total_rows": 10,
  "offset": 0,
    "rows": [
    { "id": "1", "key": "1", "value": {...} },
    { "id": "10", "key": "10", "value": {...} },
    { "id": "2", "key": "2", "value": {...} },   
    { "id": "3", "key": "3", "value": {...} },
    { "id": "4", "key": "4", "value": {...} }    
    { "id": "5", "key": "5", "value": {...} },
    { "id": "6", "key": "6", "value": {...} },   
    { "id": "7", "key": "7", "value": {...} },
    { "id": "8", "key": "8", "value": {...} },
    { "id": "9", "key": "9", "value": {...} }
  ]
}

这里附上js代码

// form submit
const form = document.getElementById("form1");
form.addEventListener("submit", dbsubmit);

function dbsubmit(e) {
   e.preventDefault();
   //   getting values from form
   var Sno = document.getElementById("number").value
   var date = document.getElementById("date").value;
   var Time = document.getElementById("time").value;
   var Trip = document.querySelector('input[name="Trip"]:checked').value;
   var TripType = document.querySelector('input[name="Type"]:checked').value;
 
 // assigning form values to db table names
  var doc = {
    _id: Sno,
    Date: date,
    time: Time,
    trip: Trip,
    triptype: TripType,
  };

   // inserting to db
  db.put(doc, function(err, response) {
    if (err) {
      return console.log(err);
    } else {
      console.log("Document created Successfully", response);
    }
  });
}

插入到第 9 个 9th doc 时它完美地插入但是当插入第 10 个 doc 时它插入到第二个位置。

文档应该按id排序,想用它在另一个页面查看。

调试了没找到解决办法,谁能帮我解决一下?

谢谢

关于文档插入,您有一个错误的概念,无论是关于时间的插入顺序很重要,就像 MS/SQL 这样的 RDBMS 所期望的那样,或者认为字符串表示形式应根据隐含的数值对数值进行排序(数据库会随意猜测)。

如明确所述here, and , and as specified by the CouchDB documentation 3.2.2.5. Collation Specification

Comparison of strings is done using ICU which implements the Unicode Collation Algorithm, giving a dictionary sorting of keys. This can give surprising results if you were expecting ASCII ordering.

文档不是按插入顺序返回的,而是根据应用于文档 ID 的 整理规则 返回的,文档 ID 是 字符串.

例如,您希望这样的顺序:

row # id
0 1
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10

但是这不符合整理规则,这会产生

row # id
0 1
1 10
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9

再次强调,插入顺序(更不用说隐含的数值)不会影响结果的顺序,这一点再怎么强调也不为过。从 RDBMS 的角度来看,将 _all_docs 结果视为按 _id 上的索引排序是有帮助的,该索引根据排序规则排序(同样,对于字符串,因为所有 _id 都是类型字符串).

下面的代码片段通过创建 100 个 ID 范围从 1 到 100 的文档来演示这一点。

// generate canned test documents with doc _id's in the range 1 to 100.
function getDocsToInstall() {
  let docs = [];
  for (let i = 1; i < 101; i++) {
    //  _id must be a string type because that's the way it is, period.
    docs.push({
      _id: i.toString()
    });
  }
  return docs;
}

let db;

// init db instance
async function initDb() {

  db = new PouchDB('test', {
    adapter: 'memory'
  });
  await db.bulkDocs(getDocsToInstall());
}

initDb().then(async() => {
  let options = {
    limit: 25,
    include_docs: false,
    reduce: false
  };

  const result = await db.allDocs(options);
  showResult(result);

});


function gel(id) {
  return document.getElementById(id);
}

function cel(name) {
  return document.createElement(name);
}

function addColumn(tr, value) {
  const td = cel('td');
  td.innerText = value;
  tr.append(td);
}

function addRow(row, index) {
  const tr = cel('tr');
  [index, row.id].forEach(value => addColumn(tr, value));
  gel('table').append(tr);
}

function showResult(result) {
  const table = gel('table');
  result.rows.forEach((row, index) => {
    addRow(row, index);
  });
}
th,
td {
  padding: .5em;
  text-align: left;
  min-width: 4em;
}

table {
  border-collapse: collapse;
}
<script src="https://cdn.jsdelivr.net/npm/pouchdb@7.1.1/dist/pouchdb.min.js"></script>
<script src="https://github.com/pouchdb/pouchdb/releases/download/7.1.1/pouchdb.memory.min.js"></script>
<table id="table" border="1">
  <tr>
    <th>row #</th>
    <th>id</th>

  </tr>
</table>

must-get 从该片段中得出的结论是返回的前 3 个文档是

row # id
0 1
1 10
2 100

因为 janl pointed out here if you need to access documents in terms of numerical ordering, then creating a view 是一个不错的选择,下面的代码片段对此进行了演示。

该代码段并排显示了 _all_docs 和 my_index 视图的结果。

// generate canned test documents with doc _id's in the range 1 to 100.
function getDocsToInstall() {
  let docs = [];
  for (let i = 1; i < 101; i++) {
    //  _id must be a string type because that's the way it is, period.
    docs.push({
      _id: i.toString()
    });
  }
  // add a design doc/view for numerically ordered documents
  docs.push({
    _id: '_design/my_ddoc',
    views: {
      my_index: {
        map: function(doc) {
          emit(Number(doc._id));
        }.toString()
      }
    }
  })
  return docs;
}

let db;

// init db instance
async function initDb() {

  db = new PouchDB('test', {
    adapter: 'memory'
  });
  await db.bulkDocs(getDocsToInstall());
}

initDb().then(async() => {
  let options = {
    limit: 25,
    include_docs: false,
    reduce: false
  };

  const allDocs = await db.allDocs(options);
  const view = await db.query('my_ddoc/my_index');
  showResult(allDocs, view);

});


function gel(id) {
  return document.getElementById(id);
}

function cel(name) {
  return document.createElement(name);
}

function addColumn(tr, value) {
  const td = cel('td');
  td.innerText = value;
  tr.append(td);
}

function addRow(index, allDocs, view) {
  const tr = cel('tr');
  [index, allDocs.rows[index].key, view.rows[index].key].forEach(value => addColumn(tr, value));
  gel('table').append(tr);
}
// show allDocs and view results side by side
function showResult(allDocs, view) {
  const table = gel('table');
  for (let i = 0; i < allDocs.rows.length; i++) {
    addRow(i, allDocs, view);
  };
}
th,
td {
  padding: .5em;
  text-align: left;
  min-width: 4em;
}

table {
  border-collapse: collapse;
}
<script src="https://cdn.jsdelivr.net/npm/pouchdb@7.1.1/dist/pouchdb.min.js"></script>
<script src="https://github.com/pouchdb/pouchdb/releases/download/7.1.1/pouchdb.memory.min.js"></script>
<table id="table" border="1">
  <tr>
    <th>row #</th>
    <th>_all_docs key</th>
    <th>my_index key</th>
  </tr>
</table>

请注意,对于 _all_docs,keyid 是文档 _id。重要的是要了解 _all_docs 实际上是一个 built-in 视图,这解释了为什么 keyid 出现在 _all_docs 结果中。

如果实际上您希望文档根据时间排序,则向文档添加创建时间戳并基于该时间戳构建视图,例如如果 creationTime 是表示 Unix 纪元中的时间点(毫秒)的整数,则 map 函数可能如下所示。

function(doc) {
   emit(doc.creationTime);
}