CouchDB在同一视图中进行排序和过滤

Apr*_*che 33 sorting couchdb filter nosql

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

{
    "title": "My Document",
    "date": 1279816057,
    "ranking": 5,
    "category": "fun",
    "tags": [
        "couchdb",
        "technology"
    ],
}
Run Code Online (Sandbox Code Playgroud)

从文档中,我了解到我可以轻松地创建一个按排名等字段排序的视图.

function(doc) {
    emit(doc.ranking, doc);
}
Run Code Online (Sandbox Code Playgroud)

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

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

http://127.0.0.1:5984/database/_design/filter/_view/filter?key=%22fun%22
Run Code Online (Sandbox Code Playgroud)

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

如何创建一个可以完成所有排序和过滤的视图?

Sam*_*bee 49

要在密钥中发送多个数据,您需要阅读复杂密钥.你最有可能最终emit()得到一个由类别和标签组成的数组.例如...

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

现在,当您查询时,?key=["fun", "couchdb"]您将获得标记为"couchdb"的有趣类别中的所有项目.或者,如果您想要有趣类别中的所有项目,无论其标记如何,那么您可以使用以下范围进行查询:?startkey=["fun"]&endkey=["fun", {}].请记住,如果您的商品有多个标签,您将在结果中多次获取(因为您emit()每个标签都需要一次文档).

要按照评级,日期和标题进行排序,您需要在数组中添加两个元素:整数以及排名,日期或标题.请记住,emit()每个地图功能可以多次使用.示例地图功能......

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

?startkey=["fun", "couchdb"]&endkey=["fun", "couchdb", {}, {}]
Run Code Online (Sandbox Code Playgroud)

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

?startkey=["fun", "couchdb", {}, {}]&endkey=["fun", "couchdb"]&descending=true
Run Code Online (Sandbox Code Playgroud)

使用couchdb标记(升序)获取有趣类别中的排名:

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

仅使用"couchdb"标记(降序)获取"fun"类别中的排名:

?startkey=["fun", "couchdb", 0, {}]&endkey=["fun", "couchdb", 0]&descending=true
Run Code Online (Sandbox Code Playgroud)

我希望这有帮助.复杂的键开始真正展示Map/Reduce在切片和切割数据时的强大功能.

干杯.