Reputation: 10646
I have a view that returns all documents for a list of tags. The problem is that it returns documents grouped by tag.
keys=["tag1","tag2"]
function(doc){
if(doc.tags){
for(var i = 0; i < doc.tags.length; i++){
emit(doc.tags[i], doc);
}
}
}
returns
["rows"]=> array(2) { [0]=> object(stdClass)#6 (2) { ["key"]=> string(4) "tag1" ["value"]=> array(1) { here my list of documents for this tag...
How to you transform that into a list of documents with unique ids ?
Upvotes: 0
Views: 143
Reputation: 1765
If you want to perform a query along the lines of "select unique doc where doc.tags contains 'tag1' and 'tag2'", you could consider using CouchDB-Lucene. You could have an index along the lines of
function(doc) {
if(doc.tags){
var result = new Document();
for(var i = 0; i < doc.tags.length; i++){
result.add(doc.tags[i], {"field":"tag"});
}
return result;
}
}
you would likely want to have it use the "keyword" analyzer as well.
You could then query it using e.g.
http://localhost:5984/_fti/local/dbname/_design/foo/view_name?q=tag%3Atag1%20AND%20tag%3Atag2
I can't think of a way to do it with "vanilla" CouchDB unless you want to de-duplicate on the client or have very large indexes (i.e. have every tag combination indexed) which obviously won't scale well if you have lots of tags.
Upvotes: 0
Reputation: 842
Add startkey and endkey arguments to your view query.
For example to retrieve only documents with "tag1", use:
GET .../_view/your-view-name?startkey="tag1"&endkey="tag1"
Your view, behind the scenes, will create a "secondary index" (a B-tree actually). This means a list of all "emitted" rows, sorted by its key. This allows for very efficient lookups, and retrieval of subsets, of adjacent rows.
The trick is to create views that place the subsets your interested on, on adjacent rows.
See the example here:
Finding many; from CouchDB the definitive guide
Read this blog, about creating very smart indexes: CouchDB joins
Upvotes: 1