简体   繁体   中英

MongoDB MapReduce from C# returns no result

I am trying to run a MongoDB MapReduce from my C# code and unfortunately I am not able to obtain any result.
If I run the same MapReduce directly in the MongoDB shell, everything works fine.
Any help would be appreciated.

Here's the data about my issue:

  • C# driver version: 2.4.4
  • MongoDB version: 3.4.5
  • Example of input document 'DocInput'
{
    "_id" : ObjectId("59c52b3cb602cb6397c2ec9d"),
    "Timestamp" : NumberLong(1505860144116),
    "Value" : 14,
    "Date" : ISODate("2017-09-19T22:29:04.116Z")
}
  • MapReduce by JS
function mapF() {
    const key = this.Date.getFullYear();
    const valuePerYear = { total: 1};

    emit(key, valuePerYear)
};      

function reduceF(year, values) {
    let sum = 0
    values.forEach(v => {
        sum += v.total;
    });
    return {total: NumberInt(sum)};
}

db
    .getCollection('DocInput')
    .mapReduce(mapF, 
               reduceF, 
               { 
                   out: { reduce: "Result", nonAtomic: true }, 
               });
  • MapReduce by C#
public class Program
{
    private const string MapJs = @"function mapF() {
    const key = this.Date.getFullYear();
    const valuePerYear = { total: 1};

    emit(key, valuePerYear)
}; ";

    private const string ReduceJS = @"function reduceF(year, values) {
    let sum = 0;
    values.forEach(v => {
        sum += v.total;
    });
    return {total: NumberInt(sum)};
}";

    public void Main1()
    {
        string mongoConnectionString = "my-connection-string";
        MongoUrl mongoUrl = MongoUrl.Create(mongoConnectionString);
        MongoClient client = new MongoClient(mongoConnectionString);
        IMongoDatabase db = client.GetDatabase(mongoUrl.DatabaseName);
        IMongoCollection<BsonDocument> collection = db.GetCollection<BsonDocument>("DocInput");
        BsonJavaScript map = new BsonJavaScript(MapJs);
        BsonJavaScript reduce = new BsonJavaScript(ReduceJS);
        FilterDefinitionBuilder<BsonDocument> filterBuilder = new FilterDefinitionBuilder<BsonDocument>();
        FilterDefinition<BsonDocument> filter = filterBuilder.Empty;
        MapReduceOptions<BsonDocument, BsonDocument> options = new MapReduceOptions<BsonDocument, BsonDocument>
        {
            Filter = filter,
            MaxTime = TimeSpan.FromMinutes(1),
            OutputOptions = MapReduceOutputOptions.Reduce("Result", nonAtomic: true),
            Verbose = true
        };
        try
        {
            collection.MapReduce(map, reduce, options).ToList();
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Exception occurred {ex.Message}");
        }
    }
}

Thanks to Alex Blex suggestion I profiled the execution of the two MapReduce. Here's the result:

  • MongoDB shell execution
{
    "op" : "command",
    "ns" : "stat.Result",
    "command" : {
        "mapreduce" : "DocInput",
        "map" : function mapF() {
    const key = this.Date.getFullYear();
    const valuePerYear = { total: 1};

    emit(key, valuePerYear);
},
        "reduce" : function reduceF(year, values) {
    let sum = 0;
    values.forEach(v => {
        sum += v.total;
    });
    return {total: NumberInt(sum)};
},
        "out" : {
            "reduce" : "Result",
            "nonAtomic" : true
        }
    },
    "keysExamined" : 0,
    "docsExamined" : 0,
    "numYield" : 1440,
    "locks" : {
        "Global" : {
            "acquireCount" : {
                "r" : NumberLong(6507),
                "w" : NumberLong(15),
                "W" : NumberLong(2)
            }
        },
        "Database" : {
            "acquireCount" : {
                "r" : NumberLong(10),
                "w" : NumberLong(7),
                "R" : NumberLong(3235),
                "W" : NumberLong(11)
            }
        },
        "Collection" : {
            "acquireCount" : {
                "r" : NumberLong(10),
                "w" : NumberLong(10)
            }
        },
        "Metadata" : {
            "acquireCount" : {
                "W" : NumberLong(1)
            }
        }
    },
    "responseLength" : 115,
    "protocol" : "op_command",
    "millis" : 1751,
    "planSummary" : "COUNT",
    "execStats" : {
        "stage" : "COUNT",
        "nReturned" : 0,
        "executionTimeMillisEstimate" : 0,
        "works" : 1,
        "advanced" : 0,
        "needTime" : 0,
        "needYield" : 0,
        "saveState" : 0,
        "restoreState" : 0,
        "isEOF" : 1,
        "invalidates" : 0,
        "nCounted" : 1,
        "nSkipped" : 0
    },
    "ts" : ISODate("2017-09-28T07:22:07.678Z"),
    "client" : "127.0.0.1",
    "appName" : "MongoDB Shell",
    "allUsers" : [ 
        {
            "user" : "statrw",
            "db" : "stat"
        }
    ],
    "user" : "statrw@stat"
}
  • C# execution
{
    "op" : "command",
    "ns" : "stat.Result",
    "command" : {
        "mapreduce" : "DocInput",
        "map" : function mapF() {
    const key = this.Date.getFullYear();
    const valuePerYear = { total: 1};

    emit(key, valuePerYear);
};,
        "reduce" : function reduceF(year, values) {
    let sum = 0;
    values.forEach(v => {
        sum += v.total;
    });
    return {total: NumberInt(sum)};
},
        "out" : {
            "reduce" : "Result",
            "db" : "statdb",
            "nonAtomic" : true
        },
        "query" : {},
        "scope" : {},
        "jsMode" : true,
        "verbose" : true,
        "maxTimeMS" : 60000.0
    },
    "keysExamined" : 0,
    "docsExamined" : 179395,
    "numYield" : 1408,
    "locks" : {
        "Global" : {
            "acquireCount" : {
                "r" : NumberLong(6432),
                "w" : NumberLong(12),
                "W" : NumberLong(2)
            }
        },
        "Database" : {
            "acquireCount" : {
                "r" : NumberLong(6),
                "w" : NumberLong(4),
                "R" : NumberLong(3203),
                "W" : NumberLong(11)
            }
        },
        "Collection" : {
            "acquireCount" : {
                "r" : NumberLong(6),
                "w" : NumberLong(7)
            }
        },
        "Metadata" : {
            "acquireCount" : {
                "W" : NumberLong(1)
            }
        }
    },
    "responseLength" : 243,
    "protocol" : "op_query",
    "millis" : 321,
    "planSummary" : "COLLSCAN",
    "execStats" : {
        "stage" : "COLLSCAN",
        "nReturned" : 179395,
        "executionTimeMillisEstimate" : 74,
        "works" : 179397,
        "advanced" : 179395,
        "needTime" : 1,
        "needYield" : 0,
        "saveState" : 3201,
        "restoreState" : 3201,
        "isEOF" : 1,
        "invalidates" : 0,
        "direction" : "forward",
        "docsExamined" : 179395
    },
    "ts" : ISODate("2017-09-28T07:23:20.567Z"),
    "client" : "127.0.0.1",
    "allUsers" : [ 
        {
            "user" : "statrw",
            "db" : "stat"
        }
    ],
    "user" : "statrw@stat"
}

As you can see in this MongoDB ticket , Robert Stam discovered a workaround: if you remove the trailing semicolon inside tha map and reduce functions, everything works fine.

However he's written that he's going to open a server ticket because the silent fail is a problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM