Sorting 按值排序CouchDB视图

Sorting 按值排序CouchDB视图,sorting,couchdb,Sorting,Couchdb,我正在测试CouchDB,看看它如何处理记录一些搜索结果。我想做的是生成一个视图,在这个视图中,我可以根据结果生成顶部查询。目前我有这样的想法: 示例文档部分 { "query": "+dangerous +dogs", "hits": "123" } function (key, values, rereduce) { return sum(values); } 地图功能 (不完全是我需要/想要的,但足以进行测试) 减少功能 { "query": "+dangerous +

我正在测试CouchDB,看看它如何处理记录一些搜索结果。我想做的是生成一个视图,在这个视图中,我可以根据结果生成顶部查询。目前我有这样的想法:

示例文档部分

{
  "query": "+dangerous +dogs",
  "hits": "123"
}
function (key, values, rereduce) {
  return sum(values);
}
地图功能 (不完全是我需要/想要的,但足以进行测试)

减少功能

{
  "query": "+dangerous +dogs",
  "hits": "123"
}
function (key, values, rereduce) {
  return sum(values);
}
现在,这将得到一种格式的结果,其中查询项是键,右边是该项的计数,这很好。但我希望按值排序,而不是按键。从它的声音,这是不可能与CouchDB


那么,有没有人知道如何获得一个视图,其中我有一个有序版本的查询术语及其相关计数?我是CouchDB的新手,我想不起如何编写所需的函数。

我不确定返回结果中的1,但我肯定这应该可以做到:

emit([doc.hits,split[i]],1)

在文档中定义了。这在CouchDB用户邮件列表上,主要开发人员之一Chris Anderson写道:

这是一个常见的请求,但CouchDB的 视图——为此,您需要将组reduce查询复制到 另一个数据库,并构建一个按值排序的视图

这是我们为了支持动态范围查询和 增量索引

我最近也需要做这件事,最后我在我的应用层做了这件事。这在JavaScript中很容易做到:

db.view('mydesigndoc', 'myview', {'group':true}, function(err, data) {

    if (err) throw new Error(JSON.stringify(err));

    data.rows.sort(function(a, b) {
        return a.value - b.value;
    });

    data.rows.reverse(); // optional, depending on your needs

    // do something with the data…
});
此示例在中运行并使用,但它可以轻松地适应在浏览器或其他JavaScript环境中运行。当然,这个概念可以移植到任何编程语言/环境中


确实没有绝对简单的答案。然而,有几种模式

  • 。我个人不喜欢这样,因为他们承认这是一个脆弱的解决方案,代码看起来并不轻松

  • Avi的答案是,在应用程序的内存中进行排序

  • 似乎每个人最终都发现自己需要它

  • 我喜欢的是克里斯在阿维的引用中所说的话。放松。在CouchDB中,数据库是轻量级的,能够为您提供数据的独特视角。这些天来,热门话题都是关于过滤复制的,过滤复制就是将数据的子集切分出来放到一个单独的数据库中

    不管怎样,基础很简单。您从视图输出中获取
    .rows
    ,然后将其插入单独的数据库中,该数据库只需发出键入计数的命令。另一个技巧是编写一个非常简单的
    \u list
    函数。列出将原始沙发输出“渲染”为不同格式。您的
    \u列表
    函数应该输出

    { "docs":
        [ {..view row1...},
          {..view row2...},
          {..etc...}
        ]
    }
    
    这样做的目的是按照
    \u bulk\u docs
    API的要求对视图输出进行格式化。现在,您可以将卷曲管直接插入另一个卷曲:

    curl host:5984/db/_design/myapp/_list/bulkdocs_formatter/query_popularity \
     | curl -X POST host:5984/popularity_sorter/_design/myapp/_view/by_count
    
  • 事实上,如果您的列表函数可以处理所有文档,您可以让它自己对它们进行排序,然后将它们返回给排序后的客户端


  • 根据Avi的回答,我提出了这个Couchdb列表函数,它满足了我的需要,它只是一个最流行事件的报告(key=event name,value=attenders)

    ddoc.lists.eventPopularity=函数(请求、恢复){ 开始({标题:{“内容类型”:“文本/普通”}}); var数据=[] while(row=getRow()){ 数据推送(row); } 数据排序(函数(a,b){ 返回a.value-b.value; }).reverse(); 对于(数据中的i){ 发送(数据[i].value+':'+data[i].key+“\n”); } } 以下是相应的视图函数供参考:

    ddoc.views.eventPopularity = { map : function(doc) { if(doc.type == 'user') { for(i in doc.events) { emit(doc.events[i].event_name, 1); } } }, reduce : '_count' } ddoc.views.eventPopularity={ 地图:功能(doc){ 如果(doc.type==“用户”){ 对于(文档事件中的i){ 发出(doc.events[i].事件名称,1); } } }, 减少:“\u计数” } 以及列表函数的输出(已剪切):

    165:设计驱动的创新:设计师如何促进对话 165:你的客户是人群还是社区? 164:社交媒体神话破坏者 163:不要害怕创造力!任何事情都有可能发生 159:机构需要像软件公司一样思考吗? 158:客户体验:未来趋势和见解 156:意外作家:对每个人来说都是很棒的网络拷贝 155:为什么一切都令人惊奇,但没有人快乐
    我认为上面的每个解决方案都会破坏couchdb的性能。我对这个数据库很陌生。据我所知,couchdb视图在被查询之前准备结果。似乎我们需要手动准备结果。例如,每个搜索词将驻留在具有命中计数的数据库中。当有人搜索时,它的搜索词将被查找并增加命中率。当我们想看到搜索词的流行程度时,它会发出(命中率,搜索词)对

    检索\u顶部\u N \u标记的链接似乎已断开,但我找到了另一种解决方案

    引用编写该解决方案的开发人员的话:

    与在映射步骤中返回由标记键入的结果不同,我将发射每个标记的每个匹配项。然后在reduce步骤中,我将使用散列计算按标记分组的聚合值,将其转换为数组,对其进行排序,然后选择前3个

    如评论中所述,唯一的问题是长尾的情况:

    问题是你必须小心你获得的标签数量;如果结果大于500字节,您将有couchdb抱怨它,因为“reduce必须有效地reduce”。不过,3个、6个甚至20个标签都不成问题


    这对我来说非常有效,请查看链接以查看代码

    这是一个老问题,但我觉得它仍然值得一个体面的回答(我花了至少20分钟寻找正确的答案…)

    我不同意这里答案中的其他建议,认为它们不令人满意。尤其是我不喜欢它 165: Design-Driven Innovation: How Designers Facilitate the Dialog 165: Are Your Customers a Crowd or a Community? 164: Social Media Mythbusters 163: Don't Be Afraid Of Creativity! Anything Can Happen 159: Do Agencies Need to Think Like Software Companies? 158: Customer Experience: Future Trends & Insights 156: The Accidental Writer: Great Web Copy for Everyone 155: Why Everything is Amazing But Nobody is Happy
    emit([doc.address.country,doc.address.state, doc.address.city], doc);
    
    startkey=["US"]&endkey=["US",{}] 
    
    startkey=["US",{}]&endkey=["US"]