2017-04-26 36 views
-1

我们的数据结构如下:顶部的话聚集了每个国家

{ 
    'country': 'United States', 
    'text': 'twitter text string...' 
}, 
{ 
    'country': 'Australia', 
    'text': 'a different twitter text string...' 
} 
... 

它包括大多数国家的数据。目前大约有150万条目。我们的目标是使用聚合来获取每个国家文本字段中最常用的单词。使用$ project,$ group,$ split,$ unwind,$ nin(用于停用词)和$ sort的组合,我们已经设法完成了。它给了我们每个单词的统计数字,按国家分开,然后我们可以排序以得到最重要的单词。然而,我试图找出如何让它只给每个国家的前N个字。因此,基本上计算每个国家的字数,排序,然后返回每个国家的前N个字。

我还不熟悉MongoDB查询。我不一定在寻找一个完整的解决方案,但我想知道我应该查看哪些查询参数和累加器来做这种事情。

回答

1

这里是与聚合框架的解决方案:

db.collection.aggregate([ 
      { 
       $project:{ 
       country:1, 
       words:{ 
        $split:[ "$text", " " ] 
       } 
       } 
      }, 
      { 
       $unwind:"$words" 
      }, 
      { 
       $group:{ 
       _id:{ 
        country:"$country", 
        word:"$words" 
       }, 
       count:{ 
        $sum:1 
       } 
       } 
      }, 
      { 
       $match:{ 
       "_id.word":{ 
        $nin:[ "a" ] 
       } 
       } 
      }, 
      { 
       $sort:{ 
       count:-1 
       } 
      }, 
      { 
       $group:{ 
       _id:"$_id.country", 
       top_words:{ 
        $push:"$_id.word" 
       } 
       } 
      }, 
      { 
       $project:{ 
       country:1, 
       top_words:{ 
        $slice:[ "$top_words", 2 ] 
       } 
       } 
      } 
     ]) 
  1. 拆分在白色空间中的文本在$project阶段
  2. 通过countrywords放松所得阵列
  3. 组得到每个国家的每个字的数量
  4. 过滤掉$match通过country阶段
  5. 排序上count
  6. 组文件和推在名为top_words
  7. 片阵列,以获得顶部N个字(这里是顶部2)
+0

此阵列,每个字精美的工作;谢谢。 $推是我失踪的关键。我现在仍然存在的一个问题就是这种问题。它给了我一个错误,它试图使用太多的内存,因为显然不同的单词列表太大了。我现在的解决方案是过滤掉小于10的任何东西。还有其他方法来处理这个问题吗? – anderspitman

+0

@anderspitman您可以尝试在查询的选项中添加'allowDiskUse:true'以避免内存错误 – felix

+0

这不会显着减慢查询吗? Mongo已经在我的系统上分配了超过20GB的内存。如果不允许查询,它会如何处理? – anderspitman