CouchDB / Couchbase视图按键数排序

时间:2013-04-11 21:15:21

标签: javascript mapreduce couchdb couchbase

我正在尝试编写一个视图,向我展示系统中使用的前10个标签。在reduce函数中使用_count获取金额相当容易,但这并不是按数字排序列表。有没有办法做到这一点?

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

结果我想:

  • Tag3 10
  • Tag1 7
  • Tag2 3
  • ...

而不是

  • Tag1 7
  • Tag2 3
  • Tag3 10

最重要的是,我不想将完整集转移到我的应用服务器并在那里处理它。

2 个答案:

答案 0 :(得分:2)

在couchbase中,你无法在reduce之后对结果进行排序,因此你不能直接获得某些东西的“前十名”。在couchbase视图中,值始终按键排序。最好的方法是:

  1. 查询返回键值对的视图:tag_name - count_value
  2. 排序的tag_name
  3. 创建每N分钟运行一次的作业,从[1]中获取结果,对它们进行排序,并将排序后的结果写入单独的键(即“Top10Tags”)。
  4. 在您的应用中,您可以查询关键字Top10Tags。
  5. 这可能会减少流量,但结果可能会过时。此外,您可以在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存储桶中。

答案 1 :(得分:0)

你认为很容易但不是真的。

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

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