CouchDB 排序和过滤在同一个视图中 [英] CouchDB sorting and filtering in the same view

查看:13
本文介绍了CouchDB 排序和过滤在同一个视图中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将 CouchDB 用于新应用程序,我需要创建一个按多个字段排序并按多个字段过滤的视图.这是一个示例文档,我省略了 _id 和 _rev 以节省自己的打字时间.

I'm trying to use CouchDB for a new app, and I need to create a view that sorts by multiple fields and also filters by multiple fields. Here is an example document, I've left out the _id and _rev to save myself some typing.

{
    "title": "My Document",
    "date": 1279816057,
    "ranking": 5,
    "category": "fun",
    "tags": [
        "couchdb",
        "technology"
    ],
}

从文档中,我了解到我可以轻松创建按字段(例如排名)排序的视图.

From the documentation, I've learned that I can easily create a view that sorts by a field such as ranking.

function(doc) {
    emit(doc.ranking, doc);
}

我还了解到我可以轻松地按类别等字段进行过滤

I've also learned that I can easily filter by fields such as category

function(doc) {
    emit(doc.category, doc);
}

http://127.0.0.1:5984/database/_design/filter/_view/filter?key=%22fun%22

我的问题是我需要同时做很多这些事情.我想根据类别和标签进行过滤.我应该能够过滤到只有fun"类别和couchdb"标签的文档.我想通过按降序排列,然后按日期按升序排列,然后按标题按字母顺序排列这些过滤结果.

My problem is that I need to do a bunch of these things all at the same time. I want to filter based on category and also tag. I should be able to filter down to only documents with category of "fun" and tag of "couchdb". I want to sort those filtered results by ranking in descending order, then by date in ascending order, then by title in alphabetical order.

如何创建一个视图来组合所有排序和过滤?

How can I create one view that does all of that sorting and filtering combined?

推荐答案

要在一个键中发出多个数据,您需要阅读 复杂键.您很可能会以 emit() 结尾,该键是由类别和标签组成的数组.比如……

For emitting more than one piece of data in a key, you'll want to read up on Complex Keys. You'll most likely end up emit()'ing a key that is an array made up of the category and tag. For example...

function(doc) {
  for(var i = 0; i < doc.tags.length; i++)
    emit([doc.category, doc.tags[i]], doc);
}

现在,当您查询 ?key=["fun", "couchdb"] 时,您将获得 fun 类别中标有couchdb"的所有项目.或者,如果您想要 fun 类别中的所有项目,而不考虑它们的标签,那么您可以使用范围进行查询:?startkey=["fun"]&endkey=["fun", {}].请记住,如果您的项目有多个标签,您将在结果中多次获得它(因为您 emit() 为每个标签添加了一次文档).

Now when you query ?key=["fun", "couchdb"] you'll get all the items in the fun category tagged with "couchdb". Or if you want all of the items in the fun category, regardless of their tag, then you can query with a range: ?startkey=["fun"]&endkey=["fun", {}]. Just remember, if your item has multiple tags, you'll get it multiple times in the results (because you emit()'d the doc once per tag).

要执行按评分、日期和标题排序的额外步骤,您需要在数组中再添加两个元素:一个整数以及排名、日期或标题.请记住,您可以在每个地图函数中多次emit().一个示例地图函数...

To go the extra step of sorting by rating, date, and title you'll add two more elements to your array: an integer and either the ranking, date, or title. Remember, you can emit() more than once per map function. An example map function...

function(doc) {
  for(var i = 0; i < doc.tags.length; i++)
  {
     emit([doc.category, doc.tags[i], 0, doc.ranking], doc);
     emit([doc.category, doc.tags[i], 1, doc.title], doc);
     emit([doc.category, doc.tags[i], 2, doc.date], doc);
  }
}

现在你的关键结构是:["category", "tag", 0 ... 2, rank/title/date]

您基本上是将所有排名低于 0,标题低于 1,日期低于 2.当然,您要传输大量数据,因此您可以将这些分组中的每一个分成单独的视图在您的设计文档中,或者只返回文档的 _id 作为值 (emit([ ...], doc._id);).

You're basically grouping all of the rankings under 0, titles under 1, and dates under 2. Of course, you're transmitting a lot of data, so you could either break each of these groupings out into a separate view in your design document, or only return the doc's _id as the value (emit([ ...], doc._id);).

使用couchdb"标签(升序)获取有趣"类别中的所有内容:

Get everything in the "fun" category with the "couchdb" tag (ascending):

?startkey=["fun", "couchdb"]&endkey=["fun", "couchdb", {}, {}]

使用couchdb"标签(降序)获取有趣"类别中的所有内容:

Get everything in the "fun" category with the "couchdb" tag (descending):

?startkey=["fun", "couchdb", {}, {}]&endkey=["fun", "couchdb"]&descending=true

使用 couchdb 标签(升序)仅获取趣味类别中的排名:

Get only rankings in the fun category with the couchdb tag (ascending):

?startkey=["fun", "couchdb", 0]&endkey=["fun", "couchdb", 0, {}]

仅使用couchdb"标签(降序)获取有趣"类别中的排名:

Get only rankings in the "fun" category with the "couchdb" tag (descending):

?startkey=["fun", "couchdb", 0, {}]&endkey=["fun", "couchdb", 0]&descending=true

我希望这会有所帮助.复杂的键开始真正显示 Map/Reduce 在切片和切块数据方面的强大功能.

I hope this helps. Complex keys start to really show how powerful Map/Reduce is at slicing and dicing data.

干杯.

这篇关于CouchDB 排序和过滤在同一个视图中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆