我有2个收藏:单词和短语 每个word文档都有一个短语id的数组。每个短语都可以是活动的或非活动的。
例如:
单词:
{“word”=> “你好”,短语=> [1,2]}
{{word“=> “table”,短语=> [2]}
短语:
{{id“=> 1,“短语”=> “你好世界!”,“主动”=> 1}
{{id“=> 2,“短语”=> “你好,我已经买了新桌子”,“主动”=> 0}
我需要为每个单词计算活动短语。
在php中我这样做:
1.得到所有的词
2.对于每个单词,获取具有条件的活动短语的计数['active'=> 1]
问题:如何在一个请求中获得包含活动短语的单词?我尝试使用MapReduce,但我需要为每个单词发出请求以获取活动短语的计数。
UPD:
在我的测试集中,有92000个短语和23000个单词。
我已经测试了两个变体:每个单词的php循环,其中我得到短语计数和mongo中的aggreagation函数。
但是由于phrase_data,我改变了聚合管道以表达以下内容。它是数组,所以我不能使用$ match。我在$ lookup之后使用$ unwind。
[ '$unwind' => '$5'],
[
'$lookup' => [
'from' => 'phrases_926ee3bc9fa72b029e028ec90e282072ea0721d1',
'localField' => '5',
'foreignField' => '0',
'as' => 'phrases_data'
]
],
[ '$unwind' => '$phrases_data'],
[ '$match' => [ 'phrases_data.3' => 77] ], //phrases_data.3 => 77 it is similar to phrases_data.active => 1
[ '$group' =>
[
'_id' => ['word' => '$1', 'id' => '$0'],
'active_count' => [ '$sum' => 1]
]
],
[ '$match' => [ 'active_count' => ['$gt' => 0]] ],
[ '$sort' =>
[
'active_count' => -1
]
]
问题是$ group命令占用了80%的处理时间。而且它比php循环要慢得多。以下是我的测试收集结果:
1. Php loop (get words-> get phrases count for each word): 10 seconds
2. Aggregation function : 20 seconds
答案 0 :(得分:0)
db.words.aggregate([
{ "$unwind" : "$phrases"},
{
"$lookup": {
"from": "phrases",
"localField": "phrases",
"foreignField": "id",
"as": "phrases_data"
}
},
{ "$match" : { "phrases_data.active" : 1} },
{ "$group" : {
"_id" : "$word",
"active_count" : { $sum : 1 }
}
}
]);
您可以使用以上聚合管道: