14

I have a bunch of MP3 metadata in CouchDB. I want to return every album that is in the MP3 metadata, but no duplicates.

A typical document looks like this:

{
   "_id": "005e16a055ba78589695c583fbcdf7e26064df98",
   "_rev": "2-87aa12c52ee0a406084b09eca6116804",
   "name": "Fifty-Fifty Clown",
   "number": 15,
   "artist": "Cocteau Twins",
   "bitrate": 320,
   "album": "Stars and Topsoil: A Collection (1982-1990)",
   "path": "Cocteau Twins/Stars and Topsoil: A Collection (1982-1990)/15 - Fifty-Fifty Clown.mp3",
   "year": 0,
   "genre": "Shoegaze"
}
Octavian Helm
  • 39,405
  • 19
  • 98
  • 102
Blaine Lafreniere
  • 3,451
  • 6
  • 33
  • 55

2 Answers2

27

I believe your map/reduce would look something like:

function map(doc) {
    emit(doc.album, null);
}

function reduce(key, values) {
    return null;
}

Remember to query with the extra parameter group=true

JasonSmith
  • 72,674
  • 22
  • 123
  • 149
David Wolever
  • 148,955
  • 89
  • 346
  • 502
  • Could you please explain where the magic is in returning unique values? – Blaine Lafreniere Mar 28 '10 at 21:13
  • 7
    Sure. Remember that the `map` function accepts one document and calls `emit` on `(key, value)` pairs. Because we only care about the album - nothing else - we only emit that. Then, for each *distinct* key, CouchDB will call `reduce(key, values)` and use that as the result of your query (again, we simply return `null` from `reduce` because we don't care about the value). – David Wolever Mar 28 '10 at 22:33
  • 1
    I think you'll also want to run this query with group=true – mikeal Mar 29 '10 at 16:22
  • Excellent. Worked beautifully. Thanks for the explanation, David. – Blaine Lafreniere Mar 30 '10 at 02:09
  • How would you instead return one object that contains one property that is a distinct sorted array of albums? I want this because it is less verbose (not containing so many null values). – Lonnie Best May 23 '16 at 19:03
11

Have a look at View Cookbook for SQL Jockeys' Get Unique Values section.

Octavian Helm
  • 39,405
  • 19
  • 98
  • 102
Adriaan Stander
  • 162,879
  • 31
  • 289
  • 284