Customer MapReduce implementation I would love a second opinion / another pair of eyes on this.

db.customers.mapReduce(
    function() {
        Array.prototype.getUnique = function() {
            var u = {}, a = [];
            for (var i = 0, l = this.length; i &lt; l; ++i) {
                if (u.hasOwnProperty(this[i])) {
                    continue;
                }
                a.push(this[i]);
                u[this[i]] = 1;
            }
            return a;
        }
        var customer = this;
        this.tags.getUnique().forEach(function(tag) {
            if (customer.status) {
                emit(customer.shop, {
                    "kind": "unique_customers_submitted",
                    "tag": tag.tag,
                });
            } else {
                emit(customer.shop, {
                    "kind": "unique_customers_withheld",
                    "tag": tag.tag,
                });
            }
            emit(customer.shop, {
                "kind": "unique_customers_total",
                "tag": tag.tag,
            });
        })
        this.tags.forEach(function(tag) {
            if (customer.status) {
                emit(customer.shop, {
                    "kind": "total_customers_submitted",
                    "tag": tag.tag,
                });
            } else {
                emit(customer.shop, {
                    "kind": "total_customers_withheld",
                    "tag": tag.tag,
                });
            }
            emit(customer.shop, {
                "kind": "total_customers",
                "tag": tag.tag,
            });
        });
    },
    function(key, sets) {
        var forms = {};
        sets.forEach(function(set) {
            if (typeof forms[set.tag] == "undefined") forms[set.tag] = {};
            if (typeof forms[set.tag][set.kind] == "undefined") forms[set.tag][set.kind] = 0;
            forms[set.tag][set.kind] += 1;
        });
        return forms;
    }, {
        out: "form_numbers",
    },
    function(err, results) {
        console.log(err);
        //console.log(results);
        results.find().toArray(function(err, numbers) {
            console.log(err);
            console.log(JSON.stringify(numbers));
            db.server.close();
        });
    }
);
I'm not familiar with MR best practices, but here are some JS-specific comments.

Key Points


DRY - that emit code is repeated all over the place and has only slight changes - parameterize what varies and put it all in a function
You are repeating your loops - either do everything in one loop for better performance (and keep in mind that for is faster than forEach, or go fully functional (see next)
You are essentially doing a filter within your loop - use filter to remove the if logic from within the loop (or see previous). If you want to go even more functional, maybe you should use underscorejs or lo-dash, which both have a unique function already.
Never change the prototype of a builtin unless you have already checked if the method exists (like a polyfill) and/or you have a really, really good reason to do so. Mostly, just don't.
Declare functions so that they are not re-created (unless necessary)
You should probably close your db connection ASAP
Oh, and name your inline functions to provide better documentation


A simple refactoring hosted as a gist for easy forking

function getUnique() {
    var u = {}, a = [];
    for (var i = 0, l = this.length; i &lt; l; ++i) {
        if (u.hasOwnProperty(this[i])) {
            continue;
        }
        a.push(this[i]);
        u[this[i]] = 1;
    }
    return a;
};
function emitHelper(kind, shop, tag) {
    emit(shop, {
        "kind": kind,
        "tag": tag,
    });
};
db.customers.mapReduce(
    function mapCustomerToShopWithKindAndTag() {
        var customer = this;
        var kind;
        getUnique(this.tags).forEach(function(tag) {
            kind = customer.status ? "unique_customers_submitted" : "unique_customers_withheld";
            emitHelper(kind, customer.shop, tag.tag);
            emitHelper("unique_customers_total", customer.shop, tag.tag);
        });
        this.tags.forEach(function(tag) {
            kind = customer.status ? "total_customers_submitted" : "total_customers_withheld";
            emitHelper(kind, customer.shop, tag.tag);
            emitHelper("total_customers_total", customer.shop, tag.tag);
        });
    },
    function reduceToCountOfKindsPerTag(key, sets) {
        var forms = {};
        sets.forEach(function(set) {
            if (typeof forms[set.tag] == "undefined") forms[set.tag] = {};
            if (typeof forms[set.tag][set.kind] == "undefined") forms[set.tag][set.kind] = 0;
            forms[set.tag][set.kind] += 1;
        });
        return forms;
    }, {
        out: "form_numbers",
    },
    function(err, results) {
        console.log(err);
        //console.log(results);
        results.find().toArray(function(err, numbers) {
            db.server.close(); // Maybe wrap in a try/catch too
            console.log(err);
            console.log(JSON.stringify(numbers));
        });
    }
);