【问题标题】:Trying to include Query within MongoDB MapReduce call尝试在 MongoDB MapReduce 调用中包含 Query
【发布时间】:2011-04-05 12:33:53
【问题描述】:

我正在尝试创建一个非常基本的 map-reduce 示例,该示例还在 MapReduce api 调用中合并了一个查询。

我的收藏有很多格式如下:

{ "_id" : { "$binary" : "PdYV4WMTAEyYMQHXJZfzvA==", "$type" : "03" }, 
    "firstname" : "Matthew", 
    "surname" : "Chambers", 
    "email" : "" }

代码如下:

var map = @"
function() {
    emit(this.surname, { count : 22 });
}";
var reduce = @"
function(key, emitValues) {
    return { count : emitValues[0].count };
}";

List<BsonValue> contactIds = new List<BsonValue>();
contactIds.Add(new Guid("A04FC88D-7BF7-443D-B5C3-EB11EE2B36DF"));
contactIds.Add(new Guid("26B690B3-5ED7-47F4-A878-3906E28BBC58"));
MongoDB.Driver.Builders.QueryConditionList queryList = MongoDB.Driver.Builders.Query.In("_id", BsonArray.Create(contactIds));
//var mr = personCollection.MapReduce(map, reduce);// THIS WORKS!    
var mr = personCollection.MapReduce(queryList, map, reduce); // THIS FAILS

如果我没有在 MapReduce 调用中包含 queryList,这一切都有效。但是,如果我确实包含了 queryList,那么我会收到以下运行时错误:

命令'mapreduce'失败:db断言失败(响应:{“assertion”:“'out'必须是字符串或对象”,“assertionCode”:13606,“errmsg”:“db断言失败”, “好”:0}) 在 C:\work\10gen\mongodb\mongo-csharp-driver\Driver\Core\MongoDatabase.cs: MongoDB.Driver.MongoCollection.MapReduce 中的 MongoDB.Driver.MongoDatabase.RunCommandAs[TCommandResult](IMongoCommand 命令):第 621 行( BsonJavaScript map, BsonJavaScript reduce, IMongoMapReduceOptions options) 在 C:\work\10gen\mongodb\mongo-csharp-driver\Driver\Core\MongoCollection.cs: MongoDB.Driver.MongoCollection.MapReduce(IMongoQuery 查询, BsonJavaScript map, BsonJavaScript reduce) 在 C:\work\10gen\mongodb\mongo-csharp-driver\Driver\Core\MongoCollection.cs:line 823 at HPSLucene.Models.Mongo.MapReduce() in C:\Inetpub\wwwroot\HPSLucene\HPSLucene \Models\Mongo.cs:第 158 行

有人知道问题出在哪里吗?非常感谢。

【问题讨论】:

  • 您使用的是什么版本的 C# 驱动程序?

标签: c# mongodb mapreduce


【解决方案1】:

看起来它已将您的呼叫与您认为正在呼叫的不同重载相匹配

即您打算调用 (query, map, reduce) 重载,但实际上它正在调用 (map, reduce, options) 重载。这会给您错误,因为您的第三个参数不是有效的选项参数。

尝试使用以下重载:(查询、映射、归约、选项) 然后它就可以正常工作了,不会对使用什么感到困惑。

例如返回 M/R 内联的结果,而不是存储在集合中:

var mr = personCollection.MapReduce(queryList, map, reduce, 
                MapReduceOptions.SetOutput(MapReduceOutput.Inline));

【讨论】:

  • 在当前驱动程序版本下,此语法似乎无效,相反,有必要通过@Journeyman 的答案中所示的options 参数设置过滤器。
【解决方案2】:

顺便说一句,按照 AdaTheDev 的回答,这就是我最终得到的结果:

List<BsonValue> contactIds = new List<BsonValue>();
contactIds.Add(new Guid("A04FC88D-7BF7-443D-B5C3-EB11EE2B36DF"));
contactIds.Add(new Guid("26B690B3-5ED7-47F4-A878-3906E28BBC58"));
MongoDB.Driver.Builders.QueryConditionList queryList = MongoDB.Driver.Builders.Query.In("_id", BsonArray.Create(contactIds));
MongoDB.Driver.Builders.MapReduceOptionsBuilder builder=new MongoDB.Driver.Builders.MapReduceOptionsBuilder();
builder.SetOutput(MongoDB.Driver.Builders.MapReduceOutput.Inline);
var mr = personCollection.MapReduce(map, reduce, builder);

【讨论】:

  • 差不多六年后的今天,这个代码示例仍然有用!
  • 虽然有用,但似乎没有显示出任何使用 queryList(已分配,但未使用)。
【解决方案3】:

我创建了一个测试程序来重现这一点,看起来它实际上正在调用正确的 MapReduce 重载。但是您在驱动程序中遇到了错误。我为它创建了一个 JIRA 案例:

http://jira.mongodb.org/browse/CSHARP-193

您的最终版本很好。通过提供显式选项参数,您可以解决该错误。

【讨论】:

  • 这个问题现在已经在 master 分支上修复了,修复将在下一个版本中进行。如果您想尽快修复,您可以获取源代码并自己构建驱动程序。感谢您报告此事!
  • 如果阅读我编写的测试程序可能对您有所帮助,您可以在这里查看:pastie.org/1759045
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-28
  • 1970-01-01
  • 1970-01-01
  • 2013-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多