1

I am using nodejs and mongoose.

Another function will provide me with a raw mongodb query as string and I need to execute that directly on the database and pass back the result.

What I need is similar to executing mysql query string on a mysql connection object but I don't know how to do that for mongo. Please help.

I don't know the model and the query can be just anything. That is the main problem. even something like show collections is valid here.

I know that makes it susceptible to SQL injection but that is not an issue in this case so don't worry about that.

Thanks in advance.

5
  • 1
    can you show a sample of the query string you will get? Commented Feb 22, 2014 at 4:10
  • String can be like: show collctions; db.users.findOne(); db.zips.find({"city" :"BRENT"} ); insert, delete, update and so on. and I will dump the result back. Commented Feb 22, 2014 at 4:19
  • 1
    "even something like show collections is valid here." no it's not , the nodejs mongodb driver is not the mongodb console application. The driver has an specific API. You cant eval random commands with it. The only thing you can do is stream data from / to the original mongo console application through nodejs if you really want to do that. Commented Feb 22, 2014 at 4:54
  • ok so I'll leave console commands for now. But how about any random query like db.users.findOne(); db.zips.find({"city" :"BRENT"} ); etc. ? I think the problem is that I won't know the schema... @mpm thanks for pointing out API based restriction. I think I can use the spawning option for those commands. Commented Feb 22, 2014 at 5:02
  • @mpm is speaking common sense. You definitely do not want to pass in things as raw as this. Nor are they going to be valid for any access API. If your need is to have some custom "over the wire" sequence then consider the answer I have given. Or anyone else's suggestion along a similar line. Commented Feb 22, 2014 at 5:02

2 Answers 2

1

If i understand correctly, you are trying to take mongo commands from some interface (webpage or something), run it on server and send back the results.

So in essence you are trying to simulate mongo shell. One approach could be to use mongo's --eval command line parameter.

  1. For every request of this type, spawn a new node child, run mongo --eval <your command in quotes> and keep listening for stdout event from child in the parent (child.stdout.on('data', cb)), and dump the resulting data to the client.

  2. You can also pass a javascript file as a parameter to mongo command. That means you can dump your mongo queries to a temporary js file, execute the file in a child process with mongo command and dump back the results.

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

3 Comments

Well spawning a child could be done. But I already have a connection object created. Wouldn't it be better to just use the connection object to execute the query string just like the way one does in case of mysql ?
mongodb =/= mysql there is no query as strings in mongodb.What Mukesh is suggesting is to use the mongo cli in nodejs.
mongo query syntax is nowhere near as expressive as sql. Hence multiple ways to different things. If you were to write a parser mongo queries, there will be a lot of if else conditions. Not so for sql.
0

I know there is an answer here to use eval() in some form, and I see in your added comments what you expect the string information would be. But I would if I may strongly discourage you from doing that.

Well actually you are being asked to spawn a mongo shell, which while novel, is probably not going to be very practical.

But before you ever arrive at the inner usage of eval() then I would suggest to please read up on the web and take heed of the warnings.

In the form I have linked to, this is going to fire off arbitrary JavaScript to your server and run the results there. There are big issues with security, and locking and much more related to taking this approach.

Rather yet, how about creating your own API layer that will take the serialized arguments. So instead of storing the whole command in a string, just call an endpoint for say find() and process the arguments.

{ 
    collections: <collection>,
    query: <query_condition>,
    project: <projection>,
    options: <options>
}

Or whatever structure suits you. And there you even have a JSON form in your string that you can use to deserialize into data for your code.

This would to me seem a more logical approach, and safer, then directly sending commands in the form you proposed. And as such is probably more analogous to sending a SQL statement over the wire as text.

1 Comment

I think you miss the point. He says in the question that he understands the risks and wants to know how to do it anyway. This doesn't really answer the question.

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.