2012-02-21 69 views
0

我在MongoDB上运行多个长时间运行的mapreduce操作,我想在运行时获取该操作的opid。使用C#驱动程序,MapReduce调用被阻塞,所以在操作完成后它会回来。找出MongoDB MapReduce opid

我希望能够标记mapreduce操作,以便我可以检查他们的进度,我现在唯一能想到的方法是创建一个具有唯一标识符的JavaScript变量,并遍历db.currentOp的输出为那个变量。有没有更好的方法来做到这一点?

代码的问题:

MongoCollection<BsonDocument> logCollection = database.GetCollection<BsonDocument>("source_collection"); 

BsonJavaScript map = new BsonJavaScript(@"function() { //map  }"); 
BsonJavaScript reduce = new BsonJavaScript(@"function(key,values){ //reduce }"); 

var builder = new MapReduceOptionsBuilder(); 
builder.SetOutput("output_collection"); 

MapReduceResult mapReduceResult = logCollection.MapReduce(map, reduce, builder); //<--- Blocks until the mapreduce job completes 

我会喜欢要做的就是提交的MapReduce的工作异步和检查进度,因为它运行像这样(注意是由MapReduceJob类):

MongoCollection<BsonDocument> logCollection = database.GetCollection<BsonDocument>("source_collection"); 

BsonJavaScript map = new BsonJavaScript(@"function() { //map  }"); 
BsonJavaScript reduce = new BsonJavaScript(@"function(key,values){ //reduce }"); 

var builder = new MapReduceOptionsBuilder(); 
builder.SetOutput("output_collection"); 

MapReduceJob job = logCollection.StartMapReduce(map, reduce, builder); //<--- Returns straight away 

while (true) 
{ 
    Thread.Sleep(1000); 
    var operationDoc = database.GetCurrentOp(); 
    var operations = operationDoc["inprog"].AsBsonArray; 
    var thisOperation = operations.FirstOrDefault(op => op["opid"] == job.OpId); 
    if (thisOperation == null) 
     break; 
    } 
} 

回答

0

如何使MapReduceJob创建一个新线程来执行阻塞映射reduce调用?您应该能够通过维护一个正确同步的标志来告诉您它是否完成,从而可以轻松判断地图是否缩短作业的完成时间。

+0

不完全。如果作业运行超时,则MapReduce调用将引发超时异常,但作业将继续运行。它也不让我跟踪进度,这可能使用'currentOp'输出。 – 2012-02-22 04:11:45

+0

在这种情况下,您确实必须轮询地图缩减作业的$ cmd.sys.inprog集合。我并不十分熟悉C#驱动程序的API,但实际上可以在js:m.r. )。但是,这只适用于你的m和r函数很小的情况,否则它会显示“查询不记录(太大)”。 – Ren 2012-02-22 16:02:55