question about $ in key names, like $schema and $ref

2,787 views
Skip to first unread message

Ognian

unread,
Mar 21, 2013, 3:34:22 PM3/21/13
to json-...@googlegroups.com
Hello,
I'm just trying to put a json schema into mongodb.
In mongo $ and . are reserved chars and they are not allowed in key names
So I have a problem putting $schema or $ref inside the db.
Of course I can translate them when putting into the db an translate them back....

Don't kill me about this suggestion, but since it is a draft wouldn't it be possible to change $ref to _ref or __ref or something like this or at least add this possibility too...

Just an idea
Ognian

Geraint

unread,
Mar 22, 2013, 5:15:50 AM3/22/13
to json-...@googlegroups.com
Interesting problem...

I'm afraid "$ref" is not changing any time soon.  That's actually a separate standard (JSON Reference) which we simply use.  JSON Reference is quite mature now, and unlikely to budge.  Given that "$ref" is fixed (and the other problems it would cause), I think we're also unlikely to change "$schema".

I'm genuinely surprised that MongoDB has no way of escaping such characters.  MySQL has reserved characters as well (such as the backtick `, used for quoting names), but even these are escapable (using a double-backtick, e.g. Table`Name  ->  `Table``Name`).  Is there a way to raise this with MongoDB?

I had a look at the MongoDB site, and their FAQ suggested using a substitute value (http://docs.mongodb.org/manual/faq/developers/#faq-dollar-sign-escaping), so that's probably the way to go for now.

Sorry we can't be of more help!

Geraint

unread,
Mar 22, 2013, 5:24:12 AM3/22/13
to json-...@googlegroups.com
I've just skimmed through what MongoDB actually uses these $-names for, and one of the uses seems to be special representations of certain data types:


For example, to encode a date, you would say: {"$date": <UTC epoch milliseconds>}

This actually seems fairly close to the use of "$schema", which identifies the particular format of the JSON Schema.  It's a shame they don't have JSON Schema support, actually - otherwise you could do queries like "get me this schema and all schemas it relies upon", or "get me any schema that includes this schema via using $ref", which otherwise require calculating and storing a whole bunch of meta-data yourself...

Ognian

unread,
Mar 22, 2013, 12:50:58 PM3/22/13
to json-...@googlegroups.com
OK, I've implemented the suggested workaround, (see below),
but it looks like this potentially could cause big misunderstanding since these two $ signs look pretty the same.... 

                        function mongoFixDollar(obj) {
                            // mongo forbids $ and . in keys so we use as recommended different unicode chars which look similar...
                            var ret = {};
                            for (var key in obj) {
                                ret[key.replace("$", "$").replace(".", ".")] = obj[key];
                                if (typeof obj[key] === "object")
                                    mongoFixDollar(obj[key]);
                            }
                            return ret;
                        };

Ognian

Geraint Luff

unread,
Mar 22, 2013, 1:11:23 PM3/22/13
to json-...@googlegroups.com
Yeah, it's a bit unfortunate - you have to be sure that every section of code that gets things *out* of the database does the same substitution backwards.

I don't think it's just JSON Schema that's the problem - even if we did change those keywords, there are still plenty of other data formats that use JSON Reference, and you'd hit trouble with them as well.

--
You received this message because you are subscribed to a topic in the Google Groups "JSON Schema" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/json-schema/Nzh0sQP0uxQ/unsubscribe?hl=en-US.
To unsubscribe from this group and all its topics, send an email to json-schema...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Ognian

unread,
Mar 22, 2013, 4:46:35 PM3/22/13
to json-...@googlegroups.com
Ups,
and the first implementation  of my "fixDollar" has a js beginner error; typeof is not what I tought ....
So here is the correct way to do it:

                        var toType = function (obj) {
                            return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
                        };

                        var mongoFixDollar = function (obj) {
                            // mongo forbids $ and . in keys so we use as recommended different unicode chars which look similar...
                            var ret = {};
                            for (var key in obj) {
                                ret[key.replace("$", "$").replace(".", ".")] = (toType(obj[key]) === "object") ? mongoFixDollar(obj[key]) : obj[key];
                            }
                            return ret;
                        };

magically this fixes my jsonary problem too...

Austin Wright

unread,
Mar 24, 2013, 8:42:25 AM3/24/13
to json-...@googlegroups.com
It's worth noting that these restrictions are only enforced at the library level. I'm perfectly capable of inserting keys with . and, I believe, $ in my database.

Nonetheless, I do escape my keys, using percent-encoding, but only for the three [$.%] characters, or, when a library calls for the $ character, I use the @ character instead (sometimes vice-versa too, since the $ character doesn't require quotes in ECMAScript, unlike @).

So there's multiple ways to deal with it.

But I agree it's rather silly it doesn't allow the full range of JSON.
Reply all
Reply to author
Forward
0 new messages