我正在尝试找到一种方法来在同一文档和文档中获取多个数组的唯一值。最好用一个例子来解释:
[
{
_id: "x",
products: {
product_a: ["v1", "v2"],
product_b: ["v3", "v2"]
}
},
{
_id: "y",
products: {
product_a: ["v1"],
product_b: ["v3", "v4"]
}
}
]
我想要的是:
答案 0 :(得分:2)
当您无法或不愿意更改架构时,您可以同时使用MapReduce
您的map-function会将产品中的所有数组连接成一个,删除重复项,然后以_id
为键发出该数组的大小。有关如何删除重复项的详细信息可以在this question中找到(忽略使用库浏览器javascript的答案)。
function mapFunction() {
var ret = [];
for (var product in this.products) {
for (var i = 0; i < product.length; i++) {
ret.push(product[i]);
}
}
[ remove duplicates with your favorite method from question 9229645 ]
return ret.length;
}
您的密钥是唯一的,因此每个密钥永远不会调用您的reduce函数。这意味着它只能返回values-array的第一个元素。
function reduceFunction(key, values) {
return values[0];
}
您可以通过将每个值作为键发送但具有无意义的值来实现此目的。
您的map-function将迭代products-object,然后迭代数组
function mapFunction() {
for (var product in this.products) {
for (var i = 0; i < product.length; i++) {
emit(product[i], null);
}
}
}
因为这些值没有意义,所以你的reduce函数对它们没有任何作用:
function reduceFunction(key, values) {
return null;
}
结果将是一组文档,其中每个_id
是数据中唯一的值之一。
如果没有充分的理由让您的架构保持现状,那么将products
对象转换为数组可以让您的生活更轻松:
products: [
{ product: "product_a", values: ["v1", "v2"] },
{ product: "product_b", values: ["v3", "v2"] }
]
在这种情况下,您可以使用聚合管道。