SCB-1500 decouple primitive.ObjectID
diff --git a/client/client_test.go b/client/client_test.go
index d92ca14..0d1af45 100644
--- a/client/client_test.go
+++ b/client/client_test.go
@@ -131,7 +131,7 @@
 				Endpoint: "http://127.0.0.1:30110",
 			})
 			It("should be 204", func() {
-				err := client3.Delete(context.TODO(), kv.ID.Hex(), "", WithProject("test"))
+				err := client3.Delete(context.TODO(), kv.ID.String(), "", WithProject("test"))
 				Ω(err).ShouldNot(HaveOccurred())
 			})
 		})
diff --git a/go.mod b/go.mod
index b4cffa8..3ad8c09 100644
--- a/go.mod
+++ b/go.mod
@@ -16,6 +16,6 @@
 	github.com/urfave/cli v1.20.0
 	github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c // indirect
 	github.com/xdg/stringprep v1.0.0 // indirect
-	go.mongodb.org/mongo-driver v1.0.0
+	go.mongodb.org/mongo-driver v1.0.3
 	gopkg.in/yaml.v2 v2.2.1
 )
diff --git a/pkg/model/mongodb_doc.go b/pkg/model/mongodb_doc.go
index 5e89975..2879154 100644
--- a/pkg/model/mongodb_doc.go
+++ b/pkg/model/mongodb_doc.go
@@ -17,25 +17,27 @@
 
 package model
 
-import "go.mongodb.org/mongo-driver/bson/primitive"
+import (
+	"github.com/apache/servicecomb-kie/server/id"
+)
 
 //LabelDoc is database struct to store labels
 type LabelDoc struct {
-	ID       primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
-	Labels   map[string]string  `json:"labels,omitempty"`
-	Revision int                `json:"revision,omitempty"`
-	Domain   string             `json:"domain,omitempty"` //tenant info
-	Project  string             `json:"project,omitempty"`
+	ID       id.ID             `json:"_id,omitempty" bson:"_id,omitempty"`
+	Labels   map[string]string `json:"labels,omitempty"`
+	Revision int               `json:"revision,omitempty"`
+	Domain   string            `json:"domain,omitempty"` //tenant info
+	Project  string            `json:"project,omitempty"`
 }
 
 //KVDoc is database struct to store kv
 type KVDoc struct {
-	ID        primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
-	LabelID   string             `json:"label_id,omitempty" bson:"label_id,omitempty"`
-	Key       string             `json:"key"`
-	Value     string             `json:"value,omitempty"`
-	ValueType string             `json:"value_type,omitempty" bson:"value_type,omitempty"` //ini,json,text,yaml,properties
-	Checker   string             `json:"check,omitempty"`                                  //python script
+	ID        id.ID  `json:"_id,omitempty" bson:"_id,omitempty"`
+	LabelID   string `json:"label_id,omitempty" bson:"label_id,omitempty"`
+	Key       string `json:"key"`
+	Value     string `json:"value,omitempty"`
+	ValueType string `json:"value_type,omitempty" bson:"value_type,omitempty"` //ini,json,text,yaml,properties
+	Checker   string `json:"check,omitempty"`                                  //python script
 
 	Labels   map[string]string `json:"labels,omitempty"` //redundant
 	Domain   string            `json:"domain,omitempty"` //redundant
@@ -45,10 +47,10 @@
 
 //LabelRevisionDoc is database struct to store label history stats
 type LabelRevisionDoc struct {
-	ID       primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
-	LabelID  string             `json:"label_id,omitempty"  bson:"label_id,omitempty"`
-	Labels   map[string]string  `json:"labels,omitempty"`
-	Domain   string             `json:"-"`
-	KVs      []*KVDoc           `json:"data,omitempty"`
-	Revision int                `json:"revision"`
+	ID       id.ID             `json:"_id,omitempty" bson:"_id,omitempty"`
+	LabelID  string            `json:"label_id,omitempty"  bson:"label_id,omitempty"`
+	Labels   map[string]string `json:"labels,omitempty"`
+	Domain   string            `json:"-"`
+	KVs      []*KVDoc          `json:"data,omitempty"`
+	Revision int               `json:"revision"`
 }
diff --git a/server/id/id.go b/server/id/id.go
new file mode 100644
index 0000000..b48556b
--- /dev/null
+++ b/server/id/id.go
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package id
+
+import (
+	"fmt"
+	"go.mongodb.org/mongo-driver/bson/bsontype"
+	"go.mongodb.org/mongo-driver/bson/primitive"
+	"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
+)
+
+//ID decouple mongodb
+type ID string
+
+//UnmarshalBSONValue is implement
+func (id *ID) UnmarshalBSONValue(t bsontype.Type, raw []byte) error {
+	if t == bsontype.ObjectID && len(raw) == 12 {
+		var objID primitive.ObjectID
+		copy(objID[:], raw)
+		*id = ID(objID.Hex())
+		return nil
+	} else if t == bsontype.String {
+		if str, _, ok := bsoncore.ReadString(raw); ok {
+			*id = ID(str)
+			return nil
+		}
+	}
+
+	return fmt.Errorf("unable to unmarshal bson id — type: %v, length: %v", len(raw), t)
+}
+
+//String return string
+func (id ID) String() string {
+	return string(id)
+}
diff --git a/server/id/id_test.go b/server/id/id_test.go
new file mode 100644
index 0000000..aa517f8
--- /dev/null
+++ b/server/id/id_test.go
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package id_test
+
+import (
+	"github.com/apache/servicecomb-kie/server/id"
+	"github.com/stretchr/testify/assert"
+	"go.mongodb.org/mongo-driver/bson"
+	"go.mongodb.org/mongo-driver/bson/primitive"
+	"testing"
+)
+
+func TestID_MarshalBSONValue(t *testing.T) {
+	type Obj struct {
+		ID id.ID `bson:"label_id,omitempty"`
+	}
+
+	o := new(Obj)
+	o.ID = id.ID(primitive.NewObjectID().Hex())
+
+	b, err := bson.Marshal(o)
+	assert.NoError(t, err)
+	t.Log(b)
+
+	o2 := new(Obj)
+	err = bson.Unmarshal(b, o2)
+	assert.NoError(t, err)
+	t.Log(o2)
+}
diff --git a/server/service/mongo/history/dao.go b/server/service/mongo/history/dao.go
index f445be0..bd5db63 100644
--- a/server/service/mongo/history/dao.go
+++ b/server/service/mongo/history/dao.go
@@ -33,18 +33,14 @@
 //AddHistory increment labels revision and save current label stats to history, then update current revision to db
 func AddHistory(ctx context.Context,
 	labelRevision *model.LabelRevisionDoc, labelID string, kvs []*model.KVDoc) (int, error) {
-	c, err := session.GetClient()
-	if err != nil {
-		return 0, err
-	}
 	labelRevision.Revision = labelRevision.Revision + 1
 
 	//save current kv states
 	labelRevision.KVs = kvs
 	//clear prev id
-	labelRevision.ID = primitive.NilObjectID
-	collection := c.Database(session.Name).Collection(session.CollectionLabelRevision)
-	_, err = collection.InsertOne(ctx, labelRevision)
+	labelRevision.ID = ""
+	collection := session.GetDB().Collection(session.CollectionLabelRevision)
+	_, err := collection.InsertOne(ctx, labelRevision)
 	if err != nil {
 		openlogging.Error(err.Error())
 		return 0, err
@@ -54,7 +50,7 @@
 		openlogging.Error(fmt.Sprintf("convert %s,err:%s", labelID, err))
 		return 0, err
 	}
-	labelCollection := c.Database(session.Name).Collection(session.CollectionLabel)
+	labelCollection := session.GetDB().Collection(session.CollectionLabel)
 	_, err = labelCollection.UpdateOne(ctx, bson.M{"_id": hex}, bson.D{
 		{"$set", bson.D{
 			{"revision", labelRevision.Revision},
@@ -68,11 +64,7 @@
 }
 
 func getHistoryByLabelID(ctx context.Context, filter bson.M) ([]*model.LabelRevisionDoc, error) {
-	c, err := session.GetClient()
-	if err != nil {
-		return nil, err
-	}
-	collection := c.Database(session.Name).Collection(session.CollectionLabelRevision)
+	collection := session.GetDB().Collection(session.CollectionLabelRevision)
 	cur, err := collection.Find(ctx, filter, options.Find().SetSort(map[string]interface{}{
 		"revisions": -1,
 	}))
diff --git a/server/service/mongo/kv/kv_dao.go b/server/service/mongo/kv/kv_dao.go
index f9aef91..c5f534c 100644
--- a/server/service/mongo/kv/kv_dao.go
+++ b/server/service/mongo/kv/kv_dao.go
@@ -20,6 +20,7 @@
 import (
 	"context"
 	"fmt"
+	"github.com/apache/servicecomb-kie/server/id"
 	"github.com/apache/servicecomb-kie/server/service"
 	"github.com/apache/servicecomb-kie/server/service/mongo/label"
 	"github.com/apache/servicecomb-kie/server/service/mongo/session"
@@ -36,10 +37,6 @@
 //and increase revision of label
 //and insert key
 func createKey(ctx context.Context, kv *model.KVDoc) (*model.KVDoc, error) {
-	c, err := session.GetClient()
-	if err != nil {
-		return nil, err
-	}
 	r, err := label.GetLatestLabel(ctx, kv.LabelID)
 	if err != nil {
 		if err != service.ErrRevisionNotExist {
@@ -54,13 +51,13 @@
 	if r != nil {
 		r.Revision = r.Revision + 1
 	}
-	collection := c.Database(session.Name).Collection(session.CollectionKV)
+	collection := session.GetDB().Collection(session.CollectionKV)
 	res, err := collection.InsertOne(ctx, kv)
 	if err != nil {
 		return nil, err
 	}
 	objectID, _ := res.InsertedID.(primitive.ObjectID)
-	kv.ID = objectID
+	kv.ID = id.ID(objectID.Hex())
 	kvs, err := findKeys(ctx, bson.M{"label_id": kv.LabelID}, true)
 	//Key may be empty When delete
 	if err != nil && err != service.ErrKeyNotExists {
@@ -82,11 +79,7 @@
 //and increase revision of label
 //and updateKeyValue and them add new revision
 func updateKeyValue(ctx context.Context, kv *model.KVDoc) (int, error) {
-	c, err := session.GetClient()
-	if err != nil {
-		return 0, err
-	}
-	collection := c.Database(session.Name).Collection(session.CollectionKV)
+	collection := session.GetDB().Collection(session.CollectionKV)
 	ur, err := collection.UpdateOne(ctx, bson.M{"key": kv.Key, "label_id": kv.LabelID}, bson.D{
 		{"$set", bson.D{
 			{"value", kv.Value},
@@ -118,11 +111,7 @@
 }
 
 func findKV(ctx context.Context, domain string, project string, opts service.FindOptions) (*mongo.Cursor, error) {
-	c, err := session.GetClient()
-	if err != nil {
-		return nil, err
-	}
-	collection := c.Database(session.Name).Collection(session.CollectionKV)
+	collection := session.GetDB().Collection(session.CollectionKV)
 	ctx, _ = context.WithTimeout(ctx, opts.Timeout)
 	filter := bson.M{"domain": domain, "project": project}
 	if opts.Key != "" {
@@ -145,17 +134,13 @@
 	return cur, err
 }
 func findOneKey(ctx context.Context, filter bson.M) ([]*model.KVDoc, error) {
-	c, err := session.GetClient()
-	if err != nil {
-		return nil, err
-	}
-	collection := c.Database(session.Name).Collection(session.CollectionKV)
+	collection := session.GetDB().Collection(session.CollectionKV)
 	sr := collection.FindOne(ctx, filter)
 	if sr.Err() != nil {
 		return nil, sr.Err()
 	}
 	curKV := &model.KVDoc{}
-	err = sr.Decode(curKV)
+	err := sr.Decode(curKV)
 	if err != nil {
 		if err == mongo.ErrNoDocuments {
 			return nil, service.ErrKeyNotExists
@@ -168,11 +153,7 @@
 
 //deleteKV by kvID
 func deleteKV(ctx context.Context, hexID primitive.ObjectID, project string) error {
-	c, err := session.GetClient()
-	if err != nil {
-		return err
-	}
-	collection := c.Database(session.Name).Collection(session.CollectionKV)
+	collection := session.GetDB().Collection(session.CollectionKV)
 	dr, err := collection.DeleteOne(ctx, bson.M{"_id": hexID, "project": project})
 	//check error and delete number
 	if err != nil {
@@ -187,11 +168,7 @@
 	return err
 }
 func findKeys(ctx context.Context, filter bson.M, withoutLabel bool) ([]*model.KVDoc, error) {
-	c, err := session.GetClient()
-	if err != nil {
-		return nil, err
-	}
-	collection := c.Database(session.Name).Collection(session.CollectionKV)
+	collection := session.GetDB().Collection(session.CollectionKV)
 	cur, err := collection.Find(ctx, filter)
 	if err != nil {
 		if err.Error() == context.DeadlineExceeded.Error() {
diff --git a/server/service/mongo/kv/kv_service.go b/server/service/mongo/kv/kv_service.go
index f9af41c..30477c3 100644
--- a/server/service/mongo/kv/kv_service.go
+++ b/server/service/mongo/kv/kv_service.go
@@ -20,14 +20,15 @@
 import (
 	"context"
 	"fmt"
-	"github.com/apache/servicecomb-kie/server/service"
-	"github.com/apache/servicecomb-kie/server/service/mongo/label"
-	"github.com/apache/servicecomb-kie/server/service/mongo/session"
+	"github.com/apache/servicecomb-kie/server/id"
 	"reflect"
 	"time"
 
 	"github.com/apache/servicecomb-kie/pkg/model"
+	"github.com/apache/servicecomb-kie/server/service"
 	"github.com/apache/servicecomb-kie/server/service/mongo/history"
+	"github.com/apache/servicecomb-kie/server/service/mongo/label"
+	"github.com/apache/servicecomb-kie/server/service/mongo/session"
 	"github.com/go-mesh/openlogging"
 	"go.mongodb.org/mongo-driver/bson"
 	"go.mongodb.org/mongo-driver/bson/primitive"
@@ -74,7 +75,7 @@
 		}
 
 	}
-	kv.LabelID = labelID.Hex()
+	kv.LabelID = string(labelID)
 	if kv.ValueType == "" {
 		kv.ValueType = session.DefaultValueType
 	}
@@ -104,7 +105,7 @@
 }
 
 //Exist supports you query by label map or labels id
-func (s *Service) Exist(ctx context.Context, domain, key string, project string, options ...service.FindOption) (primitive.ObjectID, error) {
+func (s *Service) Exist(ctx context.Context, domain, key string, project string, options ...service.FindOption) (id.ID, error) {
 	ctx, _ = context.WithTimeout(context.Background(), session.Timeout)
 	opts := service.FindOptions{}
 	for _, o := range options {
@@ -113,16 +114,16 @@
 	if opts.LabelID != "" {
 		kvs, err := findKVByLabelID(ctx, domain, opts.LabelID, key, project)
 		if err != nil {
-			return primitive.NilObjectID, err
+			return "", err
 		}
 		return kvs[0].ID, nil
 	}
 	kvs, err := s.FindKV(ctx, domain, project, service.WithExactLabels(), service.WithLabels(opts.Labels), service.WithKey(key))
 	if err != nil {
-		return primitive.NilObjectID, err
+		return "", err
 	}
 	if len(kvs) != 1 {
-		return primitive.NilObjectID, session.ErrTooMany
+		return "", session.ErrTooMany
 	}
 
 	return kvs[0].Data[0].ID, nil
diff --git a/server/service/mongo/kv/kv_test.go b/server/service/mongo/kv/kv_test.go
index 70a3bd9..b816aa4 100644
--- a/server/service/mongo/kv/kv_test.go
+++ b/server/service/mongo/kv/kv_test.go
@@ -55,7 +55,7 @@
 				Expect(err).Should(BeNil())
 			})
 			It("should has ID", func() {
-				Expect(kv.ID.Hex()).ShouldNot(BeEmpty())
+				Expect(kv.ID.String()).ShouldNot(BeEmpty())
 			})
 
 		})
@@ -80,7 +80,7 @@
 				Expect(err).Should(BeNil())
 			})
 			It("should has ID", func() {
-				Expect(kv.ID.Hex()).ShouldNot(BeEmpty())
+				Expect(kv.ID.String()).ShouldNot(BeEmpty())
 			})
 			It("should exist", func() {
 				Expect(oid).ShouldNot(BeEmpty())
@@ -115,13 +115,13 @@
 				Project: "test",
 			})
 			It("should has same id", func() {
-				Expect(afterKV.ID.Hex()).Should(Equal(beforeKV.ID.Hex()))
+				Expect(afterKV.ID.String()).Should(Equal(beforeKV.ID.String()))
 			})
 			oid, err := kvsvc.Exist(context.Background(), "default", "timeout", "test", service.WithLabels(map[string]string{
 				"app": "mall",
 			}))
 			It("should exists", func() {
-				Expect(oid.Hex()).Should(Equal(beforeKV.ID.Hex()))
+				Expect(oid.String()).Should(Equal(beforeKV.ID.String()))
 			})
 			kvs, err := kvsvc.FindKV(context.Background(), "default", "test", service.WithKey("timeout"), service.WithLabels(map[string]string{
 				"app": "mall",
@@ -223,7 +223,7 @@
 				Expect(err).Should(BeNil())
 			})
 
-			err = kvsvc.Delete(kv1.ID.Hex(), "", "default", "test")
+			err = kvsvc.Delete(kv1.ID.String(), "", "default", "test")
 			It("should not return err", func() {
 				Expect(err).Should(BeNil())
 			})
@@ -246,7 +246,7 @@
 				Expect(err).Should(BeNil())
 			})
 
-			err = kvsvc.Delete(kv1.ID.Hex(), kv1.LabelID, "default", "test")
+			err = kvsvc.Delete(kv1.ID.String(), kv1.LabelID, "default", "test")
 			It("should not return err", func() {
 				Expect(err).Should(BeNil())
 			})
diff --git a/server/service/mongo/label/label_dao.go b/server/service/mongo/label/label_dao.go
index 7e5355c..87149fc 100644
--- a/server/service/mongo/label/label_dao.go
+++ b/server/service/mongo/label/label_dao.go
@@ -21,6 +21,7 @@
 	"context"
 	"fmt"
 	"github.com/apache/servicecomb-kie/pkg/model"
+	"github.com/apache/servicecomb-kie/server/id"
 	"github.com/apache/servicecomb-kie/server/service"
 	"github.com/apache/servicecomb-kie/server/service/mongo/session"
 	"github.com/go-mesh/openlogging"
@@ -36,11 +37,7 @@
 //FindLabels find label doc by labels and project, check if the project has certain labels
 //if map is empty. will return default labels doc which has no labels
 func FindLabels(ctx context.Context, domain, project string, labels map[string]string) (*model.LabelDoc, error) {
-	c, err := session.GetClient()
-	if err != nil {
-		return nil, err
-	}
-	collection := c.Database(session.Name).Collection(session.CollectionLabel)
+	collection := session.GetDB().Collection(session.CollectionLabel)
 
 	filter := bson.M{"domain": domain, "project": project}
 	for k, v := range labels {
@@ -80,11 +77,7 @@
 
 //GetLatestLabel query revision table and find maximum revision number
 func GetLatestLabel(ctx context.Context, labelID string) (*model.LabelRevisionDoc, error) {
-	c, err := session.GetClient()
-	if err != nil {
-		return nil, err
-	}
-	collection := c.Database(session.Name).Collection(session.CollectionLabelRevision)
+	collection := session.GetDB().Collection(session.CollectionLabelRevision)
 
 	filter := bson.M{"label_id": labelID}
 
@@ -112,16 +105,16 @@
 }
 
 //Exist check whether the project has certain label or not and return label ID
-func Exist(ctx context.Context, domain string, project string, labels map[string]string) (primitive.ObjectID, error) {
+func Exist(ctx context.Context, domain string, project string, labels map[string]string) (id.ID, error) {
 	l, err := FindLabels(ctx, domain, project, labels)
 	if err != nil {
 		if err.Error() == context.DeadlineExceeded.Error() {
 			openlogging.Error("find label failed, dead line exceeded", openlogging.WithTags(openlogging.Tags{
 				"timeout": session.Timeout,
 			}))
-			return primitive.NilObjectID, fmt.Errorf("operation timout %s", session.Timeout)
+			return "", fmt.Errorf("operation timout %s", session.Timeout)
 		}
-		return primitive.NilObjectID, err
+		return "", err
 	}
 
 	return l.ID, nil
@@ -130,21 +123,17 @@
 
 //CreateLabel create a new label
 func CreateLabel(ctx context.Context, domain string, labels map[string]string, project string) (*model.LabelDoc, error) {
-	c, err := session.GetClient()
-	if err != nil {
-		return nil, err
-	}
 	l := &model.LabelDoc{
 		Domain:  domain,
 		Labels:  labels,
 		Project: project,
 	}
-	collection := c.Database(session.Name).Collection(session.CollectionLabel)
+	collection := session.GetDB().Collection(session.CollectionLabel)
 	res, err := collection.InsertOne(ctx, l)
 	if err != nil {
 		return nil, err
 	}
 	objectID, _ := res.InsertedID.(primitive.ObjectID)
-	l.ID = objectID
+	l.ID = id.ID(objectID.Hex())
 	return l, nil
 }
diff --git a/server/service/mongo/session/session.go b/server/service/mongo/session/session.go
index f1596bc..1eb43e2 100644
--- a/server/service/mongo/session/session.go
+++ b/server/service/mongo/session/session.go
@@ -24,19 +24,23 @@
 	"crypto/x509"
 	"errors"
 	"fmt"
+	"github.com/apache/servicecomb-kie/pkg/model"
+	"github.com/go-mesh/openlogging"
+	"go.mongodb.org/mongo-driver/bson"
+	"go.mongodb.org/mongo-driver/bson/bsoncodec"
+	"go.mongodb.org/mongo-driver/mongo/options"
 	"io/ioutil"
+	"reflect"
 	"sync"
 	"time"
 
 	"github.com/apache/servicecomb-kie/server/config"
-	"github.com/go-mesh/openlogging"
 	"go.mongodb.org/mongo-driver/mongo"
-	"go.mongodb.org/mongo-driver/mongo/options"
 )
 
 //const for db name and collection name
 const (
-	Name                    = "kie"
+	DBName                  = "kie"
 	CollectionLabel         = "label"
 	CollectionKV            = "kv"
 	CollectionLabelRevision = "label_revision"
@@ -60,6 +64,7 @@
 
 var client *mongo.Client
 var once sync.Once
+var db *mongo.Database
 
 //Timeout db operation time out
 var Timeout time.Duration
@@ -76,14 +81,13 @@
 	if Timeout == 0 {
 		Timeout = DefaultTimeout
 	}
-	return nil
-}
-
-//GetClient create a new mongo db client
-//if client is created, just return.
-func GetClient() (*mongo.Client, error) {
-	var err error
 	once.Do(func() {
+		sc, _ := bsoncodec.NewStructCodec(bsoncodec.DefaultStructTagParser)
+		reg := bson.NewRegistryBuilder().
+			RegisterEncoder(reflect.TypeOf(model.LabelDoc{}), sc).
+			RegisterEncoder(reflect.TypeOf(model.KVDoc{}), sc).
+			RegisterEncoder(reflect.TypeOf(model.LabelRevisionDoc{}), sc).
+			Build()
 		clientOps := []*options.ClientOptions{options.Client().ApplyURI(config.GetDB().URI)}
 		if config.GetDB().SSLEnabled {
 			if config.GetDB().RootCA == "" {
@@ -115,7 +119,14 @@
 			return
 		}
 		openlogging.Info("DB connected")
+		db = client.Database(DBName, &options.DatabaseOptions{
+			Registry: reg,
+		})
 	})
+	return nil
+}
 
-	return client, err
+//GetDB get mongo db client
+func GetDB() *mongo.Database {
+	return db
 }