1

I have a mongo db script in a js file:

query.js

//conn = new Mongo();
//db = conn.getDB("dbName");
functionFoo = function (arg){
    //----process arg
}

also I have an array of args known as args_array, (that I fetch from database using mongoid) for which I want to do something like this:

args_array.each do |arg|
   //some how call functionFoo(arg) from the query.js file
end

is this possible in rails?

I am able to execute the file from terminal but I want to wrap it in my application so that I can use it from rails console.

5
  • It looks like you're trying to call JavaScript queries directly in Ruby; you'd have to pass through a JavaScript interpreter (eg. the mongo shell) in order for these to make sense. What's your actual requirement -- do you just need to evaluate a list of saved queries in a file, or do they have to be JavaScript functions? Commented May 26, 2015 at 20:44
  • I have a javascript function which updates loads of documents, its not a list of queries.. Had it been an independent script, I could have done it using exec may be, but the function takes an argument from a ruby array, this is my exact problem Commented May 27, 2015 at 6:20
  • You can still pass arguments with Ruby's exec and define these for your mongo shell script with --eval ... . However, rather than using a mix of JavaScript + Ruby, I think it would be much more sensible to write all the functions in one language. You could either get the query arguments you need via JavaScript, or port your existing JavaScript functions to Ruby. Commented May 27, 2015 at 16:45
  • Ok thanks I will try that... Actually writing query in ruby will affect the time complexity in comparison to query written in javascript. right? As the query is long so I wrote the main part of query in javascript at the same time trying to make it accessible through the rails console somehow. Commented May 28, 2015 at 6:49
  • I'm not clear what you mean by time complexity of queries . If you are writing functions to run in the mongo shell, those are still executed on the client side similar to queries in Ruby. Spawning mongo shells to run functions & queries from the Rails console adds complexity & overhead if you could run those queries directly via the Ruby driver. The Ruby driver will also have richer I/O methods compared to the mongo shell. It would help if you can post an actual example of a function & query you are running and describe the intended goal. There is likely a more direct approach. Commented May 28, 2015 at 8:08

2 Answers 2

2

I know this old question but in case you still need answer or any one else. This answer works with gem mongo ~> 2.3.

The key to answer you do not need mongoid in this case - in my case I use it for rails model, so I use mongoid (5.1.0) only to get DB connection db = Mongoid.default_client.database - or you can get/create database using mongo gem.

To execute javascript on database you need to call command method db.command({ eval: 'js' }) or db.command({ eval: 'function(n){return db.projects.find({name: n}).toArray();}', args: ['beskhai'], nolock: true })

To get the result you can call .documents db.command(...).documents, The return is a hash {retval: it will be return of you script, ok: is 1 if success} the return object of command call is [Mongo::Operation::Result] https://github.com/mongodb/mongo-ruby-driver/blob/master/lib/mongo/operation/result.rb.

Sign up to request clarification or add additional context in comments.

Comments

1

I'm using MongoID 6.0.1, and it easy to query everything you want like that:

    db ||= Mongoid.default_client.database
    f = """
    functionFoo = function (arg){
    //----process arg
    }
    """
    result = db.command({:$eval => f, args: [arg1, arg2, ...arg_n], nolock: true})
    @result_data = result.first['retval']

It not only a function, just every thing you want to do with command. My example is:

db ||= Mongoid.default_client.database
f = """
var collectionNames = db.getCollectionNames(), stats = [];
collectionNames.forEach(function (n) { stats.push(db[n].stats()); });
stats = stats.sort(function(a, b) { return b['size'] - a['size']; });
return stats;
"""
result = db.command({:$eval => f, args: [], nolock: true})
@result_data = result.first['retval']

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.