Skip to content
This repository was archived by the owner on Oct 17, 2022. It is now read-only.

Commit 2a3c5c4

Browse files
janlflimzy
andauthored
feat(mango): updated intro tutorial to use mango isntead of MapReduce (#568)
Co-authored-by: Jonathan Hall <flimzy@flimzy.com>
1 parent 0c4700a commit 2a3c5c4

File tree

1 file changed

+71
-122
lines changed

1 file changed

+71
-122
lines changed

src/intro/tour.rst

Lines changed: 71 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -250,160 +250,109 @@ select Options, then check the Include Docs option. Finally, press the Run
250250
Query button. The full document should be displayed along with the ``_id``
251251
and ``_rev`` values.
252252

253-
Running a Query Using MapReduce
254-
===============================
255-
256-
Traditional relational databases allow you to run any queries you like as
257-
long as your data is structured correctly. In contrast,
258-
CouchDB uses predefined map and reduce functions in a style known as
259-
MapReduce. These functions provide great flexibility because they can adapt
260-
to variations in document structure, and indexes for each document can be
261-
computed independently and in parallel. The combination of a map and a reduce
262-
function is called a view in CouchDB terminology.
263-
264-
For experienced relational database programmers, MapReduce can take some
265-
getting used to. Rather than declaring which rows from which tables to
266-
include in a result set and depending on the database to determine the most
267-
efficient way to run the query, reduce queries are based on simple range
268-
requests against the indexes generated by your map functions.
269-
270-
Map functions are called once with each document as the argument.
271-
The function can choose to skip the document altogether or emit one or more
272-
view rows as key/value pairs. Map functions may not depend on any information
273-
outside of the document. This independence is what allows CouchDB views to be
274-
generated incrementally and in parallel.
275-
276-
CouchDB views are stored as rows that are kept sorted by key. This makes
277-
retrieving data from a range of keys efficient even when there are thousands
278-
or millions of rows. When writing CouchDB map functions,
279-
your primary goal is to build an index that stores related data under nearby
280-
keys.
281-
282-
Before we can run an example MapReduce view, we'll need some data to run it
283-
on. We'll create documents carrying the price of various supermarket items as
284-
found at different shops. Let's create documents for apples, oranges,
285-
and bananas. (Allow CouchDB to generate the _id and _rev fields.) Use Fauxton
286-
to create documents that have a final JSON structure that looks like this:
253+
Running a Mango Query
254+
=====================
255+
256+
Now that we have stored documents successfully, we want to be able to query
257+
them. The easiest way to do this in CouchDB is running a Mango Query. There are
258+
always two parts to a Mango Query: the index and the selector.
259+
260+
The index specifies which fields we want to be able to query on, and the
261+
selector includes the actual query parameters that define what we are looking
262+
for exactly.
263+
264+
Indexes are stored as rows that are kept sorted by the fields you specify. This
265+
makes retrieving data from a range of keys efficient even when there are
266+
thousands or millions of rows.
267+
268+
Before we can run an example query, we'll need some data to run it on. We'll
269+
create documents with information about movies. Let's create documents for
270+
three movies. (Allow CouchDB to generate the ``_id`` and ``_rev`` fields.) Use Fauxton
271+
to create documents that have a final JSON structure that look like this:
287272

288273
.. code-block:: javascript
289274
290275
{
291276
"_id": "00a271787f89c0ef2e10e88a0c0001f4",
292-
"_rev": "1-2628a75ac8c3abfffc8f6e30c9949fd6",
293-
"item": "apple",
294-
"prices": {
295-
"Fresh Mart": 1.59,
296-
"Price Max": 5.99,
297-
"Apples Express": 0.79
298-
}
277+
"type": "movie",
278+
"title": "My Neighbour Totoro",
279+
"year": 1988,
280+
"director": "miyazaki",
281+
"rating": 8.2
299282
}
300283
301-
OK, now that that's done, let's create the document for oranges:
302-
303284
.. code-block:: javascript
304285
305286
{
306287
"_id": "00a271787f89c0ef2e10e88a0c0003f0",
307-
"_rev": "1-e9680c5d9a688b4ff8dd68549e8e072c",
308-
"item": "orange",
309-
"prices": {
310-
"Fresh Mart": 1.99,
311-
"Price Max": 3.19,
312-
"Citrus Circus": 1.09
313-
}
288+
"type": "movie",
289+
"title": "Kikis Delivery Service",
290+
"year": 1989,
291+
"director": "miyazaki",
292+
"rating": 7.8
314293
}
315294
316-
And finally, the document for bananas:
317-
318295
.. code-block:: javascript
319296
320297
{
321298
"_id": "00a271787f89c0ef2e10e88a0c00048b",
322-
"_rev": "1-60e25d93dc12884676d037400a6fa189",
323-
"item": "banana",
324-
"prices": {
325-
"Fresh Mart": 1.99,
326-
"Price Max": 0.79,
327-
"Banana Montana": 4.22
328-
}
299+
"type": "movie",
300+
"title": "Princess Mononoke",
301+
"year": 1997,
302+
"director": "miyazaki",
303+
"rating": 8.4
329304
}
330305
331-
Imagine we're catering a big luncheon, but the client is very price-sensitive.
332-
To find the lowest prices, we're going to create our first view,
333-
which shows each fruit sorted by price. Click "All Documents" to return to the
334-
hello-world overview, and then from the "All Documents" plus sign, click "New
335-
View" to create a new view.
306+
Now we want to be able to find a movie by its release year, we need to create a
307+
Mango Index. To do this, go to “Run A Query with Mango” in the Database
308+
overview. Then click on “manage indexes”, and change the index field on the
309+
left to look like this:
310+
311+
.. code-block:: javascript
312+
313+
{
314+
"index": {
315+
"fields": [
316+
"year"
317+
]
318+
},
319+
"name": "year-json-index",
320+
"type": "json"
321+
}
336322
337-
Name the design document ``_design/myDesignDoc``, and set the Index name
338-
to ``prices``.
323+
This defines an index on the field ``year`` and allows us to send queries for
324+
documents from a specific year.
339325

340-
Edit the map function, on the right, so that it looks like the following:
326+
Next, click on “edit query” and change the Mango Query to look like this:
341327

342328
.. code-block:: javascript
343329
344-
function(doc) {
345-
var shop, price, value;
346-
if (doc.item && doc.prices) {
347-
for (shop in doc.prices) {
348-
price = doc.prices[shop];
349-
value = [doc.item, shop];
350-
emit(price, value);
351-
}
330+
{
331+
"selector": {
332+
"year": {
333+
"$eq": 1988
352334
}
353-
}
335+
}
336+
}
354337
355-
This is a JavaScript function that CouchDB runs for each of our documents as
356-
it computes the view. We'll leave the reduce function blank for the time being.
338+
Then click on ”Run Query”.
357339

358-
Click "Save Document and then Build Index" and you should see result rows,
359-
with the various items sorted by price. This map function could be even more
360-
useful if it grouped the items by type so that all the prices for bananas were
361-
next to each other in the result set. CouchDB's key sorting system allows any
362-
valid JSON object as a key. In this case, we'll emit an array of [item, price]
363-
so that CouchDB groups by item type and price.
340+
The result should be a single result, the movie “My Neighbour Toto” which
341+
has the year value of 1988. ``$eq`` here stands for “equal”.
364342

365-
Let's modify the view function (click the wrench icon next to the Views >
366-
prices Design Document on the left, then select Edit) so that it looks like
367-
this:
343+
You can also query for all movies during the 1980s, with this selector:
368344

369345
.. code-block:: javascript
370346
371-
function(doc) {
372-
var shop, price, key;
373-
if (doc.item && doc.prices) {
374-
for (shop in doc.prices) {
375-
price = doc.prices[shop];
376-
key = [doc.item, price];
377-
emit(key, shop);
378-
}
347+
{
348+
"selector": {
349+
"year": {
350+
"$lt": 1990
379351
}
380-
}
352+
}
353+
}
381354
382-
Here, we first check that the document has the fields we want to use. CouchDB
383-
recovers gracefully from a few isolated map function failures,
384-
but when a map function fails regularly (due to a missing required field or
385-
other JavaScript exception), CouchDB shuts off its indexing to prevent any
386-
further resource usage. For this reason, it's important to check for the
387-
existence of any fields before you use them. In this case,
388-
our map function will skip the first "hello world" document we created
389-
without emitting any rows or encountering any errors. The result of this
390-
query should now be displayed.
391-
392-
Once we know we've got a document with an item type and some prices,
393-
we iterate over the item's prices and emit key/values pairs. The key is an
394-
array of the item and the price, and forms the basis for CouchDB's sorted
395-
index. In this case, the value is the name of the shop where the item can be
396-
found for the listed price.
397-
398-
View rows are sorted by their keys -- in this example, first by item,
399-
then by price. This method of complex sorting is at the heart of creating
400-
useful indexes with CouchDB.
401-
402-
MapReduce can be challenging, especially if you've spent years working with
403-
relational databases. The important things to keep in mind are that map
404-
functions give you an opportunity to sort your data using any key you choose,
405-
and that CouchDB's design is focused on providing fast,
406-
efficient access to data within a range of keys.
355+
The result are the two movies from 1988 and 1998. ``$lt`` here means “lower than”.
407356

408357
Triggering Replication
409358
======================
@@ -416,7 +365,7 @@ through the examples.
416365

417366
First we'll need to create an empty database to be the target of replication.
418367
Return to the Databases overview and create a database called
419-
``hello-replication``. Now click "Replication" in the sidebar and choose
368+
``hello-replication``. Now click "Replication" in the sidebar and choose
420369
hello-world as the source and hello-replication as the target. Click
421370
"Replicate" to replicate your database.
422371

0 commit comments

Comments
 (0)