J'essaie d'exécuter un MapReduce MongoDB à partir de mon code C# et malheureusement je ne peux pas obtenir de résultat.
Si j'exécute le même MapReduce directement dans le shell MongoDB, tout fonctionne correctement.
Toute aide serait appréciée.MongoDB MapReduce à partir de C# ne renvoie aucun résultat
est ici les données sur mon problème:
- C# version du pilote: 2.4.4
- Version MongoDB: 3.4.5
- Exemple de document d'entrée 'DocInput'
{
"_id" : ObjectId("59c52b3cb602cb6397c2ec9d"),
"Timestamp" : NumberLong(1505860144116),
"Value" : 14,
"Date" : ISODate("2017-09-19T22:29:04.116Z")
}
- MapReduce par 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 par 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}");
}
}
}
Merci à la suggestion Alex Blex Je l'exécution de profile deux MapReduce. Voici le résultat:
- shell MongoDB exécution
{
"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" : "[email protected]"
}
- C# exécution
{
"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" : "[email protected]"
}
À partir des résultats du profileur, le C# stocke 'Result' dans la base de données' statdb'. Savez-vous d'où vient le nom db? De toute façon, essayez de le définir explicitement: 'MapReduceOutputOptions.Reduce (" Résultat ", mongoUrl.DatabaseName, nonAtomic: true),' –
Malheureusement, même avec votre suggestion, je ne suis pas en mesure d'obtenir un document réduit dans le "Résultat". De plus, j'ai remarqué que l'exécution C# crée la collection "Result" si elle n'existe pas. Mais c'est vide. –
Eh bien, la seule différence que je vois (à part la base de données de sortie et un point-virgule supplémentaire après 'emit', que je crois être une faute de frappe) sont les paramètres supplémentaires:' "query": {}, "scope": {}, "jsMode": true, "verbose": true, "maxTimeMS": 60000.0'. Je suggère de les spécifier dans la demande de shell pour confirmer que cela fonctionne encore. –