2011-11-23 116 views
3

在我开始之前,请不要告诉我使用SQL。这是一个更大范围内的小问题,我不能也不想在这里使用关系数据库。我知道这个问题在SQL中很容易解决。CouchDB MapReduce查询关系数据

有三种类型的文件:

  • 玩家
  • 赞助商

队属于一个赞助商,但有很多玩家。一名球员可以有多支球队,而一名赞助者可以有多支球队。

玩家1 ---ň队ñ--- 1个赞助

我把玩家文档ID到小组文件中的数组:

players: ["payer1","player2",...] 

现在我想所有(不同,只命名一次)赞助商为特定球员:

PLAYER1:Sponsor1,Sponsor2,Sponsor3,...

它在CouchDB Wiki有点像NN的例子,但小号因为队员中有多个键,这不起作用。

我创建了一个gist with example data.

任何想法如何编写MapReduce函数来获得此结果?

我得到的最接近,但节目赞助商多次,组级1:

function(doc) { 
    if(doc.type == "team") 
    emit(doc.players,doc.sponsor); 
} 
function(keys, values) { 
    return (values); 
} 
+0

可能是有用的? http://stackoverflow.com/questions/5511810/couchdb-view-equivalent-of-sum-group-by – ajreal

回答

4

你接近你的观点,这是略作修改:

"playerSponsers": { 
     "map": "function(doc) { 
       if(doc.type == "team" && doc.players) { 
        for (i in doc.players) { 
         emit([doc.players[i], doc.sponsor],1); 
        } 
       } 
       }", 
     "reduce": "_sum" 
    } 

这里是查询:

http://localhost:5984/test/_design/sports/_view/playerSponsors?group=true&group_level=2 

您会得到如下结果:

{"rows":[ 
{"key":["Player1","Sponsor1"],"value":1}, 
{"key":["Player1","Sponsor2"],"value":1}, 
{"key":["Player1","Sponsor3"],"value":1}, 
{"key":["Player2","Sponsor1"],"value":1}, 
{"key":["Player2","Sponsor2"],"value":2}, 
{"key":["Player2","Sponsor3"],"value":1} 
]} 

如果你想获得只是一个球员的赞助商,您可以查询这样

http://localhost:81/test/_design/sports/_view/playerSponsors?group=true&group_level=2&startkey=[%22Player1%22]&endkey=[%22Player1%22,{}] 
+0

太棒了,非常感谢你! – Patrick