2

序文:

クリーンで効果的なコードを作成するために、mapreduce mongo スクリプトで外部関数を使用したいと考えています。

問題:

次のマップ関数 (coffeescript 構文) があるとします。

map: -> 
   key = foo(@field)
   emit(key, value)

外部関数 'foo' を呼び出すとエラーが発生する

➜ rake mongo:mapreduce
MongoDB shell version: 2.0.5
connecting to: localhost:27017/connect_development
{
    "assertion" : "map invoke failed: JS Error: ReferenceError: foo is not defined nofile_b:2",
    "assertionCode" : 9014,
    "errmsg" : "db assertion failure",
    "ok" : 0
}

reduce context 呼び出しでも同じことが返されます。

悪臭の決定 - 自己呼び出しの無名関数:

map: -> 
   key = ( (field)->
     # some business logic
   )(@field)

   emit(key, value)

自己呼び出しの無名関数は非常に大きく、テストするには効果的ではなく、メモリ リークを引き起こす可能性があります (これについては不明です)。

この問題を解決するにはどうすればよいですか?

更新:

「外部関数」と言ったとき、「マップ/リデュース」関数と同じファイル(同じクラス)で宣言された関数を意味しました。もちろん、サーバー側で呼び出されます。

4

2 に答える 2

2

マップ/リデュース関数は、別のコンテキストで db サーバー上で実行する必要があるため、「外部」のものに触れることはできません。

匿名関数をインラインで使用しても問題はありません。非常に安価です。深い再帰を避けるだけです。CoffeeScript には、クロージャーを作成するための構文があります。

map: -> 
  key = do =>
    k = @field.doSomething()
    return k
  emit key, value
于 2012-07-05T00:23:12.450 に答える
0

Map/Reduce コードは MongoDB サーバーで実行されます。Map/Reduce から呼び出すことができる関数をサーバー側に格納するオプションはありますが、ベスト プラクティスとして、関数を残りのコードと共にバージョン管理に保持することをお勧めします。匿名関数は JavaScript で一般的に使用されているため、問題にはなりません。

于 2012-07-05T00:29:26.473 に答える