I might be overlooking something obvious, but is there a way to pretty print a pipeline built in Go using mongo.Pipeline{}, bson.M{} etc?
Something a bit more readable in a log that this!
2023-02-13T16:15:29.389-05:00 (mongo.Pipeline) (len=10 cap=14) {
2023-02-13T16:15:29.389-05:00 (primitive.D) (len=1 cap=1) {
2023-02-13T16:15:29.389-05:00 (primitive.E) {
2023-02-13T16:15:29.389-05:00 Key: (string) (len=6) "$match",
2023-02-13T16:15:29.389-05:00 Value: (primitive.M) (len=1) {
2023-02-13T16:15:29.389-05:00 (string) (len=17) "summary": (primitive.M) (len=1) {
2023-02-13T16:15:29.389-05:00 (string) (len=7) "$exists": (bool) true
2023-02-13T16:15:29.389-05:00 }
2023-02-13T16:15:29.389-05:00 }
2023-02-13T16:15:29.389-05:00 }
2023-02-13T16:15:29.389-05:00 },
Hi
@Ben_Giddins,
Welcome to the MongoDB Community forums 
Here, you can use bson.Marshal()
to convert each pipeline element to a BSON document. After that, you can use bson.Unmarshal()
to convert the BSON document to a bson.M
value for pretty printing.
Finally, you can use json.MarshalIndent to format the output. Here, each JSON element in the output will begin on a new line beginning with a prefix followed by one or more copies of indent according to the indentation nesting you have provided.
Here is the code snippet for your reference:
package main
import (
"encoding/json"
"fmt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
)
func main() {
pipeline := mongo.Pipeline{
bson.D{{"$match", bson.M{"age": bson.M{"$gt": 100}}}},
bson.D{{"$group", bson.M{"count": bson.M{"$sum": 1}}}},
bson.D{{"$sort", bson.M{"count": -1}}},
bson.D{{"$limit", 10}},
}
var prettyDocs []bson.M
for _, doc := range pipeline {
bsonDoc, err := bson.Marshal(doc)
if err != nil {
panic(err)
}
var prettyDoc bson.M
err = bson.Unmarshal(bsonDoc, &prettyDoc)
if err != nil {
panic(err)
}
prettyDocs = append(prettyDocs, prettyDoc)
}
prettyJSON, err := json.MarshalIndent(prettyDocs, "", " ")
if err != nil {
panic(err)
}
fmt.Println(string(prettyJSON))
}
It will return the output as follow:
[
{
"$match": {
"age": {
"$gt": 100
}
}
},
{
"$group": {
"count": {
"$sum": 1
}
}
},
{
"$sort": {
"count": -1
}
},
{
"$limit": 10
}
]
I hope it helps!
Best,
Kushagra
Thank you! This is perfect.
Minor tweak - in AWS Lambda, newline characters need to be replaced by a carriage return to get a single block of output in CloudWatch:
result := bytes.Replace(prettyJSON, []byte("\n"), []byte("\r"), -1)
fmt.Println(string(result))