2011-07-08 5 views
0

ユニグラムのベクトルを生成する必要があります。つまり、特定のテキストフィールドに表示されるすべてのユニークワードのベクトルです。 MongoDBのより広いJSONオブジェクトMongoDBのテキストフィールドからUnigramのリストを生成する最も効率的な方法

このベクターを生成する最も簡単で効率的な方法は何ですか。私は(OpenNLPのようなものを使って)トークン化を処理できる単純なJavaアプリケーションを書くことを考えていましたが、もっと良いアプローチはMongoのMap-Reduce機能を使ってこの問題に取り組むことだと思っています...しかし、私はこれについてどうやって行くことができるか確かめてください

もう1つの選択肢は、Apache Luceneのインデックス作成を使用することですが、このデータを1つずつエクスポートする必要があることを意味します。これは、カスタムJavaやRubyのアプローチで実際に同じ問題が発生します...

map Mongoのデータはより多くのドキュメントが挿入されるようになっています。新しい文書が常に追加されているので、これは本当に1つの作業ではありません。更新は非常にまれです。私はUnigramベクトルを更新するたびに、何百万ものドキュメント上でMap-Reduceを実行したくありません。

どのようにすれば最も効率的でしょうかunigramベクトルを生成し、それを更新し続ける方法?

ありがとうございます!

+0

誰でもヘルプ? – NightWolf

答えて

2

サンプルドキュメント(オブジェクト)形式を指定していないので、「stories」と呼ばれるサンプルコレクションとしてください。

{ "_id" : ObjectId("4eafd693627b738f69f8f1e3"), "body" : "There was a king", "author" : "tom" } 
{ "_id" : ObjectId("4eafd69c627b738f69f8f1e4"), "body" : "There was a queen", "author" : "tom" } 
{ "_id" : ObjectId("4eafd72c627b738f69f8f1e5"), "body" : "There was a queen", "author" : "tom" } 
{ "_id" : ObjectId("4eafd74e627b738f69f8f1e6"), "body" : "There was a jack", "author" : "tom" } 
{ "_id" : ObjectId("4eafd785627b738f69f8f1e7"), "body" : "There was a humpty and dumpty . Humtpy was tall . Dumpty was short .", "author" : "jane" } 
{ "_id" : ObjectId("4eafd7cc627b738f69f8f1e8"), "body" : "There was a cat called Mini . Mini was clever cat . ", "author" : "jane" } 

特定のデータセットでは、次のjavascriptコードを使用してソリューションにアクセスできます。コレクション "authors_unigrams"には結果が含まれています。すべてのコードはmongo console(http://www.mongodb.org/display/DOCS/mongo+-+The+Interactive+Shell)を使用して実行されるはずです。

まず、我々は「の物語」コレクションに新たに来ているすべての新しいドキュメントのマークする必要があります。私たちは以下のコマンドを使ってそれを行います。各ドキュメントに "mr_status"という新しい属性を追加し、値 "inprocess"を割り当てます。後で、map-reduce操作では、フィールド "mr_status"の値が "inprocess"のアカウント内のドキュメントのみを取得することがわかります。このようにして、以前の試みのいずれかで既に考慮されているmap-reduce操作のすべての文書を再検討することを避けることができます。

db.stories.update({mr_status:{$exists:false}},{$set:{mr_status:"inprocess"}},false,true); 

第二に、我々は()機能を減らす)(両方マップを定義します。

var map = function() { 
     uniqueWords = function (words){ 
      var arrWords = words.split(" "); 
      var arrNewWords = []; 
      var seenWords = {}; 
      for(var i=0;i<arrWords.length;i++) { 
       if (!seenWords[arrWords[i]]) { 
        seenWords[arrWords[i]]=true; 
        arrNewWords.push(arrWords[i]); 
       } 
      } 
      return arrNewWords; 
     } 
     var unigrams = uniqueWords(this.body) ; 
     emit(this.author, {unigrams:unigrams}); 
}; 

var reduce = function(key,values){ 

    Array.prototype.uniqueMerge = function(a) { 
     for (var nonDuplicates = [], i = 0, l = a.length; i<l; ++i) { 
      if (this.indexOf(a[i]) === -1) { 
       nonDuplicates.push(a[i]); 
      } 
     } 
     return this.concat(nonDuplicates) 
    }; 

    unigrams = []; 
    values.forEach(function(i){ 
     unigrams = unigrams.uniqueMerge(i.unigrams); 
    }); 
    return { unigrams:unigrams}; 
}; 

第三、我々は実際にマップ-reduce関数を実行します。

var result = db.stories.mapReduce(map, 
            reduce, 
            {query:{author:{$exists:true},mr_status:"inprocess"}, 
            out: {reduce:"authors_unigrams"} 
            }); 

第四に、我々は「処理済み」として「mr_status」を設定することで処理され、最後のランでマップ減らすために検討されているすべてのレコードをマーク。

db.stories.update({mr_status:"inprocess"},{$set:{mr_status:"processed"}},false,true); 

オプション、あなたは、以下のコマンドを焼成することにより、結果コレクション"authors_unigrams"を見ることができます。

db.authors_unigrams.find(); 
関連する問題