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,key
和 id
是文档 _id
。重要的是要了解 _all_docs 实际上是一个 built-in 视图,这解释了为什么 key
和 id
出现在 _all_docs 结果中。
如果实际上您希望文档根据时间排序,则向文档添加创建时间戳并基于该时间戳构建视图,例如如果 creationTime
是表示 Unix 纪元中的时间点(毫秒)的整数,则 map 函数可能如下所示。
function(doc) {
emit(doc.creationTime);
}
我正在使用 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,
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,key
和 id
是文档 _id
。重要的是要了解 _all_docs 实际上是一个 built-in 视图,这解释了为什么 key
和 id
出现在 _all_docs 结果中。
如果实际上您希望文档根据时间排序,则向文档添加创建时间戳并基于该时间戳构建视图,例如如果 creationTime
是表示 Unix 纪元中的时间点(毫秒)的整数,则 map 函数可能如下所示。
function(doc) {
emit(doc.creationTime);
}