Reputation: 103
I don't want to use structs before converting results into JSON. Let's say I have some results:
result, err := collection.Find(ctx, filter, options)
I can collect all results in docs variable and last result in doc variable:
var doc bson.Raw
var docs []bson.Raw
for result.Next(ctx) {
document, err := result.DecodeBytes()
if err != nil {
log.Println(err)
}
doc = document
docs = append(docs, doc)
}
I can easily convert last result into JSON without using any structs:
var jsonDoc bson.M
err = bson.Unmarshal(doc, &jsonDoc)
return jsonDoc
I can't convert docs into JSON and use as a result in my Rest server.
Update 2019-01-17:
I'm using result in my REST server like this:
user.GET("/booking/customer/:id", func(c *gin.Context) {
result := GetAllCustomerBookings(c.Param("id"))
c.JSON(http.StatusOK, result)
})
so it can't be a loop through values. The question: how to convert []bson.Raw to []byte or bson.Raw. Let's imagine that now I have {JSON} in each value of array. I need one JSON like this: [{JSON}, {JSON}, ...].
Using nodejs was easier because I could send all records in one JSON document. Go and mongodb-go-driver needs to go through all records and I don't know how to build one JSON document.
Nodejs and mongodb equivalent:
router.get('/bookings/customer/:id', function (req, res, next) {
db.Bookings.find({
"booking.customer._id": {
$eq: req.params.id
}
}).sort({
"booking.arrival_date": -1
},
function (err, bookings) {
if (err) {
res.send(err);
} else {
res.json(bookings);
}
});
});
Upvotes: 4
Views: 4826
Reputation: 441
you can also use this:
var results []bson.M
if err := cursor.All(context.TODO(), &results); err != nil {
log.Panic(err)
}
and for see the result or convert to json use this:
res, _ := json.Marshal(results)
fmt.Println(string(res))
If you would like do it by your own you can do this:
var convertedResult []map[string]interface{}
for _, item := range results {
convertedItem := make(map[string]interface{})
for key, val := range item {
switch v := val.(type) {
case primitive.ObjectID:
convertedItem[key] = v.Hex()
case bson.M:
subMap := make(map[string]interface{})
for subKey, subVal := range v {
subMap[subKey] = subVal
}
convertedItem[key] = subMap
case bson.A:
subArray := make([]interface{}, len(v))
for i, subVal := range v {
subArray[i] = subVal
}
convertedItem[key] = subArray
default:
convertedItem[key] = v
}
}
convertedResult = append(convertedResult, convertedItem)
}
jsonBytes, err := json.Marshal(convertedResult)
if err != nil {
panic(err)
}
jsonString := string(jsonBytes)
fmt.Println(jsonString)
Upvotes: 0
Reputation: 103
This code works. After few hours of trying and thanks to good luck I managed to solve this issue. Maybe someone will explain this?
Instead of bson.Raw I used bson.M and result.Decode() instead of result.DecodeBytes() Now I have the same output as nodejs gives me.
var docs []bson.M
for result.Next(ctx) {
var document bson.M
err = result.Decode(&document)
if err != nil {
log.Println(err)
}
docs = append(docs, document)
}
return docs
Upvotes: 4