开发者

MongoDB MapReduce : use positional operator $ in map function

开发者 https://www.devze.com 2023-03-09 16:56 出处:网络
I have a collection with entries that look like that : {\"userid\": 1, \"contents\": [ { \"tag\": \"whatever\", \"value\": 100 },{\"tag\": \"whatever2\", \"value\": 110 } ] }

I have a collection with entries that look like that :

{"userid": 1, "contents": [ { "tag": "whatever", "value": 100 }, {"tag": "whatever2", "value": 110 } ] }

I'm performing a MapReduce on this collection with queries such as {"contents.tag": "whatever"}.

What I'd like to do in my map function is emiting the field "value" corresponding to the entry in the array "contents" that matched the query without having to iterate through the whole array. Under normal circumstances, I could do that using the $ positional operator with something like contents.$.value. But in the MapReduce case, it's not working.

To summarize, here is the code I have right now :`

map=function(){
        e开发者_运维问答mit(this.userid, WHAT DO I WRITE HERE TO EMIT THE VALUE I WANT ?);
    }
    reduce=function(key,values){
        return values[0]; //this reduce function does not make sense, just for the example
    }
    res=db.runCommand(
    {
        "mapreduce": "collection",
        "query": {'contents.tag':'whatever'},
        "map": map,
        "reduce": reduce,
        "out": "test_mr" 
    }
    );`

Any idea ?

Thanks !


This will not work without iterating over the whole array. In MongoDB a query is intended to match an entire document.

When dealing with Map / Reduce, the query is simply trimming the number of documents that are passed into the map function. However, the map function has no knowledge of the query that was run. The two are disconnected.

The source code around the M/R is here.

There is an upcoming aggregation feature that will more closely match this desire. But there's no timeline on this feature.


No way. I've had the same problem. The iterate is necessary. You could do this:

map=function() {
  for(var i in this.contents) {
    if(this.contents[i].tag == "whatever") {
      emit(this.userid, this.contents[i].value);
    }
  } 
}
0

精彩评论

暂无评论...
验证码 换一张
取 消