Mapreduce将输入字符串拆分为输出数组



我正在处理如下文档:

> db.productData.find({"upc" : "XXX"}).pretty()
{
    "_id" : ObjectId("538dfa3d44e19b2bcf590a77"),
    "upc" : "XXX",
    "productDescription" : "bla foo bar bla bla fooX barY",
    "productSize" : "",
    "ingredients" : "foo; bar; foo1; bar1.",
    "notes" : "bla bla bla"
}
> 
  • 我想有一个包含字段之间的文档,拆分成分的列表/数组(在;上)。我想将原始集合的字符串拆分为字符串数组。
  • 我想只映射输出集合中的一些输入字段。
  • 我想在MongoDB上使用mapreduce

我尝试了许多不同的方法移动的东西从map函数到reduce函数未能找到一个适当的解决方案。从我执行的所有尝试中,现在我知道我需要检查null值等,因此以下是我的最后一次尝试:

map函数:

var mapperProductData = function () {
    var ingredientsSplitted = values.ingredientsString.split(';');
    var objToEmit = {barcode : "", description : "", ingredients : []};
    // checking for null (is this strictly necessary? why?)
    if ( 
            this.hasOwnProperty('ingredients')
         && this.hasOwnProperty('productDescription')
         && this.hasOwnProperty('upc')
       ) {
        for (var i = 0; i < ingredientsSplitted.length; i++) {
            // I want to emit a new document only when I have all the splitted strings inside the array
            if (i == ingredientsSplitted.length - 1) {
                 objToEmit.barcode     = this.upc;
                 objToEmit.description = this.productDescription;
                 objToEmit.ingredients = ingredientsSplitted;
                 emit(this.upc, objToEmit);
            }
        }
    }
};

reduce函数:

    var reducerNewMongoCollection = function(key, values) {
    return values;
};

map-reduce调用:

db.productData.mapReduce(
    mapperProductData,
    reducerNewMongoCollection,
    {
        out : "newMongoCollection" ,
        query: { "values" : {$exists: true} }
    }
);

我在输出中得到一个空集合(newMongoCollection是空的)。我做错了什么?

让我们从头开始。你的map函数应该是这样的:

var mapperProductData = function () {    
    var ingredientsSplitted = this.ingredients.split(';');    
    var objToEmit = {
        barcode : this.upc, 
        description : this.productDescription, 
        ingredients : ingredientsSplitted
    };
    emit(this.upc, objToEmit);        
};

你的map-reduce调用应该是:

db.productData.mapReduce(
    mapperProductData,
    reducerNewMongoCollection,
    {
        out : "newMongoCollection", 
        query : { 
            upc : { $exists : true }, 
            productDescription : { $exists : true }, 
            ingredients : { $exists : true , $type : 4 }
        } 
    }
);

查询部分将过滤具有相关字段的文档。此外,查询参数$type将只匹配成分为数组的文档。这样你就不需要在你的map函数中做复杂的检查,并且发送给map函数的文档数量会更少。

测试文档的结果将如下所示:

key : XXX, 
value: {
    "barcode" : "XXX",
    "description" : "bla foo bar bla bla fooX barY",
    "ingredients" : [
        "foo",
        " bar",
        " foo1",
        " bar1."
    ]
}

相关内容

  • 没有找到相关文章

最新更新