我有一个小型CouchDB表,其中包含以下文档结构:
{
"_id": "22e5cfffa3d363bb1dd3f2293e002953",
"idRubric": "9bf94452c27908f241ab559d2a0d46c5",
"category": "open",
"yada yada" : "for the rest of the fields"
}
类别和(当前)有4种可能的idRubric值。我正在尝试创建一个视图,它允许我只选择idRubric和category同时匹配给定值的那些文档。我当前的地图功能如下所示:
{
"_id": "_design/views",
"_rev": "40-97b9c83b8016e4f71738bb64cbe6c754",
"views": {
"byRubricCategory": {
"map": "function (doc) { if (doc.idRubric && doc.category) {emit(doc.idRubric, doc.category); } }"
}
}
}
这是一个数组,显示所有匹配ieRubric的文档。如果我将idRubric替换为类别,那么我将获得与该类别匹配的所有文档。我试图将结果指定为[doc.idRubric, doc.category]
,但是只返回一个空集。
根据建议,我已更新视图文档以输出数组:
{
"_id": "_design/views",
"views": {
"byRubricCategory": {
"map": "function (doc) { if (doc.idRubric && doc.category) {emit([doc.idRubric, doc.category], null); } }"
}
}
}
将emit更改为数组的结果是我现在得到一个空集:
{
"total_rows": 16,
"offset": 0,
"rows": [
]
}
我没有使用reduce函数,因为(我的理解有限)map的目标似乎是将set减少为单个值,我不想要,我需要的结果集将在最小,有4个文件,可能有20-30。
我已经完成了关于CouchDB和这个主题的20个或主题,但所有似乎都引用了多个关键查询,其中焦点是key1或key2。我正在尝试使用逻辑AND而不是逻辑OR。谢谢。
未指定密钥时的代表值:
{
"total_rows": 16,
"offset": 0,
"rows": [
{
"id": "22e5cfffa3d363bb1dd3f2293e00380a",
"key": [
"9bf94452c27908f241ab559d2a0d46c5",
"close"
],
"value": null
},
{
"id": "22e5cfffa3d363bb1dd3f2293e0045a7",
"key": [
"9bf94452c27908f241ab559d2a0d46c5",
"content"
],
"value": null
},
{
"id": "22e5cfffa3d363bb1dd3f2293e002953",
"key": [
"9bf94452c27908f241ab559d2a0d46c5",
"open"
],
"value": null
},
{
"id": "22e5cfffa3d363bb1dd3f2293e0088a4",
"key": [
"9bf94452c27908f241ab559d2a0d50d6",
"rising"
],
"value": null
}
]
}
答案 0 :(得分:3)
实现这一目标的最简单方法是使用这样的地图函数:
function (doc) {
if (doc.idRubric && doc.category) {
emit([doc.idRubric, doc.category], null);
}
}
然后,您必须使用startkey和endkey查找文档。
startkey = ["a", "b"]
endkey = ["a", "b", {}]
请记住,键应该是json字符串。 " {}"在endkey中意味着任何其他对象。它将匹配任何idRubric等于" a"和类别等于" b"。
另请注意,我不会随着密钥一起发出文档。如果您确实想要获取文档,除非您将发出的值传递给地图缩小,否则没有真正的理由发出文档。问题是您可以使用分配给发射值的文档来获取视图。所以你不必真正发出价值。这也会使视图变小。想象一下,你有一些文档内容有10mb的文档。如果你发出整个文档100次,你的文档实际上会浪费10mb x 100次= 1000mb的内存。
此外,您可能希望添加"类型"而不是idRubric和类别测试。到您的文档,使其更明确您的对象是什么。
你也可以使用它:
而不是使用" key"。当你有一组发射多个东西时很好。同样由于某种原因,您发出值的顺序也很重要。它将改变结果集的顺序。
我的方法优于"键"是你可以取这样的东西:
key: ["apple","orange"]
key: ["apple","orange"]
key: ["apple","orange","cherry"]
key: ["apple","lemon"]
使用"key" = ["apple","cherry"]
的查询将返回前2个键。使用startkey=["apple","orange"]
和带有["apple","orange",{}]
的结束键的查询将返回前3个文档,因为所有这些文档都以apple和orange开头。考虑到这一点,如果您的startkey
和endkey
相同,则会像" key
"。它只是指定两个键允许您编写更复杂的键范围。
还有一件事,如果您想要获取文档,请将"include_docs=true"
添加到您的网址。
答案 1 :(得分:1)
好吧!答案是key=
而非keys=
我一直在浏览器中测试这个:
http://localhost:5984/rubric_content/_design/views/_view/byRubricCategory?keys=[%229bf94452c27908f241ab559d2a0d46c5%22,%22content%22]
错误是关键规范。将此更正为:
http://localhost:5984/rubric_content/_design/views/_view/byRubricCategory?key=[%229bf94452c27908f241ab559d2a0d46c5%22,%22content%22]
解决了这个问题。谢谢大家的帮助和耐心。
答案 2 :(得分:0)
emit
ting [doc.idRubric, doc.category]
因为您的密钥 是正确的方法。使用该复合键和您的查看文档,您应该可以执行以下操作:curl host:5984/dbname/_design/views/_view/byRubricCategory?key=%5B%229bf94452c27908f241ab559d2a0d46c5%22,%22open%22%5D
- 请注意[
,"
和]
都是CGI转义。