2014-05-04 5 views
2

В настоящее время я бегу это в обработчике HTTP:Streaming BSON-> JSON HTTP ответ в Go?

err := mongoCollection.Find(bson.M{"name": vars["name"]}).One(&result) 
data, err := json.Marshal(result) 
w.Write(data) 

Как я могу начать служить результат до того, как полные данные BSON в?

Редактировать: ответ должен превышать расширение mgo и перейти на bson. mgo Насколько я могу судить, будут служить только полные документы, если я не ошибаюсь. У меня есть один - возможно большой документ, как показывает мой пример кода.

ответ

2

Для того, чтобы это было возможно, вы бы нужны эти вещи:

  1. Доступ к Reader для входящего потока BSON
  2. Тип данных для общих частей документа
  3. Воспроизведение потокового декодер для BSON, который считывает из Reader и производит части документа
  4. Воспроизведение потокового кодер для JSON, который потребляет части документа и записывает в Writer

mgo не дает номер 1. encoding/json не предоставляет номер 2 или 4. mgo/bson не предоставляет номер 3. Немного прибегая к помощи не оказывает никакой помощи ни для одной из этих точек в Go, хотя на других языках есть потоковые json-парсеры (см. ответы для Is there a streaming API for JSON?).

Ваше желание сделать это разумно, но поддержки пока нет. К счастью, json и bson достаточно просты, и все компоненты, которые вы используете, являются с открытым исходным кодом, поэтому теоретически вы можете написать нужные вам инструменты.

+0

Это странно; не http://golang.org/pkg/encoding/json/#NewDecoder потокового JSON-декодера? – chx

+0

@chx Да, это полупотоковый декодер в том смысле, что входные байты потребляются в кусках. Однако он не передает свой результат, результирующий документ, в куски. Вывод хранится 'Decoder.Decode (v interface {}) error' в структуру результата в одном вызове. Вам нужно что-то вроде 'bson.Decoder.NextPart() DocPart', который вы можете передать в' json.Encoder.WritePart (p DocPart) 'one' DocPart' за раз, поэтому полный 'v интерфейс {}' никогда не строится , – Sean

-1

Посмотрите на json.Encoder. Он записывает объекты JSON в выходной поток. json.Marshal производит []byte за один выстрел и не обеспечивает поток.

На стороне MongoDB посмотрите mgo.Iter. В случае, если у вас есть большое количество документов в вашем результате, вы можете сериализовать их в пакетах и ​​сделать ваше приложение более эффективным с точки зрения памяти.

Пример использования json.Encode:

data := map[string]int{"apple": 5, "lettuce": 7} 
enc := json.NewEncoder(w) 
enc.Encode(data) 

Play

+0

Это полезно, если у вас есть несколько документов; и даже в этом случае примера было бы недостаточно, чтобы на самом деле собрать его:/ – chx

+0

'json.Encode' будет передавать клиенту хотя бы один документ. Поэтому он должен решить вашу проблему. Образец должен был дать вам указатель в правильном направлении и не делать все необходимое кодирование. – Sebastian

+0

'mgo.Iter' предоставит вам один документ, на самом деле вопрос, как вызвать' bson', чтобы получить результат, полученный таким образом, чтобы 'json.NewEncoder' мог поток? – chx

1

Я не думаю, что есть все, что вы можете сделать, чтобы избежать демаршаллизации весь BSON (и, следовательно, не служит результат до тех пор, пока BSON был полностью доставлен mgo), за исключением взлома на mgo. Его API имеет дело только в целом, unmarshalled документов, не имеющий доступ к любому BSON кодировка []byte или Reader, что вы могли бы потенциально поэлементное bsondecode-Then-jsonencode, как данные поступают в.

+0

Erm. Мое редактирование, которое является старым днем, говорит так: «Редактировать: ответ должен выйти за пределы расширения mgo и перейти в bson». – chx

+0

@chx Я знаю, но пакет bson ничего не может сделать для вас. Он не может попасть внутрь пакета mgo и остановить его от разборки документа. –

+0

, но может ли он обеспечить декодирование в bson-wire, необходимое для разговора с сервером? – chx

0

Посмотрите на chanson, вы можете легко построить и передать поток json. Есть пример, который считывает данные из каналов для добавления элементов в список. Возможно, вы можете сделать что-то подобное

 Смежные вопросы

  • Нет связанных вопросов^_^