Skip to content

Commit 3609061

Browse files
authored
DOCSP-26417: use struct in aggregation pg (#209)
* DOCSP-26415: structs in agg pg * first pass fixes * spacing fix * MW small fixes
1 parent 74a5908 commit 3609061

File tree

2 files changed

+69
-64
lines changed

2 files changed

+69
-64
lines changed

source/fundamentals/aggregation.txt

Lines changed: 38 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,15 @@ operations, keep the following in mind:
8585
Examples
8686
--------
8787

88+
The examples in this section use the following ``Tea`` struct as a model for documents
89+
in the ``menu`` collection:
90+
91+
.. literalinclude:: /includes/fundamentals/code-snippets/aggregation.go
92+
:start-after: start-tea-struct
93+
:end-before: end-tea-struct
94+
:language: go
95+
:dedent:
96+
8897
To run the examples in this section, load the sample data into the
8998
``tea.menu`` collection with the following snippet:
9099

@@ -94,16 +103,16 @@ To run the examples in this section, load the sample data into the
94103
:language: go
95104
:dedent:
96105

97-
Each document represents a tea on the menu of a shop. It conatains
98-
information about the tea type, the toppings you can add, and its price.
106+
Each document represents a tea on the menu of a shop and contains
107+
information about the tea type, the available toppings, and the price.
99108

100109
Average Rating
101110
~~~~~~~~~~~~~~
102111

103112
The following example calculates and displays the average rating and
104-
amount of ratings for each tea.
113+
number of ratings for each tea category.
105114

106-
The aggregation pipleline uses the ``$group`` stage to group the
115+
The aggregation pipeline uses the ``$group`` stage to group the
107116
documents by the ``category`` field, calculates the average using the
108117
``$avg`` expression operator, and counts the number of documents using
109118
the ``$sum`` expression operator.
@@ -114,54 +123,49 @@ the ``$sum`` expression operator.
114123
.. input::
115124
:language: go
116125

117-
// create the stage
126+
// create group stage
118127
groupStage := bson.D{
119128
{"$group", bson.D{
120129
{"_id", "$category"},
121-
{"average_price", bson.D{
122-
{"$avg", "$price"},
123-
}},
124-
{"type_total", bson.D{
125-
{"$sum", 1},
126-
}},
127-
}}}
128-
129-
// pass the stage into a pipeline
130-
// pass the pipeline as the second paramter in the Aggregate() method
130+
{"average_price", bson.D{{"$avg", "$price"}}},
131+
{"type_total", bson.D{{"$sum", 1}}},
132+
}}}
133+
134+
// pass the pipeline to the Aggregate() method
131135
cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{groupStage})
132136
if err != nil {
133137
panic(err)
134138
}
135-
139+
136140
// display the results
137141
var results []bson.M
138142
if err = cursor.All(context.TODO(), &results); err != nil {
139143
panic(err)
140144
}
141145
for _, result := range results {
142-
fmt.Printf("Average price of %v tea: $%v \n", result["_id"], result["average_price"])
143-
fmt.Printf("Amount of %v tea: %v \n\n", result["_id"], result["type_total"])
146+
fmt.Printf("Average price of %v tea options: $%v \n", result["_id"], result["average_price"])
147+
fmt.Printf("Number of %v tea options: %v \n\n", result["_id"], result["type_total"])
144148
}
145149

146150
.. output::
147151
:language: none
148152
:visible: false
149153

150-
Average price of black tea: $6.075
151-
Amount of black tea: 4
154+
Average price of black tea options: $6.075
155+
Number of black tea options: 4
152156

153-
Average price of green tea: $5.7
154-
Amount of green tea: 4
157+
Average price of green tea options: $5.70
158+
Number of green tea options: 4
155159

156160
Omit Fields in Results
157161
~~~~~~~~~~~~~~~~~~~~~~
158162

159163
The following example matches documents where you can get milk foam as a
160164
topping and lists the two cheapest options.
161165

162-
The aggregation pipleline contains the following stages:
166+
The aggregation pipeline contains the following stages:
163167

164-
- ``$match`` stage to match documents where its ``toppings`` contain "milk foam"
168+
- ``$match`` stage to match documents where the ``toppings`` field contains "milk foam"
165169
- ``$unset`` stage to omit the ``_id`` and ``category`` fields
166170
- ``$sort`` stage to sort the ``price`` and ``toppings`` in ascending order
167171
- ``$limit`` stage to show the first two documents
@@ -175,38 +179,34 @@ The aggregation pipleline contains the following stages:
175179
// create the stages
176180
matchStage := bson.D{{"$match", bson.D{{"toppings", "milk foam"}}}}
177181
unsetStage := bson.D{{"$unset", bson.A{"_id", "category"}}}
178-
sortStage := bson.D{{"$sort", bson.D{
179-
{"price", 1},
180-
{"toppings", 1}},
181-
}}
182+
sortStage := bson.D{{"$sort", bson.D{{"price", 1}, {"toppings", 1}}}}
182183
limitStage := bson.D{{"$limit", 2}}
183-
184-
// pass the stage into a pipeline
185-
// pass the pipeline as the second paramter in the Aggregate() method
184+
185+
// pass the pipeline to the Aggregate() method
186186
cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{matchStage, unsetStage, sortStage, limitStage})
187187
if err != nil {
188188
panic(err)
189189
}
190-
190+
191191
// display the results
192-
var results []bson.M
192+
var results []Tea
193193
if err = cursor.All(context.TODO(), &results); err != nil {
194194
panic(err)
195195
}
196196
for _, result := range results {
197-
fmt.Printf("Tea: %v \nToppings: %v \nPrice: $%v \n\n", result["type"], result["toppings"], result["price"])
197+
fmt.Printf("Tea: %v \nToppings: %v \nPrice: $%v \n\n", result.Type, strings.Join(result.Toppings, ", "), result.Price)
198198
}
199199

200200
.. output::
201201
:language: none
202202
:visible: false
203203

204204
Tea: Hojicha
205-
Toppings: [lemon ginger milk foam]
205+
Toppings: lemon, ginger, milk foam
206206
Price: $5.55
207-
207+
208208
Tea: Gyokuro
209-
Toppings: [berries milk foam]
209+
Toppings: berries, milk foam
210210
Price: $5.65
211211

212212
Additional Information
@@ -238,5 +238,4 @@ To learn more about any of the methods or types discussed in this
238238
guide, see the following API Documentation:
239239

240240
- `Aggregate() <{+api+}/mongo#Collection.Aggregate>`__
241-
- `AggregateOptions <{+api+}/mongo/options#AggregateOptions>`__
242-
241+
- `AggregateOptions <{+api+}/mongo/options#AggregateOptions>`__

source/includes/fundamentals/code-snippets/aggregation.go

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,23 @@ import (
55
"fmt"
66
"log"
77
"os"
8+
"strings"
89

910
"go.mongodb.org/mongo-driver/bson"
1011
"go.mongodb.org/mongo-driver/mongo"
1112
"go.mongodb.org/mongo-driver/mongo/options"
1213
)
1314

15+
// start-tea-struct
16+
type Tea struct {
17+
Type string
18+
Category string
19+
Toppings []string
20+
Price float32
21+
}
22+
23+
// end-tea-struct
24+
1425
func main() {
1526
var uri string
1627
if uri = os.Getenv("MONGODB_URI"); uri == "" {
@@ -31,34 +42,32 @@ func main() {
3142
// begin insert docs
3243
coll := client.Database("tea").Collection("menu")
3344
docs := []interface{}{
34-
bson.D{{"type", "Masala"}, {"category", "black"}, {"toppings", bson.A{"ginger", "pumpkin spice", "cinnomon"}}, {"price", 6.75}},
35-
bson.D{{"type", "Gyokuro"}, {"category", "green"}, {"toppings", bson.A{"berries", "milk foam"}}, {"price", 5.65}},
36-
bson.D{{"type", "English Breakfast"}, {"category", "black"}, {"toppings", bson.A{"whipped cream", "honey"}}, {"price", 5.75}},
37-
bson.D{{"type", "Sencha"}, {"category", "green"}, {"toppings", bson.A{"lemon", "whipped cream"}}, {"price", 5.15}},
38-
bson.D{{"type", "Assam"}, {"category", "black"}, {"toppings", bson.A{"milk foam", "honey", "berries"}}, {"price", 5.65}},
39-
bson.D{{"type", "Matcha"}, {"category", "green"}, {"toppings", bson.A{"whipped cream", "honey"}}, {"price", 6.45}},
40-
bson.D{{"type", "Earl Grey"}, {"category", "black"}, {"toppings", bson.A{"milk foam", "pumpkin spice"}}, {"price", 6.15}},
41-
bson.D{{"type", "Hojicha"}, {"category", "green"}, {"toppings", bson.A{"lemon", "ginger", "milk foam"}}, {"price", 5.55}},
45+
Tea{Type: "Masala", Category: "black", Toppings: []string{"ginger", "pumpkin spice", "cinnamon"}, Price: 6.75},
46+
Tea{Type: "Gyokuro", Category: "green", Toppings: []string{"berries", "milk foam"}, Price: 5.65},
47+
Tea{Type: "English Breakfast", Category: "black", Toppings: []string{"whipped cream", "honey"}, Price: 5.75},
48+
Tea{Type: "Sencha", Category: "green", Toppings: []string{"lemon", "whipped cream"}, Price: 5.15},
49+
Tea{Type: "Assam", Category: "black", Toppings: []string{"milk foam", "honey", "berries"}, Price: 5.65},
50+
Tea{Type: "Matcha", Category: "green", Toppings: []string{"whipped cream", "honey"}, Price: 6.45},
51+
Tea{Type: "Earl Grey", Category: "black", Toppings: []string{"milk foam", "pumpkin spice"}, Price: 6.15},
52+
Tea{Type: "Hojicha", Category: "green", Toppings: []string{"lemon", "ginger", "milk foam"}, Price: 5.55},
4253
}
4354

4455
result, err := coll.InsertMany(context.TODO(), docs)
56+
// end insert docs
57+
4558
if err != nil {
4659
panic(err)
4760
}
48-
// end insert docs
61+
4962
fmt.Printf("Number of documents inserted: %d\n", len(result.InsertedIDs))
5063

51-
fmt.Println("Average:")
64+
fmt.Println("\nAggregation Example - Average\n")
5265
{
5366
groupStage := bson.D{
5467
{"$group", bson.D{
5568
{"_id", "$category"},
56-
{"average_price", bson.D{
57-
{"$avg", "$price"},
58-
}},
59-
{"type_total", bson.D{
60-
{"$sum", 1},
61-
}},
69+
{"average_price", bson.D{{"$avg", "$price"}}},
70+
{"type_total", bson.D{{"$sum", 1}}},
6271
}}}
6372

6473
cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{groupStage})
@@ -71,32 +80,29 @@ func main() {
7180
panic(err)
7281
}
7382
for _, result := range results {
74-
fmt.Printf("Average price of %v tea: $%v \n", result["_id"], result["average_price"])
75-
fmt.Printf("Amount of %v tea: %v \n\n", result["_id"], result["type_total"])
83+
fmt.Printf("Average price of %v tea options: $%v \n", result["_id"], result["average_price"])
84+
fmt.Printf("Number of %v tea options: %v \n\n", result["_id"], result["type_total"])
7685
}
7786
}
7887

79-
fmt.Println("Unset:")
88+
fmt.Println("\nAggregation Example - Unset\n")
8089
{
8190
matchStage := bson.D{{"$match", bson.D{{"toppings", "milk foam"}}}}
8291
unsetStage := bson.D{{"$unset", bson.A{"_id", "category"}}}
83-
sortStage := bson.D{{"$sort", bson.D{
84-
{"price", 1},
85-
{"toppings", 1}},
86-
}}
92+
sortStage := bson.D{{"$sort", bson.D{{"price", 1}, {"toppings", 1}}}}
8793
limitStage := bson.D{{"$limit", 2}}
8894

8995
cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{matchStage, unsetStage, sortStage, limitStage})
9096
if err != nil {
9197
panic(err)
9298
}
9399

94-
var results []bson.M
100+
var results []Tea
95101
if err = cursor.All(context.TODO(), &results); err != nil {
96102
panic(err)
97103
}
98104
for _, result := range results {
99-
fmt.Printf("Tea: %v \nToppings: %v \nPrice: $%v \n\n", result["type"], result["toppings"], result["price"])
105+
fmt.Printf("Tea: %v \nToppings: %v \nPrice: $%v \n\n", result.Type, strings.Join(result.Toppings, ", "), result.Price)
100106
}
101107
}
102108
}

0 commit comments

Comments
 (0)