Using tag for field result in wrong field name

152 views
Skip to first unread message

bsr

unread,
Apr 14, 2011, 7:53:18 AM4/14/11
to mgo-users
Hello,

If I tag my struct fields, mgo uses the tag instead of the field name
to persist the object

say,

type AA struct {
B string "hello"
}

if you persist this object,

{
"_id": ObjectId("4da6dece7d6g69a25ad1dc9d"),
"hello": "dfswesw"
}

I would expect

{
"_id": ObjectId("4da6dece7d6g69a25ad1dc9d"),
"b": "dfswesw"
}

this issue is really blocking me. Any help appreciated.

thanks.

Dmitry Chestnykh

unread,
Apr 14, 2011, 8:17:49 AM4/14/11
to mgo-...@googlegroups.com
That's actually a feature of gobson. If not for it, you won't be able to have _id in a struct, for example:

type Record struct {
     Id bson.ObjectId "_id"
}

and it enables conditional flag "/c":

type Record struct {
    Sensitive string "/c"
}

means that if Sensitive is zero (empty string in this case), it won't be serialized.

To avoid this, I think you can manually convert your struct to map and serialize it.

-Dmitry

Dmitry Chestnykh

unread,
Apr 14, 2011, 8:19:31 AM4/14/11
to mgo-...@googlegroups.com
BTW, that's the feature of pretty much every serialization package for Go, i.e. JSON: http://golang.org/pkg/json/#Marshal
Why do you want to tag struct fields if not for serialization?

-Dmitry

bsr

unread,
Apr 14, 2011, 8:35:07 AM4/14/11
to mgo-users
Thanks Dmitry for quick reply...

I wanted to tag my domain fields so I can use it for UI processing.
Say a field needs to be rendered as textarea instead of textfield
(sure I could use template in this case). Another, say depending on
the tag I could do validation on the field. something like, required
tag does a validation whether the value is set.

thanks for the pointer to Json. it says,

If the struct field has a non-empty tag consisting of only Unicode
letters, digits, and underscores, that tag will be used as the name
instead. Only exported fields will be encoded.

I am not sure how "/c" would be treated by Json then (do they really
mean letter or char "/" also comes in the above classification) .
Similar way, can i use any special character (say ";" ) to skip
treating the tag as field name in mgo and Json.

thanks again.
bsr

Dmitry Chestnykh

unread,
Apr 14, 2011, 8:48:34 AM4/14/11
to mgo-...@googlegroups.com
"/c" for zero fields is, I think, Gustavo's invention for bson serializer, so it's not used in json package.
I'm not sure about special characters.

Seems like your use of tags collides with tag usage for serialization, so one of them has to go. You can make a function to serialize a struct into a map, and then pass the map to mgo.

-Dmitry

Gustavo Niemeyer

unread,
Apr 14, 2011, 8:49:14 AM4/14/11
to mgo-...@googlegroups.com, bsr
> I wanted to tag my domain fields so I can use it for UI processing.
> Say a field needs to be rendered as textarea instead of textfield
> (sure I could use template in this case). Another, say depending on
> the tag I could do validation on the field. something like, required
> tag does a validation whether the value is set.

It feels like this is going a bit too far with the use of tags. If
you want to do field validation, you'll want more metadata associated,
so some richer representation would be interesting.

(...)


> I am not sure how "/c" would be treated by Json then (do they really
> mean letter or char "/" also comes in the above classification) .

As I mentioned previously, "/c" was a new concept introduced by
gobson, so JSON doesn't do anything with it at the moment.

> Similar way, can i use any special character (say ";" ) to skip
> treating the tag as field name in mgo and Json.

No, that won't work with gobson. We can introduce a flag to signal
that the text preceding the "/" should not be treated as a field name,
maybe. I'd like to see more details of how you'd use that first,
though.

--
Gustavo Niemeyer
http://niemeyer.net
http://niemeyer.net/blog
http://niemeyer.net/twitter

bsr

unread,
Apr 14, 2011, 8:58:14 AM4/14/11
to mgo-users
Yes, one thing I confirmed is that you can bypass Json processing by
using a any special char. The below program work as intended.

Well whatever the case, I don't think it is a good practice to block
the usage of tag .. It make sense to say "/" is reserved for mgo
rather than there is no freedom for the user of mgo (do you think that
practical for everyone).

Gustavo, me being a novice user, can you please explain a bit on "If
you want to do field validation, you'll want more metadata
associated". I don't know any other way t associate metadata to struct
field.

thanks .


package main

import ("json"; "log"; "os")

func main() {
enc := json.NewEncoder(os.Stdout)
v := struct {
A string "/hello"
B string
}{"hello", "world"}


if err := enc.Encode(&v); err != nil {
log.Println(err)

Gustavo Niemeyer

unread,
Apr 14, 2011, 9:11:11 AM4/14/11
to mgo-...@googlegroups.com, bsr
> Yes, one thing I confirmed is that you can bypass Json processing by
> using a any special char. The below program work as intended.

Yes, JSON will only work with letters, digits, and underscore. We
can't do just that in BSON, though. There are many other valid
characters which are commonly used (e.g. $, -, etc) in key fields.

Not sure if we want to restrict the set of valid characters, will have
to think about it a bit more.

> Well whatever the case, I don't think it is a good practice to block
> the usage of tag .. It make sense to say "/" is reserved for mgo
> rather than there is no freedom for the user of mgo (do you think that
> practical for everyone).

We're not blocking but rather making good use of them. There's a
distinction there.

> Gustavo, me being a novice user, can you please explain a bit on "If
> you want to do field validation, you'll want more metadata
> associated". I don't know any other way t associate metadata to struct
> field.

Right, you'd have to do that with actual logic in your own
application. When doing validation, you'll want to start to associate
things like text size, text field length, etc. This is too much for
tags, IMO.

bsr

unread,
Apr 14, 2011, 9:27:35 AM4/14/11
to mgo-users
Thanks for your response.

I would say, any good library should be non invasive .. A tag in go,
which gives similar functionality as annotation in Java, needs to be
processed by the intended party. As a user of mgo, I am constrained
not to use tags since it interfere with mgo. This is a concern as I
evolve my program, as I cannot foresee whether I ever need tag for
some special purpose. I think it is more appropriate for me to tag
anything mgo related with "/" (/_id , /c, /customfieldname etc).

thanks.

Dmitry Chestnykh

unread,
Apr 14, 2011, 10:08:39 AM4/14/11
to mgo-...@googlegroups.com
I think you're trying to assign too much meaning to tags. To me, a tag is nothing more than a special name for a structure field, that is not limited by the language identifier rules.

I don't know Java, but from what I read, Java's annotation is very different concept.

-Dmitry

Ralph Stevens

unread,
Apr 14, 2011, 10:29:41 AM4/14/11
to mgo-...@googlegroups.com
I don't see anything wrong with the way that bsr wants to use tags. The problem is that there can be conflicting uses for struct field tags. See http://code.google.com/p/go/issues/detail?id=1520 for discussion of a similar issue.  This is something that Go should fix.

bsr

unread,
Apr 14, 2011, 10:32:01 AM4/14/11
to mgo-users
I agree, I should not use tag for things it is not intended for. may
be giving validation options in tag is one among them.
But please tell me, do you agree that it is the user who should decide
on it, or mgo should impose it.

see the section from go spec.

there is no mention of "special name" or any meaning to it, rather
than just a meta data useful while reflection processing. In that
example protocol buffer has it's own meaning for the tag. So, I think
your first answer about mapping domain object to a map prior to
persisting is probably the only option for me. I wish I could avoid
this indirection.

thanks for ur time for responding to me.
bsr.

A field declaration may be followed by an optional string literal tag,
which becomes an attribute for all the fields in the corresponding
field declaration. The tags are made visible through a reflection
interface but are otherwise ignored.
// A struct corresponding to the TimeStamp protocol buffer.
// The tag strings define the protocol buffer field numbers.
struct {
microsec uint64 "field 1"
serverIP6 uint64 "field 2"
process string "field 3"

bsr

unread,
Apr 14, 2011, 10:41:46 AM4/14/11
to mgo-users
Thanks I am posting a similar message in go mailing list...

On Apr 14, 10:29 am, Ralph Stevens <dbd...@live.com> wrote:
> I don't see anything wrong with the way that bsr wants to use tags. The
> problem is that there can be conflicting uses for struct field
> tags. Seehttp://code.google.com/p/go/issues/detail?id=1520for discussion

Dmitry Chestnykh

unread,
Apr 14, 2011, 10:47:31 AM4/14/11
to mgo-...@googlegroups.com
After seeing what goprotobuf do with tags, I no longer believe my own words.

Still, what if you decide to later use protocol buffers? You can no longer use the same structure for both your app and protocol buffers. The same is true if you'll use JSON.

The use of tags is documented in gobson package. Maybe, to be clear about it, mgo should also mention it in docs?

-Dmitry

Ralph Stevens

unread,
Apr 14, 2011, 10:56:28 AM4/14/11
to mgo-...@googlegroups.com
The conflicting uses of tags in other packages show that the problem is with Go and not with the way that bsr wants to use tags.

bsr

unread,
Apr 14, 2011, 11:07:39 AM4/14/11
to mgo-users
I think Dmitry is right in saying that it is the user's responsibility
to tag the field as intended by the library to use it. So, multiple
libraries use it differently, we may have to remap it accordingly. In
case of mgo, I wish there is a way to specify tags intended for mgo as
almost all the time you want your domain object to be persisted. It
makes easier, as the user of the library, not to map/reset any custom
tags before passing to mgo. It is more of convenience and performance.

thanks.
bsr.

Gustavo Niemeyer

unread,
Apr 14, 2011, 11:19:04 AM4/14/11
to mgo-...@googlegroups.com, bsr
> I think Dmitry is right in saying that it is the user's responsibility
> to tag the field as intended by the library to use it. So, multiple
> libraries use it differently, we may have to remap it accordingly. In
> case of mgo, I wish there is a way to specify tags intended for mgo as
> almost all the time you want your domain object to be persisted. It

Yes, I understand your point, and I'll fix it somehow. Just thinking
about the right approach.

bsr

unread,
Apr 14, 2011, 11:36:07 AM4/14/11
to mgo-users
thanks Gustavo. no hurry, as I decided to use the tag differently than
originally thought, thanks to this discussion.
But it will give peace of mind knowing I have the flexibility to use
tags as I wanted in the future.
thanks for the consideration,
bsr.
Reply all
Reply to author
Forward
0 new messages