在couchdb中选择前10个或最新的10个?

12

如何在CouchDB中执行等同于 "select top 10" 的查询?

例如,我有一个这样的 "schema":

title   body   modified

我想选择最近修改的10个文档。

如果有人能想出一种针对每个类别执行相同操作的方法,那就更好了。例如:

title   category   body   modified

返回每个类别的最新10个文档列表。

我只是想知道在couchdb中是否可能进行这样的查询。


你不想手动操作的原因是什么?首先查询可用类别,然后按类别查询列表。将第二个查询批处理,就像一个查询一样。 - b_erb
我可以做到,但我的问题是在couchdb中是否有可能用一条查询语句实现这样的操作。例如,在SQL中可以使用一个非常复杂的嵌套选择语句来完成这个操作。 - Andriy Drozdyuk
3个回答

7
为了从您的数据库中获取前10个文档,您可以使用限制查询选项。例如,调用:
http://localhost:5984/yourdb/_design/design_doc/_view/view_name?limit=10

您可以获取前10个文档。

查看行会按键排序; 在查询字符串中添加descending=true将颠倒它们的顺序。您还可以使用查询字符串仅发出您感兴趣的文档,以选择您感兴趣的键。 因此,在视图中,您可以像这样编写映射函数:

function(doc) {
    emit([doc.category, doc.modified], doc);
}

并且您可以像这样查询它:

http://localhost:5984/yourdb/_design/design_doc/_view/view_name?startkey=["youcategory"]&endkey=["youcategory", date_in_the_future]&limit=10&descending=true

那个第二个查询语句会选择每个类别中的最新的10个条目吗?还是只选择一个类别中的最新的10个条目? - Andriy Drozdyuk
抱歉,我误读了你的问题。它从一个类别中选择最新的10个项目。 - filippo

3

以下是您需要做的事情。

映射函数

function(doc)
{
  if (doc.category)
  {
    emit(['category', doc.category], doc.modified);
  }
}

那么您需要一个列表函数来对它们进行分组,您可能会尝试滥用 reduce 函数来完成此操作,但是在处理大量数据时,这可能会导致错误。

function(head, req)
{
  % this sort function assumes that modifed is a number
  % and it sorts in descending order
  function sortCategory(a,b) { b.value - a.value; }
  var categories = {};
  var category;
  var id;
  var row;
  while (row = getRow())
  {
    if (!categories[row.key[0]])
    {
      categories[row.key[0]] = [];
    }
    categories[row.key[0]].push(row);
  }
  for (var cat in categories)
  {
    categories[cat].sort(sortCategory);
    categories[cat] = categories[cat].slice(0,10);
  }
  send(toJSON(categories));  
}

现在您可以使用以下方法获取所有类别的前10名:
http://localhost:5984/database/_design/doc/_list/top_ten/by_categories

使用以下方式获取文档:

http://localhost:5984/database/_design/doc/_list/top_ten/by_categories?include_docs=true

现在您可以使用多范围POST查询并限制类别。

curl -X POST http://localhost:5984/database/_design/doc/_list/top_ten/by_categories -d '{"keys":[["category1"],["category2",["category3"]]}'

你也可以不硬编码 10,而是通过 req 变量传递数字。

这里还有一些更多的视图/列表技巧


我没有测试这个答案,但是我还是会接受它,因为我不再使用couchdb。 - Andriy Drozdyuk

0

稍作更正,直到我在你的sortCategory函数中添加了"return"关键字后才进行排序。应该是像这样:

function sortCategory(a,b) { return b.value - a.value; }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接