C#でMongoDBでのサーバーサイドJavaScriptを実行する

 コレクションの集計処理をしたかったのだが、MapReduceでは望みの形に集計結果をまとめられなかった。だからサーバーサイドJavaScriptでやることにした。ただしサーバーサイドJavaScriptはセキュリティの懸念やパフォーマンスの注意点があるので気軽に使うものではない。今回はそれらが問題として出てこないので使うことにした。

 まずC#コード。サーバーサイドで実行するJavaScriptも埋め込んだ。
//using MongoDB.Driver;

//using MongoDB.Bson;
//using MongoDB.Driver.Core.Operations;
//using MongoDB.Driver.Core.WireProtocol.Messages.Encoders;
//using MongoDB.Driver.Core.Bindings;
//using System.Threading;

class Program
{
private static IMongoClient client;
private static IMongoDatabase DbConnection;

static void Main(string[] args)
{
client = new MongoClient("mongodb://127.0.0.1");
DbConnection = client.GetDatabase("helicon");

AggregateTag();
}

public static void AggregateTag()
{
var databaseName = new DatabaseNamespace("helicon");

var code = (BsonJavaScript)@"
function () {
// do something
}";

var messageEncodingSettings = new MessageEncoderSettings();
var operation = new EvalOperation(databaseName, code, messageEncodingSettings);
var source = new CancellationTokenSource();
var token = source.Token;
var writeBinding = new WritableServerBinding(client.Cluster);
operation.Execute(writeBinding, CancellationToken.None);
}
}


 あとはサーバサイドでJavaScriptを実行するために、接続ユーザに実行権限を持たせる。
Allow user to execute eval() command on MongoDB 3.x

データベースに管理権限者でログイン。そしてadminデータベースへ。
use admin;


ロールを作成。
db.createRole( { role: "executeFunctions", privileges: [ { resource: { anyResource: true }, actions: [ "anyAction" ] } ], roles: [] } )


ロールを接続ユーザに付加。
db.grantRolesToUser("someone", [ { role: "executeFunctions", db: "admin" } ])


付加されたことを確認。
db.getUser("someone") 


これで権限が付いたので、C#コードを実行すればMongoDBのサーバサイドJSが実行される。

 このブログのサイドバーの、タグや投稿月毎の記事のカウントにこの、MongoDBのサーバサイドJSを使っている。
comment: 0