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);
}
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).
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);
}
}
Now your key structure is: ["category", "tag", 0 ... 2, rank/title/date]
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);
).
Get everything in the "fun" category with the "couchdb" tag (ascending):
?startkey=["fun", "couchdb"]&endkey=["fun", "couchdb", {}, {}]
Get everything in the "fun" category with the "couchdb" tag (descending):
?startkey=["fun", "couchdb", {}, {}]&endkey=["fun", "couchdb"]&descending=true
Get only rankings in the fun category with the couchdb tag (ascending):
?startkey=["fun", "couchdb", 0]&endkey=["fun", "couchdb", 0, {}]
Get only rankings in the "fun" category with the "couchdb" tag (descending):
?startkey=["fun", "couchdb", 0, {}]&endkey=["fun", "couchdb", 0]&descending=true
I hope this helps. Complex keys start to really show how powerful Map/Reduce is at slicing and dicing data.
Cheers.