2015-09-09 15 views
5

Próbuję wywołać funkcję JavaScript przechowywaną ze sterownika Java MongoDB.Wywołanie funkcji MongoDB z Java

Podążałem za tym przewodnikiem, aby zapisać funkcję na serwerze DB i mogę wywołać funkcję z powłoki mongo i uzyskać wynik.

Jednak nie mogę się dowiedzieć, jak wywołać tę samą funkcję w Javie?

Według tego http://api.mongodb.org/java/current/com/mongodb/DB.html#doEval-java.lang.String-java.lang.Object...- istnieje metoda zwana doEval

Próbowałem również z niego korzystać z tej metody:

public static String callFunction() { 

    try (MongoClient client = new MongoClient("localhost")) { 
     com.mongodb.DB db = client.getDB("TestDB"); 
     return db.doEval("echoFunction", 3).toString(); 
    } 
} 

Ale gdy zgłoszę metody jest to, co mam:

{ "retval" : { "$code" : "function (x) {\n return x;\n}"} , "ok" : 1.0} 

i spodziewałbym się, że w tym przypadku otrzymam numer 3.

Kolejnym problemem z powyższym kodem jest to, że metoda client.getDB() jest przestarzała. Jak rozumiem, nowa metoda wywołania to client.getDatabase() i zwraca obiekt MongoDatabase, ale zgodnie z API nie ma metody wykonywania funkcji.

Moje pytanie brzmi: czy można uruchomić zapisaną funkcję JavaScript na serwerze bazy danych z poziomu Javy i odzyskać wynik tej funkcji? A jeśli to możliwe, byłbym wdzięczny za pomoc, jak to zrobić?

Dziękuję.

Edit:

Według komentarzu Calling server js function on mongodb from java:

„Wydaje się getNextSequence jest funkcja napisana w Mongo javascript shell Ani bazy danych (mongod) ani Java. strona wie, że ta funkcja istnieje i nie jest w stanie interpretować kodu JavaScript, który zawiera ta funkcja. Będziesz musiał ponownie wdrożyć go w języku Java . "

Funkcja, którą próbuję zaimplementować, jest nieco bardziej skomplikowana niż powyższy przykład - powinna zwracać kolekcję dokumentów i wydaje się, że nie działa ona przy użyciu metody db.doEval.

Zgaduję, że komentarz jest poprawny?

Odpowiedz

1

Należy to zrobić w zamian:

 return db.doEval("echoFunction(3)").toString(); 

Jeśli używasz tylko nazwisko funkcja w eval Ci odnieść tylko do zmiennej JavaScript po stronie serwera przechowującego kod funkcji. Nie wykonuje tego. Kiedy używasz nawiasów, prosisz o wykonanie funkcji. Jeśli chcesz wysłać coś bardziej skomplikowanego niż numer, radziłbym użyć serializatora JSON.

+0

OK, że pracował, dziękuję. Ale to zupełnie nie odpowiada na moje pytanie. Tak jak napisałem: Metoda client.getDB() jest przestarzała. Jak rozumiem, nową metodą wywołania jest client.getDatabase() i zwraca obiekt MongoDatabase, ale zgodnie z API nie ma metody wykonywania funkcji. Muszę się dowiedzieć, czy używa on niezamężnej metody/klasy. –

+0

Edytowałem moje pytanie z większą informatoną. –

+0

Przyjąłem twoją odpowiedź tak, jak ty pomogłeś. Ale zdecydowałem się wdrożyć moją funkcję w Javie. –

0

postanowiłem ten sam problem w następujący sposób:

uruchomić komendę w mongoShell stworzyć moje przechowywanych funkcji JavaScript:

db.system.js.save(
    { 
    _id: "echoFunction" , 
    value : function(x1) { return x1; } 
    } 
) 

db.system.js.save(
    { 
    _id : "myAddFunction" , 
    value : function (x, y){ return x + y; } 
    } 
); 


db.system.js.save(
    { 
    _id: "fullFillCollumns" , 
    value : function() { 
     for (i = 0; i < 2000; i++) { 
     db.numbers.save({num:i}); } } 
    } 
); 

Aby wykonać to funkcje ze sterownikiem MongoDB Java:

MongoClient mongoClient = new MongoClient(); 
MongoDatabase db = mongoClient.getDatabase("databaseName"); 

db.runCommand(new Document("$eval", "fullFillCollumns()")); 

Document doc1 = db.runCommand(new Document("$eval", "echoFunction(5)")); 
System.out.println(doc1); 

Document doc2 = db.runCommand(new Document("$eval", "myAddFunction(5,8)")); 
System.out.println(doc2); 

Widzę, że numery kolekcji zostały utworzone i wypełnione wartościami. W konsoli IntellijIdea widzę:

Document{{retval=5.0, ok=1.0}} 
Document{{retval=13.0, ok=1.0}} 
3

Możesz zrobić to wszystko za pomocą sterownika Java.

MongoClient mongoClient = new MongoClient(); 
MongoDatabase mdb = mongoClient.getDatabase("TestDB"); 

/* run this <code snippet> in bootstrap */ 
BsonDocument echoFunction = new BsonDocument("value", 
     new BsonJavaScript("function(x1) { return x1; }")); 

BsonDocument myAddFunction = new BsonDocument("value", 
     new BsonJavaScript("function (x, y){ return x + y; }")); 

mdb.getCollection("system.js").updateOne(
     new Document("_id", "echoFunction"), 
     new Document("$set", echoFunction), 
     new UpdateOptions().upsert(true)); 

mdb.getCollection("system.js").updateOne(
     new Document("_id", "myAddFunction"), 
     new Document("$set", myAddFunction), 
     new UpdateOptions().upsert(true)); 

mdb.runCommand(new Document("$eval", "db.loadServerScripts()")); 
/* end </code snippet> */ 

Document doc1 = mdb.runCommand(new Document("$eval", "echoFunction(5)")); 
System.out.println(doc1); 

Rezultatem jest również:

Document{{retval=5.0, ok=1.0}}