Hi folks,
I've been playing around with mongodb and mgo, both for the first
time, for a few days now. I had a question about how mgo marshalls
maps and how mongodb queries work. This may be a stupid question due
to my misunderstanding something fundamental about mongodb or mgo, and
if it is I apologize in advance.
Earlier today my go code had structures similar to the following:
type Monitor struct {
Name string `bson:"_id"`
Paths map[string]Node
}
type Node struct {
LastModified int64
Owner string
}
An example of the data in such a structure could be
Monitor{
Name: "monitor-v1",
Paths: map[string]Node{
"/a/1": Node{
LastModified: 1369180634
Owner: "jim.robinson"
},
"/b/2": Node{
LastModified: 1369180635
Owner: "jim.robinson"
}
"/c/3": Node{
LastModified: 1369180636
Owner: "jim.robinson"
}
},
}
As far as I can determine the mgo driver maps this in a
straight-forward fashion:
{
"_id": "monitor-v1"
"paths":{
"/a/1":{
"lastmodified": Long(1369180634),
"owner": "jim.robinson"
},
"/b/2":{
"lastmodified": Long(1369180635),
"owner": "jim.robinson"
}
"/c/3":{
"lastmodified": Long(1369180636),
"owner": "jim.robinson"
}
}
}
What I'm finding though, and perhaps this is a misunderstanding on my
part, is that mongodb doesn't make that data structure particularly
easy to work with when it comes to searching the subdocuments.
It appears to me as though one ends up dealing with path names like
"paths./a/1", which are effectively useless when it comes to either
querying for any paths with a given key or for querying the innermost
subdocuments.
Flipping through the mongodb documentation I see examples of data
structures somewhat similar to the above, but they use arrays. E.g.,
if we were to move the key of the map into such a structure we'd have
{
"_id": "monitor-v1"
"paths":[
{
"path": "/a/1"
"lastmodified": Long(1369180634),
"owner": "jim.robinson"
},
{
"path": "/b/2"
"lastmodified": Long(1369180635),
"owner": "jim.robinson"
},
{
"path": "/c/3"
"lastmodified": Long(1369180636),
"owner": "jim.robinson"
}
]
}
Here one could fairly easily run searches, e.g., against paths.path
and paths.lastmodified.
I ended up changing my code to something like
type Monitor struct {
Name string `bson:"_id"`
Paths []Node
}
type Node struct {
Path string
LastModified int64
Owner string
}
but this means that I now have to do things like traverse the Paths
slice if I'm looking to see whether or not a particular Path has been
defined.
I was wondering if mgo might offer any facilities for automatically
flattening maps into arrays when storing the data in mongodb, and
performing the reverse when loading the document? This may be naive,
but I was thinking that a tag like `,flatten="Path"` could be used as
a directive to flatten a map into an array of values, with the key
merged into the the values?
Am I missing something obvious?
Jim