BSON.deserialize(query)

383 views
Skip to first unread message

Kevin Fairclough

unread,
Jan 27, 2014, 6:20:16 AM1/27/14
to mongod...@googlegroups.com
Hi

In my REST interface I accept mongoDB queries as JSON strings.  How do I convert them to official mongoDB query objects?

Original I was using JSON.parse but this doesn't seem to work with queries such as the LIKE query as it isn't valid JSON and if I make it valid by adding quotes then mongoDB's find using the query doesn't return anything.
I've tried BSON.deserialize(query) but this throws "invalid token :" error or Error: corrupt bson message.

My query string looks like this: '"name":"\Bob\"', mongoDB is expecting an object {name: \Bob\}

Kind Regards
Kevin


Oisin Hurley

unread,
Jan 27, 2014, 9:12:09 AM1/27/14
to Kevin Fairclough, mongod...@googlegroups.com

> In my REST interface I accept mongoDB queries as JSON strings. How do I convert them to official mongoDB query objects?

JSON will lose the type information that is required to make the query - it doesn’t have Time-like types, or Regex types, just strings and numbers, hashes and arrays. To make a functional query, you will need to fill in the type data where the query is taking place, on the server.

Sending JSON from the client to be interpreted on the server can mean that the server is subject to potential denial of service - a badly-formed query on the client could cause an issue on the server. It would be a safer approach to have a specific REST endpoint that takes a parameter, which the server parses to a Ruby regex (I assume you are using Ruby from the JSON syntax you were using). Then you can use that regex as a sensible typed object to the Mongo binding.

 --oh

--
Oisin Hurley
@oisin

Kevin Fairclough

unread,
Jan 27, 2014, 9:38:36 AM1/27/14
to mongod...@googlegroups.com, Kevin Fairclough
Thanks for your reply.   I had a few typos in my original post.

My REST interface is on Node.js in Javascript.

My query is coming via the URL as ?query={"name":"/Bob/"} ***note original typo***

I figured out that I had to parse this to JSON then serialize to BSON using the following:

try{
    query = JSON.parse(query);
    query = BSON.serialize(query);
} catch(err) {
    console.log(err);
}

This works for queries such as the following (orderCount > 4):
query={%22orderCount%22:{%22$gt%22:4}}

However I still cannot get the LIKE query to work.

Regards
Kevin

Oisin Hurley

unread,
Jan 27, 2014, 10:25:00 AM1/27/14
to Kevin Fairclough, mongod...@googlegroups.com, Kevin Fairclough
I wasn’t clear enough in my original mail.

?query={"name":"/Bob/“}

In this query, “/Bob/“ is a string. If it were /Bob/, then it would be regex, but JSON doesn’t have a regex type, so /Bob/ would be illegal JSON. Once the JSON is parsed, it will produce a map will have “name” as a key, and “/Bob/“ as it’s value - it will be a string. The server will query using this string, and not a regex as you intended.

What you might try instead is

?query={“name”: { “$regexp” : “/Bob”}}

which will remove the ambiguity that is causing the issue.

Make sure to validate the queries that the client is sending to the server.

Kevin Fairclough

unread,
Jan 27, 2014, 11:34:59 AM1/27/14
to mongod...@googlegroups.com, Kevin Fairclough
Thanks Oisin

I have tried this and still cannot get the results to return.

?query={“name”: { “$regex” : “/Bob”}}

It looks like the quotes are still being considered by the query
I've also tried ?query={“name”: { “$regex” : “/^B/”}} and still no rows.

Regards
Kevin

Oisin Hurley

unread,
Jan 28, 2014, 4:47:12 AM1/28/14
to Kevin Fairclough, mongod...@googlegroups.com, Kevin Fairclough

> ?query={“name”: { “$regex” : “/Bob”}}
>
> It looks like the quotes are still being considered by the query
> I've also tried ?query={“name”: { “$regex” : “/^B/”}} and still no rows.

Took the time to test it and having the regex in quotes once again
causes the driver to interpret as a string - it needs the regex to
look like

db[‘people'].find({name : { $regex : /^B/}})

You’ll have to take a different approach. FWIW, I would have a specific
resource that takes the query string, and the implementation of that
resource will convert the string to a regex type and apply the query.

Michael Grundy

unread,
Jan 30, 2014, 12:01:45 PM1/30/14
to mongod...@googlegroups.com, Kevin Fairclough
Try using a RexExp() constructor:

myRe = new RegExp("^B");
db[‘people'].find({name : { $regex : myRe}})
Reply all
Reply to author
Forward
0 new messages