【问题标题】:CouchDB / Couchbase view ordered by number of keysCouchDB / Couchbase 视图按键数排序
【发布时间】:2013-04-04 06:01:02
【问题描述】:

我正在尝试编写一个视图来显示我系统中使用的前 10 个标签。在 reduce 函数中使用 _count 获取数量相当容易,但这不会按数字对列表进行排序。有没有办法做到这一点?

function(doc, meta) {
  if(doc.type === 'log') {
    emit(doc.tag, 1);
  }
}
_count

因此我想要:

  • 标签3 10
  • 标签1 7
  • 标签2 3
  • ...

代替

  • 标签1 7
  • 标签2 3
  • 标签3 10

最重要的是,我不想将整个集合传输到我的应用程序服务器并在那里进行处理。

【问题讨论】:

标签: javascript mapreduce couchdb couchbase


【解决方案1】:

您认为很容易但实际上并非如此的事情。

在 couchdb 中,我会使用列表函数,并使用 JavaScript sort() 对结果进行排序。这样一来,所有内容都在服务器端进行排序,您可以让列表只返回前 10 个。

请记住,对于大型数据集,这会很慢。

【讨论】:

  • 嗯,将设备转移到服务器对我来说不是一个选项。我经常需要数据,但对于一个过于简单的问题,它会导致过多的网络流量。
【解决方案2】:

在 couchbase 中,您无法在 reduce 中/之后对结果进行排序,因此您无法直接获得“前 10 名”。在 couchbase 视图中,值总是按键排序。最好的办法是:

  1. 查询返回键值对的视图:tag_name - count_valuetag_name 排序
  2. 创建每 N 分钟运行一次的作业,从 [1] 获取结果,对其进行排序,并将排序后的结果写入单独的键(即“Top10Tags”)。
  3. 在您的应用中查询关键 Top10Tags。

这可能会减少流量,但结果可能会过时。您还可以在 couchbase 运行的同一台服务器上创建该“作业”(即编写小型 node.js 应用程序或其他东西),并且它只需要环回流量和少量 cpu 用于每 N 分钟排序一次。

另外,如果您使用 _count reduce 函数,则不需要发出任何数字,只需使用 null:

function(doc, meta) {
  if(meta.type === "json" && doc.type === 'log') {
    emit(doc.tag, null);
  }
}

如果你想让文档被多个标签标记,比如

{
  "type": "log",
  "tags": ["tag1","tag2","tag3"]
}

您的地图功能应该是:

function(doc, meta) {
  if(meta.type === "json" && doc.type === 'log') {
    for(var i = 0; i < doc.tags.length; i++){
      emit(doc.tags[i], null);
    }
  }
}

关于前 10 名名单的另一件事。如果您不想存储在磁盘上,可以将其存储在 memcache 存储桶中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-13
    • 1970-01-01
    • 2015-12-23
    • 2011-12-26
    • 2012-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多