Collated view with condition

Hello,

could anybody explain me how to add a condition to a collated view, like a where-clause in SQL which compares the contents of columns in different tables?

Example:

we have documents named "movies", every movies document contains a name and a movie ID, furthermore we have documents named "artists", every single artists document contains a movie ID and an artist name.

The collated view to show the movie names with the refering actor names could look like this:

function(doc) {
if (doc.type == "movies") {
emit([doc.movieid, 1], doc.moviename);
} else if (doc.type == "artists") {
emit([doc.movieid, 2], doc.artistname);
}
}

In a different case I want to emit only the batman movies:

function(doc) {
if (doc.type == "movies" && doc["moviename"].match("batman")) {
emit([doc.movieid, 1], doc.moviename);
} else if (doc.type == "artists") {
emit([doc.movieid, 2], doc.artistname);
}
}

The Problem I have know is that I don't know how to emit only the actor names for the batman movies and not for all movies. Could anybody help me?

-Phil

1 Answer

« Back to question.

There are multiple approaches to this which stem from denormalizing the dataset.

  1. Embed a list of actor IDs in the movie and have a way to reference back. This could look like this
    movie = { name: "Batman", year: 1989, actors: [1,2]}
    actorOne = { id: 1, name: "Jack Nicholson", born: 1937 }
    actorTwo = { id: 2, name: "Michael Keaton", born: 1951 }

    Now you can emit the actors directly from the movie document, and then perform a 2. query to load their details as needed. You can of course do this the other way around as well and include a list of movies in the actor data, depends on what makes more sense to you.

  2. Embed the whole actor in the movie since actors and movies are closely related it can be useful to always query them as one Document, and therefor embed all the information about the actor inside the JSON
    movie = { name: "Batman", 
                     year: 1989, 
                     actors: [{ name: "Jack Nicholson", born: 1937 }, 
                     { name: "Michael Keaton", born: 1951 }]
                   }

    This only makes sense for closely related information and can cause trouble if you need to update an actor or want to generate a list of movies an actor has been part of, but this could maybe achieved via a view.

Those would be the options which come to mind, otherwise you would have to know the ID of the batman movie to emit only actors with this id in them, which would be complicated since you would need to query the movie to get it's id and then generate a view from there to have it's ID ready. This would also take quite some time and you don't want to generate and extensive amount of views for every movie in this case.