2017-02-20 17 views
1

я доступ к MongoDB, используя Go следующим образом:экранным MongoDB от Go

var configRes *clientConfigData 
err := clientDB. 
    C(clientConfigCollection). 
    Find(bson.M{}). 
    One(&configRes) 
if err != nil { 
    return nil, errors.Wrap(err, "finding config collection") 
} 

Где

type clientConfigData struct { 
    SMTPAssoc  int  `bson:"smtp_assoc"` 
    PlanType  string `bson:"plan_type"` 
    EndDate  string `bson:"end_date"` 
} 

Теперь, так как EndDate в MongoDB хранится как string поэтому я объявил EndDate как string. Но мне нужно получить доступ к этой дате как Go Time в clientConfigData. Пожалуйста помоги.

ответ

2

Если вы хотите изменить значение или преобразовать тип при маршалинге/разметке ваших значений с/на MongoDB, вы можете сделать это, выполнив собственную логику маршалинга/размаширования.

Вы можете сделать это, реализовав интерфейсы bson.Getter и bson.Setter. Внутри этих методов вы можете делать все, что хотите, со значениями, которые маршалируются/не маршалируются.

Проще всего расширить clientConfigData тип с дополнительным полем, один, который будет иметь тип time.Time значение вам нужно:

type clientConfigData struct { 
    SMTPAssoc int  `bson:"smtp_assoc"` 
    PlanType string `bson:"plan_type"` 
    EndDateStr string `bson:"end_date"` 
    EndDate time.Time `bson:"-"` 
} 

Это имеет значение тега bson:"-", потому что мы не хотим, чтобы это появляются в MongoDB.

А теперь обычай маршалинг/unmarhsaling логики:

const endDateLayout = "2006-01-02 15:04:05" // Use your layout here 

func (c *clientConfigData) SetBSON(raw bson.Raw) (err error) { 
    type my clientConfigData 
    if err = raw.Unmarshal((*my)(c)); err != nil { 
     return 
    } 
    c.EndDate, err = time.Parse(endDateLayout, c.EndDateStr) 
    return 
} 

func (c *clientConfigData) GetBSON() (interface{}, error) { 
    c.EndDateStr = c.EndDate.Format(endDateLayout) 
    type my *clientConfigData 
    return my(c), nil 
} 

Что здесь происходит, что SetBSON() несет ответственность «заселить» ваше значение структуры с исходным значением наступающего из MongoDB, и GetBSON() отвечает, чтобы обеспечить значение, которое вы хотите сохранить (маршалин).

При загрузке: SetBSON() первые демаршализует значение как-есть, затем правильно устанавливает EndDate поле (которое имеет тип time.Time) от даты string значения, которые пришли из БД (EndDateStr).

При сохранении: GetBSON() первых заполняет EndDateStr поля (тот, который сохраняется) от EndDate поля, а затем просто возвращается, давая понять, что это нормально, чтобы сохранить.

Следует отметить: как SetBSON(), так и GetBSON() создать новый тип my внутри них. Причина этого заключается в том, чтобы избежать переполнения стека. Просто возвращение значения типа clientConfigData является плохим, потому что мы внедрили bson.Getter и bson.Setter, поэтому SetBSON() и GetBSON() получили бы бесконечное название. Новый тип my не имеет этих методов, поэтому бесконечная «рекурсия» не происходит (ключевое слово type создает новый тип и не наследует методы базового типа).

Смотрите также связанные/аналогичный вопрос: Set default date when inserting document with time.Time field

+0

так Если мы не реализовали 'bson.Getter' и' bson.Setter' мы можем просто вернуть 'clienConfigData' правильно? но в этом случае лучше не делать. Это верно? –

+1

Ваш вопрос не имеет смысла, так как добавление 'GetBSON()' и 'SetBSON()' ** ** реализует «Getter» и «Setter» («Getter» и «Setter» - это интерфейсы, определяющие «GetBSON () 'и' SetBSON() ').Если вы не добавите эти методы, от них не будет чего-то возвращать. – icza

+0

Спасибо большое @icza –