To display a list of all breweries, a view will be necessary. This map function for this view will simply emit null keys and values for each of the brewery documents in the database. This view will live in a “breweries” design document and be named “all.”
For more information on working with views in the admin console, see the documentation.
function(doc, meta) { if (doc.type == "brewery") { emit(null, null); } }
A null-key index still provides access to each of the document's keys when the view is queried. Note however that range queries on keys would not be supported with this view.
You could create the “all” view above by creating a new design
document in the Couchbase web console or you could use the
CouchbaseCluster API
(see
docs) found in Couchbase.dll to create and to save a
design document. However, an easier approach is to use the
CouchbaseLabs
project Couchbase Model Views.
The Couchbase Model Views project is not part of the Client Library, but makes use of its design doc management API to create views from attributes placed on model classes. Using NuGet, add a reference to the CouchbaseModelViews package.
Once installed, modify the Brewery class definition to have two
class level attributes, CouchbaseDesignDoc and
CouchbaseAllView.
[CouchbaseDesignDoc("breweries")] [CouchbaseAllView] public class Brewery : ModelBase { //props omitted for brevity }
The CouchbaseDesignDoc attribute instructs the
Model Views framework to create a design document with the given
name. The CouchbaseAllView will create the
“all” view as shown previously.
To get the Model Views framework to create the design doc and
view, you'll need to register the assembly containing the models
with the framework. In Global.asax, create a static
RegisterModelViews method for this purpose.
public static void RegisterModelViews(IEnumerable<Assembly> assemblies) { var builder = new ViewBuilder(); builder.AddAssemblies(assemblies.ToList()); var designDocs = builder.Build(); var ddManager = new DesignDocManager(); ddManager.Create(designDocs); }
Then in the existing Application_Start method,
add a line to register the current assembly.
RegisterModelViews(new Assembly[] { Assembly.GetExecutingAssembly() });Note that the Model Views framework will create the design doc only if it has changed, so you don't have to worry about your indexes being recreated each time your app starts.
To test that the Model Views framework is working, simply run the application (Ctrl + F5). If all went well, you should be able to navigate to the “Views” tab in the Couchbase web console and see the new design doc and view in the “Production Views” tab (as shown below).
If you click the link next to the “Filter Results” button, you
will see the JSON that is returned to the
CouchbaseClient when querying a view. Notice
the “id” property found in each row. That is the key that was
used to store the document.
{"total_rows":1412,"rows":[ {"id":"21st_amendment_brewery_cafe","key":null,"value":null}, {"id":"357","key":null,"value":null}, {"id":"3_fonteinen_brouwerij_ambachtelijke_geuzestekerij","key":null,"value":null}, {"id":"512_brewing_company","key":null,"value":null}, {"id":"aass_brewery","key":null,"value":null}, {"id":"abbaye_de_leffe","key":null,"value":null}, {"id":"abbaye_de_maredsous","key":null,"value":null}, {"id":"abbaye_notre_dame_du_st_remy","key":null,"value":null}, {"id":"abbey_wright_brewing_valley_inn","key":null,"value":null}, {"id":"aberdeen_brewing","key":null,"value":null} ] }
With the view created, the next step is to modify the
RepositoryBase to have a
GetAll method. This method will use some
conventions to allow for reuse across subclasses. One of those
conventions is that queries will be made to design docs with
camel-cased and pluralized names (e.g., Brewery to breweries). To
aid in the pluralization process, create a reference to
inflector_extension using NuGet. Note that in .NET 4.5, there is a
PluralizationService class that will provide
some of the same support.
To the RepositoryBase class, add a readonly
private field and initialize it to the inflected and pluralized
name of the type of T. The inflector extension methods will
require an additional using statement.
using inflector_extension; private readonly string _designDoc; public RepositoryBase() { _designDoc = typeof(T).Name.ToLower().InflectTo().Pluralized; }
The initial implementation of GetAll will
simply return all breweries using the generic
GetView<T> method of
CouchbaseClient. The third parameter instructs
CouchbaseClient to retrieve the original
document rather than deserialize the value of the view row.
public virtual IEnumerable<T> GetAll() { return _Client.GetView<T>(_designDoc, "all", true); }
RepositoryBase is a generic and abstract class,
so obviously it cannot be used directly. Create a new class in
“Models” named “BreweryRepository.” The code for this
class is very minimal, as it will rely on its base class for most
functionality.
public class BreweryRepository : RepositoryBase<Brewery> { }