2017-09-27 5 views
1

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]" 
} 
+0

À 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),' –

+0

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. –

+0

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. –

Répondre

0

Comme vous pouvez le voir dans cette MongoDB ticket, Robert Stam a découvert une solution : si vous enlevez e le point-virgule à l'intérieur de la carte et réduire les fonctions, tout fonctionne bien. Cependant, il a écrit qu'il allait ouvrir un ticket de serveur parce que l'échec silencieux est un problème.