Create your own id with Mgo

I am currently starting with GoLang and MongoDB. I am writing a small web app, blog more specific (this is like the first webapp I write when I try new languages). Everything works fine with MGO, even if I had problems at first. But now I would like to access each blog post (articles will be referred to as posts to stick with my models) separately. I could use ObjectID in the url. But it's damn ugly. For example:
mydomain.com/entries/543fd8940e82533995000002/


This is not convenient. I did a lot of research on the internet to find a suitable solution, because using any other database engine, I could just use the ID (and that would be fine).

Can anyone help me create a custom (public) ID that will automatically increment when I insert a new record and what can I use in the URL?

Here is my model code:

package models

import (
    "time"

    "labix.org/v2/mgo"
    "labix.org/v2/mgo/bson"
)

type (
    Entries []Entry
    Entry   struct {
        ID      bson.ObjectId `bson:"_id,omitempty"`
        Title   string        `bson:"title"`
        Short   string        `bson:"short"`
        Content string        `bson:"content"`
        Posted  time.Time     `bson:"posted"`
    }
)

// Insert an entry to the database
func InsertEntry(database *mgo.Database, entry *Entry) error {
    entry.ID = bson.NewObjectId()
    return database.C("entries").Insert(entry)
}

// Find an entry by id
func GetEntryByID(database *mgo.Database, id string) (entry Entry, err error) {
    bid := bson.ObjectIdHex(id)
    err = database.C("entries").FindId(bid).One(&entry)
    return
}

// Retrieves all the entries
func AllEntries(database *mgo.Database) (entries Entries, err error) {
    err = database.C("entries").Find(nil).All(&entries)
    return
}

// Retrieve all the entries sorted by date.
func AllEntriesByDate(database *mgo.Database) (entries Entries, err error) {
    err = database.C("entries").Find(nil).Sort("-posted").All(&entries)
    return
}

// Counts all the entries.
func CountAllEntries(database *mgo.Database) (count int, err error) {
    count, err = database.C("entries").Find(nil).Count()
    return
}

      

+3


source to share


1 answer


As you know, _id is a required field that is automatically populated by the driver when you don't install it. This is the behavior you have in your current application / code. You can find information about this type and its generation here: http://docs.mongodb.org/manual/reference/object-id/

However, you can create your own _id and set a value to anything that makes sense for your company.

This is why I don't understand the following statement:

I did a lot of research on the internet to find a suitable solution, because using any other database engine, I could just use the ID (and that would be nice).

You can use whatever value you want, as soon as it is unique to your collection.

About auto-increment MongoDB does not provide any auto-increment field, so you must implement it yourself and call the increment from your application.



For example, you create a new collection containing your "sequences / counters": (showing no shell commands)

{
  _id : "entry",
  sequence : 0
}

      

Then, when you need a new id for your document that you first updated, find and modify the document you created with a simple $ inc operation

var ret = db.counters.findAndModify(
          {
            query: { _id: "entry" },
            update: { $inc: { seq: 1 } },
            new: true
          }
   );

      

Then you can use the return value in the new document as _id.

This pattern is described here: http://docs.mongodb.org/manual/tutorial/create-an-auto-incrementing-field/

+2


source







All Articles