如果要在一个键中发出多个数据,您需要了解复杂键的知识。最可能的情况是使用emit()
发出一个由类别和标签组成的数组作为键。例如...
function(doc) {
for(var i = 0; i < doc.tags.length; i++)
emit([doc.category, doc.tags[i]], doc);
}
现在,当你查询?key=["fun", "couchdb"]
时,将会得到所有带有"couchdb"标签的"fun"类别的项。或者,如果你想要所有属于"fun"类别的项,无论它们是否带有标签,那么你可以查询一个范围:?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);
}
}
现在你的键结构为:
["category", "tag", 0 ... 2, rank/title/date]
。基本上,你将所有排名归为0,标题归为1,日期归为2。当然,你正在传输大量数据,因此你可以将这些分组中的每一个拆分成设计文档中的单独视图,或者仅返回文档的
_id
作为值 (
emit([ ...], doc._id);
)。
按升序获取“趣味”类别中具有“couchdb”标记的所有内容:
?startkey=["fun", "couchdb"]&endkey=["fun", "couchdb", {}, {}]
获取 "fun" 类别中带有 "couchdb" 标签的所有内容(按降序排列):
?startkey=["fun", "couchdb", {}, {}]&endkey=["fun", "couchdb"]&descending=true
获取只属于"couchdb"标签下的"fun"排名(升序):
?startkey=["fun", "couchdb", 0]&endkey=["fun", "couchdb", 0, {}]
获取只属于"couchdb"标签下的"fun"排名(降序):
?startkey=["fun", "couchdb", 0, {}]&endkey=["fun", "couchdb", 0]&descending=true
我希望这能有所帮助。复杂的键开始展现出Map/Reduce在切片和切块数据方面的强大。
谢谢。