出于某些原因,我需要在我的 couchdb 中获取每 50 个文档。
例如,我的数据库中有 500 个用户,我想获取第一个、第 51 个、第 101 个......第 451 个用户。
如何通过map/reduce功能获得此结果?
(我知道我可以在 url 中设置"skip"参数来执行类似的行为,但我想通过 map/reduce 来做到这一点(
谢谢!
问题
要记住的关键是 CouchDB map/reduce 更像CREATE INDEX...
,它不像SELECT * FROM...
映射/归约创建静态行列表。行可以按您想要的任何顺序排列(按您发出的键排序(,但一个文档不可能更改另一个文档的结果。
为了说明这一点,假设您有一个包含此类行的假设视图。键是他们在列表中的"位置",值是用户名
// View rows (conceptual diagram only)
// Key, Value
0 , "mark" // Suppose Alice was created first, 1 week ago
1 , "bob" // and Bob was created 1 day ago
2 , "evan" // and Evan was created 1 hour ago... so this view is chronological
... // etc.
现在您意识到 Bob 的文档有错误。他实际上是在一年前注册的,而不是一天前。你更新他的时间戳。视图现在应该是什么样子?
// View rows (conceptual diagram only)
// Key, Value
0 , "bob" // The corrected Bob document was created 1 **year** ago
1 , "mark" // ...and now Mark scoots down to the next position (!!!)
2 , "evan" // ...and Evan stayed the same
... // etc.
问题是:在 CouchDB 中,如果你只更改 Bob 的文档,就不可能影响 Mark 的行。这是基本结构。上面的(!!!)
标签表示不可能的功能。问题在于我们最初的假设:我们可以有一个视图来指示行彼此之间的绝对位置。(注意,"相对"一词与">关系数据库">中的词根相同(
所以这样的技术是不可能的,通过归纳和荒谬。
溶液
你可以用map/reduce做你需要的大部分事情。使用时间戳作为键,而不是假设位置作为键。
// View rows (conceptual diagram only)
// Key, Value
2011-05-06, "bob" // Bob signed up one year ago
2012-05-05, "mark" // Mark signed up one day ago
2012-05-06, "evan" // Evan one hour ago
... // etc.
当然,时间戳格式只是为了做一个清晰的例子。您可能应该使用 ISO 8601 格式(即您从 JavaScript 中的JSON.stringify(new Date)
中获取的内容(。
最新的优先注册,请对视图进行降序查询;若要仅获取一行,请使用"limit
"选项。
- 要获取最新注册:
?descending=true&limit=1
- 要获得第 50 个最新:
?descending=true&limit=1&skip=50
- 要获得第 100 个最新:
?descending=true&limit=1&skip=100