1

我正在尝试编写一个视图,显示系统中使用的前 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

最重要的是,我不想将全套传输到我的应用程序服务器并在那里处理它。

4

2 回答 2

2

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

  1. 查询返回键值对的视图:tag_name - count_valueorder bytag_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);
    }
  }
}

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

于 2013-04-12T13:24:46.807 回答
0

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

在 couchdb 中,我会使用列表函数,并使用 JavaScript sort() 对结果进行排序。这样它就在服务器端进行了排序,你可以让列表只返回前 10 个。

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

于 2013-04-12T04:33:08.577 回答