Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Golang/mgo: How can I ask MongoDB to use current time in a field?

Tags:

mongodb

go

mgo

I have this struct that matches the types of a MongoDB collection I'm using:

type AppInstance struct {
    Id bson.ObjectId "_id,omitempty"
    Url string
    Priority int
    LastSeen string
}

I want the LastSeen field to hold the time of the last interaction with that particular app. So, the app registers itself setting current time (as a string).

What I would like is Mongo to dynamically set its own current time into that field when it inserts, just like MySQL's NOW() function would do.

I have this helper function:

func mongoNow() bson.JavaScript {
    return bson.JavaScript{Code: 
         "return (new Date()).ISODate('YYYY-MM-DD hh:mm:ss');"}
}

And I tried this:

c := mongoSession.DB("myapp").C("instances")
rand.Seed(time.Now().UnixNano())
err := c.Insert(
   struct{Id, Serial, Priority, Url, LastSeen interface{}}{ 
      Id: bson.NewObjectId(), 
      Url: getInformedHost() + ":" + getRunningPortString(), 
      Priority: rand.Int(), 
      LastSeen: mongoNow() }
)
checkError(err, "Could not register on MongoDB server.", 3)

the LastSeen field gets stored as a script instead of evaluated:

[_id] => MongoId Object (
    [$id] => 502d6f984eaead30a134fa10
)
[id] => MongoId Object (
    [$id] => 502d6f98aa443e0ffd000001
)
[priority] => 1694546828
[url] => 127.0.0.1:8080
[lastseen] => MongoCode Object (
    [code] => (new Date()).ISODate('YYYY-MM-DD hh:mm:ss')
    [scope] => Array (
    )
)

So, I think there are to questions:

First, how can I insert the current time?

Second, how can I get some javascript evaluated instead of inserted?

The answer to the second one could be enough to answer the first one, but it might as well not be.

like image 646
Sebastián Grignoli Avatar asked Aug 16 '12 23:08

Sebastián Grignoli


2 Answers

Don't store time as string. mgo supports time.Time which is like a Date object in Javascript:

type Event struct {
    Id    bson.ObjectId "_id,omitempty"
    Which string
    Date  time.Time
}

Insert an event that happened now:

e := Event{
    Which: "first event",
    Date: time.Now(),
}
c.Insert(e)
like image 163
Zippo Avatar answered Sep 23 '22 17:09

Zippo


In Mongo 2.6 you can do it natively with $currentDate operator.

db.users.update( { _id: 1 }, {
   $currentDate: {
     lastModified: true,
     lastModifiedTS: { $type: "timestamp" }
   },
   $set: { status: "D" }
})
like image 32
Salvador Dali Avatar answered Sep 23 '22 17:09

Salvador Dali