I\'ve been trying to find a solution for this requirement but I\'ve hit many dead ends.
I\'m using Cloudant as my data store of user documents. Each
Cloudant's search works at the granularity of returning a document. Your indexing function could index the categories in use across the item
s in the document and then your search would return the documents containing item
s with the category you mention. Your application code would then need to filter down to the item
s to return to the client.
Your index function would be something like (shamelessly cribbing from Wintamute):
if (!doc.items || doc.items.length === 0) return;
var item;
for (var i=0; i<doc.items.length; i++) {
index("cat", doc.items[i].cat, {"index": "not_analyzed"});
}
The alternative is to break out the items into their own documents if you really want to be able to get just the items.
However, I'd second (and have up-voted) Wintamute's answer as I agree that the suggested view is the best solution in this specific case (find and display items by cat
).
This actually can be done with Cloudant search. I had a similar issue that I needed to solve. Special thanks to Mike Bresslin at Cloudant for his help.
function(doc){
if (doc.items) {
for (var n in doc.items) {
if (doc.items[n].cat) {
index("cat", doc.items[n].cat, { store : true });
}
}
}
}
You can query it in a search as:
?q=cat:hardwork OR cat:determination
In CouchDB you can't pass in a dynamic value for a query parameter to a view (in your case cat=determination). The approach in CouchDB is to create a more general view, and then adjust how the result is sorted when you call the view to get at the data you need.
You'll need to create custom view in your db's design document to achieve this:
byUserItemCat: {
map: function (doc) {
if ( !doc.items || doc.items.length === 0 ) return;
for ( var i=0; i<doc.items.length; i++ ) {
emit(doc.items[i].cat,{doc._id,doc.items[i].date,doc.items[i].text});
}
}
}
So the above view takes each doc in the db, checks it has an items array with contents, and then loops over all the doc's items. For each item element it finds it emits cat
into the result set as the index, this is important since we can then sort against against this index. We're free to build the result object in anyway we like (second argument to emit
), and in the above case I'm building an object with the user id, and the item's date and text.
You'd call the view something like this, to get all the results:
curl -X GET http://127.0.0.1:5984/<db-name>/_design/<design-doc-name>/_view/byUserItemCat
And if you were just interested in the results where the index key (i.e. cat
) was "determination" you'd do:
curl -X GET http://127.0.0.1:5984/<db-name>/_design/<design-doc-name>/_view/byUserItemCat?key="determination"