按 unix 时间戳和分页对 CouchDB 结果进行排序
Sorting CouchDB result by unix timestamp and paginate
这几天我一直在努力让分页工作。我有一个带有文档的数据库,并且有一些数据库将时间戳作为降序排序的关键。但我似乎无法获得下一组文档...
如果我 运行 它,我将获得前 5 个文档。当我尝试使用 startkey 或 startkey_docid 时,我似乎只会再次获得相同的行。
尝试沙发文档我不确定我需要什么才能让它工作。
couchdb 的设计如下:
{
"_id": "_design/filters",
"views": {
"blog": {
"map": "function (doc) { if (doc.published && doc.type == 'post') emit(doc.header.date); }"
}
}
}
... header.date
由 +new Date()
生成
在nodejs端,使用github/nano,我使用类似于:
import nano from 'nano';
let db = nano(SERVICE_URL).use('blog_main');
let lastDocId = ctx.query.lastDocId;
let lastSkip = ctx.query.lastSkip ? +ctx.query.lastSkip + 5 : null;
let query = {
limit: 1 + 4, // limit to 5
descending: true, // reverse order: newest to top
include_docs: true,
}
if (lastDocId) { // initally off
query.startkey = lastDocId;
}
if (lastSkip) { // other method for tests
query.skip = lastSkip; // ----> this results in some previous and some new items
}
let itemRows = await db.view('filters','blog', query);
let items = itemRows.rows;
// each doc is in items[].doc
我已经看到 ,排序对我有用 - 但我似乎无法使用分页。
我不确定 "I get the same lines again" 的说法。如果 startkey
是先前结果的第一个而不是最后一个键,那么这是可重现的——这将是 第一个 问题。
无论如何,假设 startkey
是正确的参数 skip
和 startkey
是冲突的。最初 skip
应为 0,之后应为 1,以便在后续查询中跳过 startkey
。
CouchDB 分页文档1 中清楚地概述了此技术。
详情
假设 complete 视图(其中键是 unix 时间戳)是
{
"total_rows":7,
"offset":0,
"rows":[
{"id":"821985c5140ca583e108653fb6091ac8","key":1580050872331,"value":null},
{"id":"821985c5140ca583e108653fb6092c3b","key":1580050872332,"value":null},
{"id":"821985c5140ca583e108653fb6093f47","key":1580050872333,"value":null},
{"id":"821985c5140ca583e108653fb6094309","key":1580050872334,"value":null},
{"id":"821985c5140ca583e108653fb6094463","key":1580050872335,"value":null},
{"id":"821985c5140ca583e108653fb60945f4","key":1580050872336,"value":null},
{"id":"821985c5140ca583e108653fb60949f3","key":1580050872339,"value":null}
]
}
给定初始查询条件
{
limit: 5,
descending: true,
include_docs: false // for brevity
}
确实产生了预期的结果,5 行最近的排在第一位
{
"total_rows":7,
"offset":0,
"rows":[
{"id":"821985c5140ca583e108653fb60949f3","key":1580050872339,"value":null},
{"id":"821985c5140ca583e108653fb60945f4","key":1580050872336,"value":null},
{"id":"821985c5140ca583e108653fb6094463","key":1580050872335,"value":null},
{"id":"821985c5140ca583e108653fb6094309","key":1580050872334,"value":null},
{"id":"821985c5140ca583e108653fb6093f47","key":1580050872333,"value":null}
]
}
现在假设第二个查询是这样
{
limit: 5,
descending: true,
include_docs: false, // for brevity
startkey: 1580050872333,
skip: 5
}
startkey
(先前结果的最后一行的键)是正确的,但 skip
参数实际上是跳过了下一组(逻辑)行。特别是对于这些参数和上面的示例视图,查询将忽略剩余的键,从而导致空行集。
这是我们想要的:
{
limit: 5,
descending: true,
include_docs: false, // for brevity
startkey: 1580050872333,
skip: 1 // just skip the last doc (startkey)
}
1 CouchDB 分页食谱 3.2.5.5. Paging (Alternate Method)
使用 startkey 或 skip,返回的结果也包括一些跳过的结果,或者所有以前的结果(奇怪地混淆)。
我通过使用 - 第二部分扩展结果键解决了这个问题。
由于密钥基于没有时间的日期,因此由于相似的日期时间戳,它似乎重新排列了每个请求的条目。添加第二部分也是可排序的(使用创建的时间戳作为第二部分)修复它。
现在的关键是 [datetimestamp, createdtimestamp] .. 两者都可以降序排列。
这几天我一直在努力让分页工作。我有一个带有文档的数据库,并且有一些数据库将时间戳作为降序排序的关键。但我似乎无法获得下一组文档...
如果我 运行 它,我将获得前 5 个文档。当我尝试使用 startkey 或 startkey_docid 时,我似乎只会再次获得相同的行。
尝试沙发文档我不确定我需要什么才能让它工作。
couchdb 的设计如下:
{
"_id": "_design/filters",
"views": {
"blog": {
"map": "function (doc) { if (doc.published && doc.type == 'post') emit(doc.header.date); }"
}
}
}
... header.date
由 +new Date()
在nodejs端,使用github/nano,我使用类似于:
import nano from 'nano';
let db = nano(SERVICE_URL).use('blog_main');
let lastDocId = ctx.query.lastDocId;
let lastSkip = ctx.query.lastSkip ? +ctx.query.lastSkip + 5 : null;
let query = {
limit: 1 + 4, // limit to 5
descending: true, // reverse order: newest to top
include_docs: true,
}
if (lastDocId) { // initally off
query.startkey = lastDocId;
}
if (lastSkip) { // other method for tests
query.skip = lastSkip; // ----> this results in some previous and some new items
}
let itemRows = await db.view('filters','blog', query);
let items = itemRows.rows;
// each doc is in items[].doc
我已经看到
我不确定 "I get the same lines again" 的说法。如果 startkey
是先前结果的第一个而不是最后一个键,那么这是可重现的——这将是 第一个 问题。
无论如何,假设 startkey
是正确的参数 skip
和 startkey
是冲突的。最初 skip
应为 0,之后应为 1,以便在后续查询中跳过 startkey
。
CouchDB 分页文档1 中清楚地概述了此技术。
详情
假设 complete 视图(其中键是 unix 时间戳)是
{
"total_rows":7,
"offset":0,
"rows":[
{"id":"821985c5140ca583e108653fb6091ac8","key":1580050872331,"value":null},
{"id":"821985c5140ca583e108653fb6092c3b","key":1580050872332,"value":null},
{"id":"821985c5140ca583e108653fb6093f47","key":1580050872333,"value":null},
{"id":"821985c5140ca583e108653fb6094309","key":1580050872334,"value":null},
{"id":"821985c5140ca583e108653fb6094463","key":1580050872335,"value":null},
{"id":"821985c5140ca583e108653fb60945f4","key":1580050872336,"value":null},
{"id":"821985c5140ca583e108653fb60949f3","key":1580050872339,"value":null}
]
}
给定初始查询条件
{
limit: 5,
descending: true,
include_docs: false // for brevity
}
确实产生了预期的结果,5 行最近的排在第一位
{
"total_rows":7,
"offset":0,
"rows":[
{"id":"821985c5140ca583e108653fb60949f3","key":1580050872339,"value":null},
{"id":"821985c5140ca583e108653fb60945f4","key":1580050872336,"value":null},
{"id":"821985c5140ca583e108653fb6094463","key":1580050872335,"value":null},
{"id":"821985c5140ca583e108653fb6094309","key":1580050872334,"value":null},
{"id":"821985c5140ca583e108653fb6093f47","key":1580050872333,"value":null}
]
}
现在假设第二个查询是这样
{
limit: 5,
descending: true,
include_docs: false, // for brevity
startkey: 1580050872333,
skip: 5
}
startkey
(先前结果的最后一行的键)是正确的,但 skip
参数实际上是跳过了下一组(逻辑)行。特别是对于这些参数和上面的示例视图,查询将忽略剩余的键,从而导致空行集。
这是我们想要的:
{
limit: 5,
descending: true,
include_docs: false, // for brevity
startkey: 1580050872333,
skip: 1 // just skip the last doc (startkey)
}
1 CouchDB 分页食谱 3.2.5.5. Paging (Alternate Method)
使用 startkey 或 skip,返回的结果也包括一些跳过的结果,或者所有以前的结果(奇怪地混淆)。
我通过使用 - 第二部分扩展结果键解决了这个问题。 由于密钥基于没有时间的日期,因此由于相似的日期时间戳,它似乎重新排列了每个请求的条目。添加第二部分也是可排序的(使用创建的时间戳作为第二部分)修复它。 现在的关键是 [datetimestamp, createdtimestamp] .. 两者都可以降序排列。