我正在尝试使用以下代码从Java运行一些Js代码:
public void mapReduceScript()
{
try{
MongoClient mongoClient = new MongoClient( CoreConfigModel.get("com.dice.api.mongo.host") , Integer.parseInt(CoreConfigModel.get("com.dice.api.mongo.port")));
// Now connect to your databases
DB db = mongoClient.getDB( "tracking" );
System.out.println("Connect to database successfully");
boolean auth = db.authenticate(CoreConfigModel.get("mongo.username"), CoreConfigModel.get("mongo.password").toCharArray() );
System.out.println("Authentication: "+auth);
ClassLoader classLoader = Thread.currentThread()
.getContextClassLoader();
InputStream reduceStream = classLoader.getResourceAsStream("/data/mapReduceFunctionsByGroupIdIterative.js");
String reduce = IOUtils.toString(reduceStream, "UTF-8");
db.eval(reduce, new BasicDBObject("nolock", true));
}
catch (Exception e)
{
System.out.println(e);
}
}
以下是mapReduceFunctionsByGroupIdIterative.js
function mapFunction() {
if (!this.eventdata.Viewed || this.eventdata.Viewed.length === 0) {
return;
}
var key = this.groupid;
var value = {
Dockey: this.eventdata.Viewed[0].Dockey,
PID: this.eventdata.Viewed[0].PID,
datecreated: this.datecreated,
entityid: this.entityid
};
emit(key, value);
}
function reduceFunction(key, values) {
function merge(target, firstSource) { 'use strict';
if (target === undefined || target === null)
throw new TypeError('Cannot convert first argument to object');
var to = Object(target);
var hasPendingException = false;
var pendingException;
for (var i = 1; i < arguments.length; i++) {
var nextSource = arguments[i];
if (nextSource === undefined || nextSource === null)
continue;
var keysArray = Object.keys(Object(nextSource));
for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
var nextKey = keysArray[nextIndex];
try {
var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
if (desc !== undefined && desc.enumerable)
to[nextKey] = nextSource[nextKey];
} catch (e) {
if (!hasPendingException) {
hasPendingException = true;
pendingException = e;
}
}
}
if (hasPendingException)
throw pendingException;
}
return to;
}
var mostRecentViews = {
Dockey: {},
PID: {}
};
values.forEach(function (value) {
var key = value.Dockey ? 'Dockey' : 'PID';
var reducedValue = {
profileid: value[key],
datecreated: value.datecreated,
entityid: value.entityid
};
if (!(value[key] in this[key]) ||
new Date(value.datecreated) > new Date(this[key][value[key]].datecreated)) {
this[key][value[key]] = reducedValue;
}
}, mostRecentViews);
var reducedObject = merge({}, mostRecentViews.Dockey, mostRecentViews.PID);
return reducedObject;
}
function finalizeFunction(key, reducedValue) {
var finalizedObject = Object.keys(reducedValue).map(function (key, index, array) {
return reducedValue[key];
});
return finalizedObject;
}
var lastrundate = db.TRACKING_DATA.findOne({'_id': 'lastruntimeGroup'}).lastruntime;
db.TRACKING_DATA.mapReduce(mapFunction,
reduceFunction,
{
out: { reduce: "LASTVIEWED_GROUP"},
query: { datecreated:
{ $gt: lastrundate }
},
finalize: finalizeFunction
}
)
db.TRACKING_DATA.update({'_id': 'lastruntimeGroup'},{'_id': 'lastruntimeGroup', 'lastruntime': new Date()},{upsert:true})
然而,当我执行代码时,我会抛出错误:
com.mongodb.CommandFailureException: { "serverUsed" : "127.0.0.1:27017" , "errmsg" : "exception: ReferenceError: db is not defined" , "code" : 16722 , "ok" : 0.0}
我在我的Java代码中有两个对db one的引用:
DB db = mongoClient.getDB( "tracking" );
我的Js代码中的一个应该通过以下方式在mongo shell中运行:
db.eval(reduce, new BasicDBObject("nolock", true));
我在shell上运行了js文件,它按预期工作,所以我的java代码或调用db.eval()
的东西都在做一些时髦的事情。