1// Copyright (C) MongoDB, Inc. 2017-present. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); you may 4// not use this file except in compliance with the License. You may obtain 5// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 6 7// NOTE: Any time this file is modified, a WEBSITE ticket should be opened to sync the changes with 8// the "What is MongoDB" webpage, which the example was originally added to as part of WEBSITE-5148. 9 10package documentation_examples 11 12import ( 13 "context" 14 "fmt" 15 "io/ioutil" 16 logger "log" 17 "sync/atomic" 18 "testing" 19 "time" 20 21 "github.com/stretchr/testify/require" 22 "go.mongodb.org/mongo-driver/bson" 23 "go.mongodb.org/mongo-driver/bson/primitive" 24 "go.mongodb.org/mongo-driver/mongo" 25 "go.mongodb.org/mongo-driver/mongo/options" 26 "go.mongodb.org/mongo-driver/mongo/readconcern" 27 "go.mongodb.org/mongo-driver/mongo/readpref" 28 "go.mongodb.org/mongo-driver/mongo/writeconcern" 29) 30 31func requireCursorLength(t *testing.T, cursor *mongo.Cursor, length int) { 32 i := 0 33 for cursor.Next(context.Background()) { 34 i++ 35 } 36 37 require.NoError(t, cursor.Err()) 38 require.Equal(t, i, length) 39} 40 41func containsKey(doc bson.Raw, key ...string) bool { 42 _, err := doc.LookupErr(key...) 43 if err != nil { 44 return false 45 } 46 return true 47} 48 49func parseDate(t *testing.T, dateString string) time.Time { 50 rfc3339MilliLayout := "2006-01-02T15:04:05.999Z07:00" // layout defined with Go reference time 51 parsedDate, err := time.Parse(rfc3339MilliLayout, dateString) 52 53 require.NoError(t, err) 54 return parsedDate 55} 56 57// InsertExamples contains examples for insert operations. 58func InsertExamples(t *testing.T, db *mongo.Database) { 59 coll := db.Collection("inventory_insert") 60 61 err := coll.Drop(context.Background()) 62 require.NoError(t, err) 63 64 { 65 // Start Example 1 66 67 result, err := coll.InsertOne( 68 context.Background(), 69 bson.D{ 70 {"item", "canvas"}, 71 {"qty", 100}, 72 {"tags", bson.A{"cotton"}}, 73 {"size", bson.D{ 74 {"h", 28}, 75 {"w", 35.5}, 76 {"uom", "cm"}, 77 }}, 78 }) 79 80 // End Example 1 81 82 require.NoError(t, err) 83 require.NotNil(t, result.InsertedID) 84 } 85 86 { 87 // Start Example 2 88 89 cursor, err := coll.Find( 90 context.Background(), 91 bson.D{{"item", "canvas"}}, 92 ) 93 94 // End Example 2 95 96 require.NoError(t, err) 97 requireCursorLength(t, cursor, 1) 98 99 } 100 101 { 102 // Start Example 3 103 104 result, err := coll.InsertMany( 105 context.Background(), 106 []interface{}{ 107 bson.D{ 108 {"item", "journal"}, 109 {"qty", int32(25)}, 110 {"tags", bson.A{"blank", "red"}}, 111 {"size", bson.D{ 112 {"h", 14}, 113 {"w", 21}, 114 {"uom", "cm"}, 115 }}, 116 }, 117 bson.D{ 118 {"item", "mat"}, 119 {"qty", int32(25)}, 120 {"tags", bson.A{"gray"}}, 121 {"size", bson.D{ 122 {"h", 27.9}, 123 {"w", 35.5}, 124 {"uom", "cm"}, 125 }}, 126 }, 127 bson.D{ 128 {"item", "mousepad"}, 129 {"qty", 25}, 130 {"tags", bson.A{"gel", "blue"}}, 131 {"size", bson.D{ 132 {"h", 19}, 133 {"w", 22.85}, 134 {"uom", "cm"}, 135 }}, 136 }, 137 }) 138 139 // End Example 3 140 141 require.NoError(t, err) 142 require.Len(t, result.InsertedIDs, 3) 143 } 144} 145 146// QueryToplevelFieldsExamples contains examples for querying top-level fields. 147func QueryToplevelFieldsExamples(t *testing.T, db *mongo.Database) { 148 coll := db.Collection("inventory_query_top") 149 150 err := coll.Drop(context.Background()) 151 require.NoError(t, err) 152 153 { 154 // Start Example 6 155 156 docs := []interface{}{ 157 bson.D{ 158 {"item", "journal"}, 159 {"qty", 25}, 160 {"size", bson.D{ 161 {"h", 14}, 162 {"w", 21}, 163 {"uom", "cm"}, 164 }}, 165 {"status", "A"}, 166 }, 167 bson.D{ 168 {"item", "notebook"}, 169 {"qty", 50}, 170 {"size", bson.D{ 171 {"h", 8.5}, 172 {"w", 11}, 173 {"uom", "in"}, 174 }}, 175 {"status", "A"}, 176 }, 177 bson.D{ 178 {"item", "paper"}, 179 {"qty", 100}, 180 {"size", bson.D{ 181 {"h", 8.5}, 182 {"w", 11}, 183 {"uom", "in"}, 184 }}, 185 {"status", "D"}, 186 }, 187 bson.D{ 188 {"item", "planner"}, 189 {"qty", 75}, 190 {"size", bson.D{ 191 {"h", 22.85}, 192 {"w", 30}, 193 {"uom", "cm"}, 194 }}, 195 {"status", "D"}, 196 }, 197 bson.D{ 198 {"item", "postcard"}, 199 {"qty", 45}, 200 {"size", bson.D{ 201 {"h", 10}, 202 {"w", 15.25}, 203 {"uom", "cm"}, 204 }}, 205 {"status", "A"}, 206 }, 207 } 208 209 result, err := coll.InsertMany(context.Background(), docs) 210 211 // End Example 6 212 213 require.NoError(t, err) 214 require.Len(t, result.InsertedIDs, 5) 215 } 216 217 { 218 // Start Example 7 219 220 cursor, err := coll.Find( 221 context.Background(), 222 bson.D{}, 223 ) 224 225 // End Example 7 226 227 require.NoError(t, err) 228 requireCursorLength(t, cursor, 5) 229 } 230 231 { 232 // Start Example 9 233 234 cursor, err := coll.Find( 235 context.Background(), 236 bson.D{{"status", "D"}}, 237 ) 238 239 // End Example 9 240 241 require.NoError(t, err) 242 requireCursorLength(t, cursor, 2) 243 } 244 245 { 246 // Start Example 10 247 248 cursor, err := coll.Find( 249 context.Background(), 250 bson.D{{"status", bson.D{{"$in", bson.A{"A", "D"}}}}}) 251 252 // End Example 10 253 254 require.NoError(t, err) 255 requireCursorLength(t, cursor, 5) 256 } 257 258 { 259 // Start Example 11 260 261 cursor, err := coll.Find( 262 context.Background(), 263 bson.D{ 264 {"status", "A"}, 265 {"qty", bson.D{{"$lt", 30}}}, 266 }) 267 268 // End Example 11 269 270 require.NoError(t, err) 271 requireCursorLength(t, cursor, 1) 272 } 273 274 { 275 // Start Example 12 276 277 cursor, err := coll.Find( 278 context.Background(), 279 bson.D{ 280 {"$or", 281 bson.A{ 282 bson.D{{"status", "A"}}, 283 bson.D{{"qty", bson.D{{"$lt", 30}}}}, 284 }}, 285 }) 286 287 // End Example 12 288 289 require.NoError(t, err) 290 requireCursorLength(t, cursor, 3) 291 } 292 293 { 294 // Start Example 13 295 296 cursor, err := coll.Find( 297 context.Background(), 298 bson.D{ 299 {"status", "A"}, 300 {"$or", bson.A{ 301 bson.D{{"qty", bson.D{{"$lt", 30}}}}, 302 bson.D{{"item", primitive.Regex{Pattern: "^p", Options: ""}}}, 303 }}, 304 }) 305 306 // End Example 13 307 308 require.NoError(t, err) 309 requireCursorLength(t, cursor, 2) 310 } 311 312} 313 314// QueryEmbeddedDocumentsExamples contains examples for querying embedded document fields. 315func QueryEmbeddedDocumentsExamples(t *testing.T, db *mongo.Database) { 316 coll := db.Collection("inventory_query_embedded") 317 318 err := coll.Drop(context.Background()) 319 require.NoError(t, err) 320 321 { 322 // Start Example 14 323 324 docs := []interface{}{ 325 bson.D{ 326 {"item", "journal"}, 327 {"qty", 25}, 328 {"size", bson.D{ 329 {"h", 14}, 330 {"w", 21}, 331 {"uom", "cm"}, 332 }}, 333 {"status", "A"}, 334 }, 335 bson.D{ 336 {"item", "notebook"}, 337 {"qty", 50}, 338 {"size", bson.D{ 339 {"h", 8.5}, 340 {"w", 11}, 341 {"uom", "in"}, 342 }}, 343 {"status", "A"}, 344 }, 345 bson.D{ 346 {"item", "paper"}, 347 {"qty", 100}, 348 {"size", bson.D{ 349 {"h", 8.5}, 350 {"w", 11}, 351 {"uom", "in"}, 352 }}, 353 {"status", "D"}, 354 }, 355 bson.D{ 356 {"item", "planner"}, 357 {"qty", 75}, 358 {"size", bson.D{ 359 {"h", 22.85}, 360 {"w", 30}, 361 {"uom", "cm"}, 362 }}, 363 {"status", "D"}, 364 }, 365 bson.D{ 366 {"item", "postcard"}, 367 {"qty", 45}, 368 {"size", bson.D{ 369 {"h", 10}, 370 {"w", 15.25}, 371 {"uom", "cm"}, 372 }}, 373 {"status", "A"}, 374 }, 375 } 376 377 result, err := coll.InsertMany(context.Background(), docs) 378 379 // End Example 14 380 381 require.NoError(t, err) 382 require.Len(t, result.InsertedIDs, 5) 383 } 384 385 { 386 // Start Example 15 387 388 cursor, err := coll.Find( 389 context.Background(), 390 bson.D{ 391 {"size", bson.D{ 392 {"h", 14}, 393 {"w", 21}, 394 {"uom", "cm"}, 395 }}, 396 }) 397 398 // End Example 15 399 400 require.NoError(t, err) 401 requireCursorLength(t, cursor, 1) 402 } 403 404 { 405 // Start Example 16 406 407 cursor, err := coll.Find( 408 context.Background(), 409 bson.D{ 410 {"size", bson.D{ 411 {"w", 21}, 412 {"h", 14}, 413 {"uom", "cm"}, 414 }}, 415 }) 416 417 // End Example 16 418 419 require.NoError(t, err) 420 requireCursorLength(t, cursor, 0) 421 } 422 423 { 424 // Start Example 17 425 426 cursor, err := coll.Find( 427 context.Background(), 428 bson.D{{"size.uom", "in"}}, 429 ) 430 431 // End Example 17 432 433 require.NoError(t, err) 434 requireCursorLength(t, cursor, 2) 435 } 436 437 { 438 // Start Example 18 439 440 cursor, err := coll.Find( 441 context.Background(), 442 bson.D{ 443 {"size.h", bson.D{ 444 {"$lt", 15}, 445 }}, 446 }) 447 448 // End Example 18 449 450 require.NoError(t, err) 451 requireCursorLength(t, cursor, 4) 452 } 453 454 { 455 // Start Example 19 456 457 cursor, err := coll.Find( 458 context.Background(), 459 bson.D{ 460 {"size.h", bson.D{ 461 {"$lt", 15}, 462 }}, 463 {"size.uom", "in"}, 464 {"status", "D"}, 465 }) 466 467 // End Example 19 468 469 require.NoError(t, err) 470 requireCursorLength(t, cursor, 1) 471 } 472 473} 474 475// QueryArraysExamples contains examples for querying array fields. 476func QueryArraysExamples(t *testing.T, db *mongo.Database) { 477 coll := db.Collection("inventory_query_array") 478 479 err := coll.Drop(context.Background()) 480 require.NoError(t, err) 481 482 { 483 // Start Example 20 484 485 docs := []interface{}{ 486 bson.D{ 487 {"item", "journal"}, 488 {"qty", 25}, 489 {"tags", bson.A{"blank", "red"}}, 490 {"dim_cm", bson.A{14, 21}}, 491 }, 492 bson.D{ 493 {"item", "notebook"}, 494 {"qty", 50}, 495 {"tags", bson.A{"red", "blank"}}, 496 {"dim_cm", bson.A{14, 21}}, 497 }, 498 bson.D{ 499 {"item", "paper"}, 500 {"qty", 100}, 501 {"tags", bson.A{"red", "blank", "plain"}}, 502 {"dim_cm", bson.A{14, 21}}, 503 }, 504 bson.D{ 505 {"item", "planner"}, 506 {"qty", 75}, 507 {"tags", bson.A{"blank", "red"}}, 508 {"dim_cm", bson.A{22.85, 30}}, 509 }, 510 bson.D{ 511 {"item", "postcard"}, 512 {"qty", 45}, 513 {"tags", bson.A{"blue"}}, 514 {"dim_cm", bson.A{10, 15.25}}, 515 }, 516 } 517 518 result, err := coll.InsertMany(context.Background(), docs) 519 520 // End Example 20 521 522 require.NoError(t, err) 523 require.Len(t, result.InsertedIDs, 5) 524 } 525 526 { 527 // Start Example 21 528 529 cursor, err := coll.Find( 530 context.Background(), 531 bson.D{{"tags", bson.A{"red", "blank"}}}, 532 ) 533 534 // End Example 21 535 536 require.NoError(t, err) 537 requireCursorLength(t, cursor, 1) 538 } 539 540 { 541 // Start Example 22 542 543 cursor, err := coll.Find( 544 context.Background(), 545 bson.D{ 546 {"tags", bson.D{{"$all", bson.A{"red", "blank"}}}}, 547 }) 548 549 // End Example 22 550 551 require.NoError(t, err) 552 requireCursorLength(t, cursor, 4) 553 } 554 555 { 556 // Start Example 23 557 558 cursor, err := coll.Find( 559 context.Background(), 560 bson.D{ 561 {"tags", "red"}, 562 }) 563 564 // End Example 23 565 566 require.NoError(t, err) 567 requireCursorLength(t, cursor, 4) 568 } 569 570 { 571 // Start Example 24 572 573 cursor, err := coll.Find( 574 context.Background(), 575 bson.D{ 576 {"dim_cm", bson.D{ 577 {"$gt", 25}, 578 }}, 579 }) 580 581 // End Example 24 582 583 require.NoError(t, err) 584 requireCursorLength(t, cursor, 1) 585 } 586 587 { 588 // Start Example 25 589 590 cursor, err := coll.Find( 591 context.Background(), 592 bson.D{ 593 {"dim_cm", bson.D{ 594 {"$gt", 15}, 595 {"$lt", 20}, 596 }}, 597 }) 598 599 // End Example 25 600 601 require.NoError(t, err) 602 requireCursorLength(t, cursor, 4) 603 } 604 605 { 606 // Start Example 26 607 608 cursor, err := coll.Find( 609 context.Background(), 610 bson.D{ 611 {"dim_cm", bson.D{ 612 {"$elemMatch", bson.D{ 613 {"$gt", 22}, 614 {"$lt", 30}, 615 }}, 616 }}, 617 }) 618 619 // End Example 26 620 621 require.NoError(t, err) 622 requireCursorLength(t, cursor, 1) 623 } 624 625 { 626 // Start Example 27 627 628 cursor, err := coll.Find( 629 context.Background(), 630 bson.D{ 631 {"dim_cm.1", bson.D{ 632 {"$gt", 25}, 633 }}, 634 }) 635 636 // End Example 27 637 638 require.NoError(t, err) 639 requireCursorLength(t, cursor, 1) 640 } 641 642 { 643 // Start Example 28 644 645 cursor, err := coll.Find( 646 context.Background(), 647 bson.D{ 648 {"tags", bson.D{ 649 {"$size", 3}, 650 }}, 651 }) 652 653 // End Example 28 654 655 require.NoError(t, err) 656 requireCursorLength(t, cursor, 1) 657 } 658 659} 660 661// QueryArrayEmbeddedDocumentsExamples contains examples for querying fields with arrays and embedded documents. 662func QueryArrayEmbeddedDocumentsExamples(t *testing.T, db *mongo.Database) { 663 coll := db.Collection("inventory_query_array_embedded") 664 665 err := coll.Drop(context.Background()) 666 require.NoError(t, err) 667 668 { 669 // Start Example 29 670 671 docs := []interface{}{ 672 bson.D{ 673 {"item", "journal"}, 674 {"instock", bson.A{ 675 bson.D{ 676 {"warehouse", "A"}, 677 {"qty", 5}, 678 }, 679 bson.D{ 680 {"warehouse", "C"}, 681 {"qty", 15}, 682 }, 683 }}, 684 }, 685 bson.D{ 686 {"item", "notebook"}, 687 {"instock", bson.A{ 688 bson.D{ 689 {"warehouse", "C"}, 690 {"qty", 5}, 691 }, 692 }}, 693 }, 694 bson.D{ 695 {"item", "paper"}, 696 {"instock", bson.A{ 697 bson.D{ 698 {"warehouse", "A"}, 699 {"qty", 60}, 700 }, 701 bson.D{ 702 {"warehouse", "B"}, 703 {"qty", 15}, 704 }, 705 }}, 706 }, 707 bson.D{ 708 {"item", "planner"}, 709 {"instock", bson.A{ 710 bson.D{ 711 {"warehouse", "A"}, 712 {"qty", 40}, 713 }, 714 bson.D{ 715 {"warehouse", "B"}, 716 {"qty", 5}, 717 }, 718 }}, 719 }, 720 bson.D{ 721 {"item", "postcard"}, 722 {"instock", bson.A{ 723 bson.D{ 724 {"warehouse", "B"}, 725 {"qty", 15}, 726 }, 727 bson.D{ 728 {"warehouse", "C"}, 729 {"qty", 35}, 730 }, 731 }}, 732 }, 733 } 734 735 result, err := coll.InsertMany(context.Background(), docs) 736 737 // End Example 29 738 739 require.NoError(t, err) 740 require.Len(t, result.InsertedIDs, 5) 741 } 742 743 { 744 // Start Example 30 745 746 cursor, err := coll.Find( 747 context.Background(), 748 bson.D{ 749 {"instock", bson.D{ 750 {"warehouse", "A"}, 751 {"qty", 5}, 752 }}, 753 }) 754 755 // End Example 30 756 757 require.NoError(t, err) 758 requireCursorLength(t, cursor, 1) 759 } 760 761 { 762 // Start Example 31 763 764 cursor, err := coll.Find( 765 context.Background(), 766 bson.D{ 767 {"instock", bson.D{ 768 {"qty", 5}, 769 {"warehouse", "A"}, 770 }}, 771 }) 772 773 // End Example 31 774 775 require.NoError(t, err) 776 requireCursorLength(t, cursor, 0) 777 } 778 779 { 780 // Start Example 32 781 782 cursor, err := coll.Find( 783 context.Background(), 784 bson.D{ 785 {"instock.0.qty", bson.D{ 786 {"$lte", 20}, 787 }}, 788 }) 789 790 // End Example 32 791 792 require.NoError(t, err) 793 requireCursorLength(t, cursor, 3) 794 } 795 796 { 797 // Start Example 33 798 799 cursor, err := coll.Find( 800 context.Background(), 801 bson.D{ 802 {"instock.qty", bson.D{ 803 {"$lte", 20}, 804 }}, 805 }) 806 807 // End Example 33 808 809 require.NoError(t, err) 810 requireCursorLength(t, cursor, 5) 811 } 812 813 { 814 // Start Example 34 815 816 cursor, err := coll.Find( 817 context.Background(), 818 bson.D{ 819 {"instock", bson.D{ 820 {"$elemMatch", bson.D{ 821 {"qty", 5}, 822 {"warehouse", "A"}, 823 }}, 824 }}, 825 }) 826 827 // End Example 34 828 829 require.NoError(t, err) 830 requireCursorLength(t, cursor, 1) 831 } 832 833 { 834 // Start Example 35 835 836 cursor, err := coll.Find( 837 context.Background(), 838 bson.D{ 839 {"instock", bson.D{ 840 {"$elemMatch", bson.D{ 841 {"qty", bson.D{ 842 {"$gt", 10}, 843 {"$lte", 20}, 844 }}, 845 }}, 846 }}, 847 }) 848 849 // End Example 35 850 851 require.NoError(t, err) 852 requireCursorLength(t, cursor, 3) 853 } 854 855 { 856 // Start Example 36 857 858 cursor, err := coll.Find( 859 context.Background(), 860 bson.D{ 861 {"instock.qty", bson.D{ 862 {"$gt", 10}, 863 {"$lte", 20}, 864 }}, 865 }) 866 867 // End Example 36 868 869 require.NoError(t, err) 870 requireCursorLength(t, cursor, 4) 871 } 872 873 { 874 // Start Example 37 875 876 cursor, err := coll.Find( 877 context.Background(), 878 bson.D{ 879 {"instock.qty", 5}, 880 {"instock.warehouse", "A"}, 881 }) 882 883 // End Example 37 884 885 require.NoError(t, err) 886 requireCursorLength(t, cursor, 2) 887 } 888} 889 890// QueryNullMissingFieldsExamples contains examples for querying fields that are null or missing. 891func QueryNullMissingFieldsExamples(t *testing.T, db *mongo.Database) { 892 coll := db.Collection("inventory_query_null_missing") 893 894 err := coll.Drop(context.Background()) 895 require.NoError(t, err) 896 897 { 898 // Start Example 38 899 900 docs := []interface{}{ 901 bson.D{ 902 {"_id", 1}, 903 {"item", nil}, 904 }, 905 bson.D{ 906 {"_id", 2}, 907 }, 908 } 909 910 result, err := coll.InsertMany(context.Background(), docs) 911 912 // End Example 38 913 914 require.NoError(t, err) 915 require.Len(t, result.InsertedIDs, 2) 916 } 917 918 { 919 // Start Example 39 920 921 cursor, err := coll.Find( 922 context.Background(), 923 bson.D{ 924 {"item", nil}, 925 }) 926 927 // End Example 39 928 929 require.NoError(t, err) 930 requireCursorLength(t, cursor, 2) 931 } 932 933 { 934 // Start Example 40 935 936 cursor, err := coll.Find( 937 context.Background(), 938 bson.D{ 939 {"item", bson.D{ 940 {"$type", 10}, 941 }}, 942 }) 943 944 // End Example 40 945 946 require.NoError(t, err) 947 requireCursorLength(t, cursor, 1) 948 } 949 950 { 951 // Start Example 41 952 953 cursor, err := coll.Find( 954 context.Background(), 955 bson.D{ 956 {"item", bson.D{ 957 {"$exists", false}, 958 }}, 959 }) 960 961 // End Example 41 962 963 require.NoError(t, err) 964 requireCursorLength(t, cursor, 1) 965 } 966} 967 968// ProjectionExamples contains examples for specifying projections in find operations. 969func ProjectionExamples(t *testing.T, db *mongo.Database) { 970 coll := db.Collection("inventory_project") 971 972 err := coll.Drop(context.Background()) 973 require.NoError(t, err) 974 975 { 976 // Start Example 42 977 978 docs := []interface{}{ 979 bson.D{ 980 {"item", "journal"}, 981 {"status", "A"}, 982 {"size", bson.D{ 983 {"h", 14}, 984 {"w", 21}, 985 {"uom", "cm"}, 986 }}, 987 {"instock", bson.A{ 988 bson.D{ 989 {"warehouse", "A"}, 990 {"qty", 5}, 991 }, 992 }}, 993 }, 994 bson.D{ 995 {"item", "notebook"}, 996 {"status", "A"}, 997 {"size", bson.D{ 998 {"h", 8.5}, 999 {"w", 11}, 1000 {"uom", "in"}, 1001 }}, 1002 {"instock", bson.A{ 1003 bson.D{ 1004 {"warehouse", "EC"}, 1005 {"qty", 5}, 1006 }, 1007 }}, 1008 }, 1009 bson.D{ 1010 {"item", "paper"}, 1011 {"status", "D"}, 1012 {"size", bson.D{ 1013 {"h", 8.5}, 1014 {"w", 11}, 1015 {"uom", "in"}, 1016 }}, 1017 {"instock", bson.A{ 1018 bson.D{ 1019 {"warehouse", "A"}, 1020 {"qty", 60}, 1021 }, 1022 }}, 1023 }, 1024 bson.D{ 1025 {"item", "planner"}, 1026 {"status", "D"}, 1027 {"size", bson.D{ 1028 {"h", 22.85}, 1029 {"w", 30}, 1030 {"uom", "cm"}, 1031 }}, 1032 {"instock", bson.A{ 1033 bson.D{ 1034 {"warehouse", "A"}, 1035 {"qty", 40}, 1036 }, 1037 }}, 1038 }, 1039 bson.D{ 1040 {"item", "postcard"}, 1041 {"status", "A"}, 1042 {"size", bson.D{ 1043 {"h", 10}, 1044 {"w", 15.25}, 1045 {"uom", "cm"}, 1046 }}, 1047 {"instock", bson.A{ 1048 bson.D{ 1049 {"warehouse", "B"}, 1050 {"qty", 15}, 1051 }, 1052 bson.D{ 1053 {"warehouse", "EC"}, 1054 {"qty", 35}, 1055 }, 1056 }}, 1057 }, 1058 } 1059 1060 result, err := coll.InsertMany(context.Background(), docs) 1061 1062 // End Example 42 1063 1064 require.NoError(t, err) 1065 require.Len(t, result.InsertedIDs, 5) 1066 } 1067 1068 { 1069 // Start Example 43 1070 1071 cursor, err := coll.Find( 1072 context.Background(), 1073 bson.D{{"status", "A"}}, 1074 ) 1075 1076 // End Example 43 1077 1078 require.NoError(t, err) 1079 requireCursorLength(t, cursor, 3) 1080 } 1081 1082 { 1083 // Start Example 44 1084 1085 projection := bson.D{ 1086 {"item", 1}, 1087 {"status", 1}, 1088 } 1089 1090 cursor, err := coll.Find( 1091 context.Background(), 1092 bson.D{ 1093 {"status", "A"}, 1094 }, 1095 options.Find().SetProjection(projection), 1096 ) 1097 1098 // End Example 44 1099 1100 require.NoError(t, err) 1101 1102 for cursor.Next(context.Background()) { 1103 doc := cursor.Current 1104 1105 require.True(t, containsKey(doc, "_id")) 1106 require.True(t, containsKey(doc, "item")) 1107 require.True(t, containsKey(doc, "status")) 1108 require.False(t, containsKey(doc, "size")) 1109 require.False(t, containsKey(doc, "instock")) 1110 } 1111 1112 require.NoError(t, cursor.Err()) 1113 } 1114 1115 { 1116 // Start Example 45 1117 1118 projection := bson.D{ 1119 {"item", 1}, 1120 {"status", 1}, 1121 {"_id", 0}, 1122 } 1123 1124 cursor, err := coll.Find( 1125 context.Background(), 1126 bson.D{ 1127 {"status", "A"}, 1128 }, 1129 options.Find().SetProjection(projection), 1130 ) 1131 1132 // End Example 45 1133 1134 require.NoError(t, err) 1135 1136 for cursor.Next(context.Background()) { 1137 doc := cursor.Current 1138 1139 require.False(t, containsKey(doc, "_id")) 1140 require.True(t, containsKey(doc, "item")) 1141 require.True(t, containsKey(doc, "status")) 1142 require.False(t, containsKey(doc, "size")) 1143 require.False(t, containsKey(doc, "instock")) 1144 } 1145 1146 require.NoError(t, cursor.Err()) 1147 } 1148 1149 { 1150 // Start Example 46 1151 1152 projection := bson.D{ 1153 {"status", 0}, 1154 {"instock", 0}, 1155 } 1156 1157 cursor, err := coll.Find( 1158 context.Background(), 1159 bson.D{ 1160 {"status", "A"}, 1161 }, 1162 options.Find().SetProjection(projection), 1163 ) 1164 1165 // End Example 46 1166 1167 require.NoError(t, err) 1168 1169 for cursor.Next(context.Background()) { 1170 doc := cursor.Current 1171 1172 require.True(t, containsKey(doc, "_id")) 1173 require.True(t, containsKey(doc, "item")) 1174 require.False(t, containsKey(doc, "status")) 1175 require.True(t, containsKey(doc, "size")) 1176 require.False(t, containsKey(doc, "instock")) 1177 } 1178 1179 require.NoError(t, cursor.Err()) 1180 } 1181 1182 { 1183 // Start Example 47 1184 1185 projection := bson.D{ 1186 {"item", 1}, 1187 {"status", 1}, 1188 {"size.uom", 1}, 1189 } 1190 1191 cursor, err := coll.Find( 1192 context.Background(), 1193 bson.D{ 1194 {"status", "A"}, 1195 }, 1196 options.Find().SetProjection(projection), 1197 ) 1198 1199 // End Example 47 1200 1201 require.NoError(t, err) 1202 1203 for cursor.Next(context.Background()) { 1204 doc := cursor.Current 1205 1206 require.True(t, containsKey(doc, "_id")) 1207 require.True(t, containsKey(doc, "item")) 1208 require.True(t, containsKey(doc, "status")) 1209 require.True(t, containsKey(doc, "size")) 1210 require.False(t, containsKey(doc, "instock")) 1211 1212 require.True(t, containsKey(doc, "size", "uom")) 1213 require.False(t, containsKey(doc, "size", "h")) 1214 require.False(t, containsKey(doc, "size", "w")) 1215 1216 } 1217 1218 require.NoError(t, cursor.Err()) 1219 } 1220 1221 { 1222 // Start Example 48 1223 1224 projection := bson.D{ 1225 {"size.uom", 0}, 1226 } 1227 1228 cursor, err := coll.Find( 1229 context.Background(), 1230 bson.D{ 1231 {"status", "A"}, 1232 }, 1233 options.Find().SetProjection(projection), 1234 ) 1235 1236 // End Example 48 1237 1238 require.NoError(t, err) 1239 1240 for cursor.Next(context.Background()) { 1241 doc := cursor.Current 1242 1243 require.True(t, containsKey(doc, "_id")) 1244 require.True(t, containsKey(doc, "item")) 1245 require.True(t, containsKey(doc, "status")) 1246 require.True(t, containsKey(doc, "size")) 1247 require.True(t, containsKey(doc, "instock")) 1248 1249 require.False(t, containsKey(doc, "size", "uom")) 1250 require.True(t, containsKey(doc, "size", "h")) 1251 require.True(t, containsKey(doc, "size", "w")) 1252 1253 } 1254 1255 require.NoError(t, cursor.Err()) 1256 } 1257 1258 { 1259 // Start Example 49 1260 1261 projection := bson.D{ 1262 {"item", 1}, 1263 {"status", 1}, 1264 {"instock.qty", 1}, 1265 } 1266 1267 cursor, err := coll.Find( 1268 context.Background(), 1269 bson.D{ 1270 {"status", "A"}, 1271 }, 1272 options.Find().SetProjection(projection), 1273 ) 1274 1275 // End Example 49 1276 1277 require.NoError(t, err) 1278 1279 for cursor.Next(context.Background()) { 1280 doc := cursor.Current 1281 1282 require.True(t, containsKey(doc, "_id")) 1283 require.True(t, containsKey(doc, "item")) 1284 require.True(t, containsKey(doc, "status")) 1285 require.False(t, containsKey(doc, "size")) 1286 require.True(t, containsKey(doc, "instock")) 1287 1288 instock, err := doc.LookupErr("instock") 1289 require.NoError(t, err) 1290 1291 vals, err := instock.Array().Values() 1292 require.NoError(t, err) 1293 1294 for _, val := range vals { 1295 require.Equal(t, bson.TypeEmbeddedDocument, val.Type) 1296 subdoc := val.Document() 1297 elems, err := subdoc.Elements() 1298 require.NoError(t, err) 1299 1300 require.Equal(t, 1, len(elems)) 1301 _, err = subdoc.LookupErr("qty") 1302 require.NoError(t, err) 1303 } 1304 } 1305 1306 require.NoError(t, cursor.Err()) 1307 } 1308 1309 { 1310 // Start Example 50 1311 1312 projection := bson.D{ 1313 {"item", 1}, 1314 {"status", 1}, 1315 {"instock", bson.D{ 1316 {"$slice", -1}, 1317 }}, 1318 } 1319 1320 cursor, err := coll.Find( 1321 context.Background(), 1322 bson.D{ 1323 {"status", "A"}, 1324 }, 1325 options.Find().SetProjection(projection), 1326 ) 1327 1328 // End Example 50 1329 1330 require.NoError(t, err) 1331 1332 for cursor.Next(context.Background()) { 1333 doc := cursor.Current 1334 1335 require.True(t, containsKey(doc, "_id")) 1336 require.True(t, containsKey(doc, "item")) 1337 require.True(t, containsKey(doc, "status")) 1338 require.False(t, containsKey(doc, "size")) 1339 require.True(t, containsKey(doc, "instock")) 1340 1341 instock, err := doc.LookupErr("instock") 1342 require.NoError(t, err) 1343 vals, err := instock.Array().Values() 1344 require.NoError(t, err) 1345 require.Equal(t, len(vals), 1) 1346 } 1347 1348 require.NoError(t, cursor.Err()) 1349 } 1350} 1351 1352// UpdateExamples contains examples of update operations. 1353func UpdateExamples(t *testing.T, db *mongo.Database) { 1354 coll := db.Collection("inventory_update") 1355 1356 err := coll.Drop(context.Background()) 1357 require.NoError(t, err) 1358 1359 { 1360 // Start Example 51 1361 1362 docs := []interface{}{ 1363 bson.D{ 1364 {"item", "canvas"}, 1365 {"qty", 100}, 1366 {"size", bson.D{ 1367 {"h", 28}, 1368 {"w", 35.5}, 1369 {"uom", "cm"}, 1370 }}, 1371 {"status", "A"}, 1372 }, 1373 bson.D{ 1374 {"item", "journal"}, 1375 {"qty", 25}, 1376 {"size", bson.D{ 1377 {"h", 14}, 1378 {"w", 21}, 1379 {"uom", "cm"}, 1380 }}, 1381 {"status", "A"}, 1382 }, 1383 bson.D{ 1384 {"item", "mat"}, 1385 {"qty", 85}, 1386 {"size", bson.D{ 1387 {"h", 27.9}, 1388 {"w", 35.5}, 1389 {"uom", "cm"}, 1390 }}, 1391 {"status", "A"}, 1392 }, 1393 bson.D{ 1394 {"item", "mousepad"}, 1395 {"qty", 25}, 1396 {"size", bson.D{ 1397 {"h", 19}, 1398 {"w", 22.85}, 1399 {"uom", "in"}, 1400 }}, 1401 {"status", "P"}, 1402 }, 1403 bson.D{ 1404 {"item", "notebook"}, 1405 {"qty", 50}, 1406 {"size", bson.D{ 1407 {"h", 8.5}, 1408 {"w", 11}, 1409 {"uom", "in"}, 1410 }}, 1411 {"status", "P"}, 1412 }, 1413 bson.D{ 1414 {"item", "paper"}, 1415 {"qty", 100}, 1416 {"size", bson.D{ 1417 {"h", 8.5}, 1418 {"w", 11}, 1419 {"uom", "in"}, 1420 }}, 1421 {"status", "D"}, 1422 }, 1423 bson.D{ 1424 {"item", "planner"}, 1425 {"qty", 75}, 1426 {"size", bson.D{ 1427 {"h", 22.85}, 1428 {"w", 30}, 1429 {"uom", "cm"}, 1430 }}, 1431 {"status", "D"}, 1432 }, 1433 bson.D{ 1434 {"item", "postcard"}, 1435 {"qty", 45}, 1436 {"size", bson.D{ 1437 {"h", 10}, 1438 {"w", 15.25}, 1439 {"uom", "cm"}, 1440 }}, 1441 {"status", "A"}, 1442 }, 1443 bson.D{ 1444 {"item", "sketchbook"}, 1445 {"qty", 80}, 1446 {"size", bson.D{ 1447 {"h", 14}, 1448 {"w", 21}, 1449 {"uom", "cm"}, 1450 }}, 1451 {"status", "A"}, 1452 }, 1453 bson.D{ 1454 {"item", "sketch pad"}, 1455 {"qty", 95}, 1456 {"size", bson.D{ 1457 {"h", 22.85}, 1458 {"w", 30.5}, 1459 {"uom", "cm"}, 1460 }}, 1461 {"status", "A"}, 1462 }, 1463 } 1464 1465 result, err := coll.InsertMany(context.Background(), docs) 1466 1467 // End Example 51 1468 1469 require.NoError(t, err) 1470 require.Len(t, result.InsertedIDs, 10) 1471 } 1472 1473 { 1474 // Start Example 52 1475 1476 result, err := coll.UpdateOne( 1477 context.Background(), 1478 bson.D{ 1479 {"item", "paper"}, 1480 }, 1481 bson.D{ 1482 {"$set", bson.D{ 1483 {"size.uom", "cm"}, 1484 {"status", "P"}, 1485 }}, 1486 {"$currentDate", bson.D{ 1487 {"lastModified", true}, 1488 }}, 1489 }, 1490 ) 1491 1492 // End Example 52 1493 1494 require.NoError(t, err) 1495 require.Equal(t, int64(1), result.MatchedCount) 1496 require.Equal(t, int64(1), result.ModifiedCount) 1497 1498 cursor, err := coll.Find( 1499 context.Background(), 1500 bson.D{ 1501 {"item", "paper"}, 1502 }) 1503 1504 require.NoError(t, err) 1505 1506 for cursor.Next(context.Background()) { 1507 doc := cursor.Current 1508 1509 uom, err := doc.LookupErr("size", "uom") 1510 require.NoError(t, err) 1511 require.Equal(t, uom.StringValue(), "cm") 1512 1513 status, err := doc.LookupErr("status") 1514 require.NoError(t, err) 1515 require.Equal(t, status.StringValue(), "P") 1516 1517 require.True(t, containsKey(doc, "lastModified")) 1518 } 1519 1520 require.NoError(t, cursor.Err()) 1521 } 1522 1523 { 1524 // Start Example 53 1525 1526 result, err := coll.UpdateMany( 1527 context.Background(), 1528 bson.D{ 1529 {"qty", bson.D{ 1530 {"$lt", 50}, 1531 }}, 1532 }, 1533 bson.D{ 1534 {"$set", bson.D{ 1535 {"size.uom", "cm"}, 1536 {"status", "P"}, 1537 }}, 1538 {"$currentDate", bson.D{ 1539 {"lastModified", true}, 1540 }}, 1541 }, 1542 ) 1543 1544 // End Example 53 1545 1546 require.NoError(t, err) 1547 require.Equal(t, int64(3), result.MatchedCount) 1548 require.Equal(t, int64(3), result.ModifiedCount) 1549 1550 cursor, err := coll.Find( 1551 context.Background(), 1552 bson.D{ 1553 {"qty", bson.D{ 1554 {"$lt", 50}, 1555 }}, 1556 }) 1557 1558 require.NoError(t, err) 1559 1560 for cursor.Next(context.Background()) { 1561 doc := cursor.Current 1562 1563 uom, err := doc.LookupErr("size", "uom") 1564 require.NoError(t, err) 1565 require.Equal(t, uom.StringValue(), "cm") 1566 1567 status, err := doc.LookupErr("status") 1568 require.NoError(t, err) 1569 require.Equal(t, status.StringValue(), "P") 1570 1571 require.True(t, containsKey(doc, "lastModified")) 1572 } 1573 1574 require.NoError(t, cursor.Err()) 1575 } 1576 1577 { 1578 // Start Example 54 1579 1580 result, err := coll.ReplaceOne( 1581 context.Background(), 1582 bson.D{ 1583 {"item", "paper"}, 1584 }, 1585 bson.D{ 1586 {"item", "paper"}, 1587 {"instock", bson.A{ 1588 bson.D{ 1589 {"warehouse", "A"}, 1590 {"qty", 60}, 1591 }, 1592 bson.D{ 1593 {"warehouse", "B"}, 1594 {"qty", 40}, 1595 }, 1596 }}, 1597 }, 1598 ) 1599 1600 // End Example 54 1601 1602 require.NoError(t, err) 1603 require.Equal(t, int64(1), result.MatchedCount) 1604 require.Equal(t, int64(1), result.ModifiedCount) 1605 1606 cursor, err := coll.Find( 1607 context.Background(), 1608 bson.D{ 1609 {"item", "paper"}, 1610 }) 1611 1612 require.NoError(t, err) 1613 1614 for cursor.Next(context.Background()) { 1615 require.True(t, containsKey(cursor.Current, "_id")) 1616 require.True(t, containsKey(cursor.Current, "item")) 1617 require.True(t, containsKey(cursor.Current, "instock")) 1618 1619 instock, err := cursor.Current.LookupErr("instock") 1620 require.NoError(t, err) 1621 vals, err := instock.Array().Values() 1622 require.NoError(t, err) 1623 require.Equal(t, len(vals), 2) 1624 1625 } 1626 1627 require.NoError(t, cursor.Err()) 1628 } 1629 1630} 1631 1632// DeleteExamples contains examples of delete operations. 1633func DeleteExamples(t *testing.T, db *mongo.Database) { 1634 coll := db.Collection("inventory_delete") 1635 1636 err := coll.Drop(context.Background()) 1637 require.NoError(t, err) 1638 1639 { 1640 // Start Example 55 1641 docs := []interface{}{ 1642 bson.D{ 1643 {"item", "journal"}, 1644 {"qty", 25}, 1645 {"size", bson.D{ 1646 {"h", 14}, 1647 {"w", 21}, 1648 {"uom", "cm"}, 1649 }}, 1650 {"status", "A"}, 1651 }, 1652 bson.D{ 1653 {"item", "notebook"}, 1654 {"qty", 50}, 1655 {"size", bson.D{ 1656 {"h", 8.5}, 1657 {"w", 11}, 1658 {"uom", "in"}, 1659 }}, 1660 {"status", "P"}, 1661 }, 1662 bson.D{ 1663 {"item", "paper"}, 1664 {"qty", 100}, 1665 {"size", bson.D{ 1666 {"h", 8.5}, 1667 {"w", 11}, 1668 {"uom", "in"}, 1669 }}, 1670 {"status", "D"}, 1671 }, 1672 bson.D{ 1673 {"item", "planner"}, 1674 {"qty", 75}, 1675 {"size", bson.D{ 1676 {"h", 22.85}, 1677 {"w", 30}, 1678 {"uom", "cm"}, 1679 }}, 1680 {"status", "D"}, 1681 }, 1682 bson.D{ 1683 {"item", "postcard"}, 1684 {"qty", 45}, 1685 {"size", bson.D{ 1686 {"h", 10}, 1687 {"w", 15.25}, 1688 {"uom", "cm"}, 1689 }}, 1690 {"status", "A"}, 1691 }, 1692 } 1693 1694 result, err := coll.InsertMany(context.Background(), docs) 1695 1696 // End Example 55 1697 1698 require.NoError(t, err) 1699 require.Len(t, result.InsertedIDs, 5) 1700 } 1701 1702 { 1703 // Start Example 57 1704 1705 result, err := coll.DeleteMany( 1706 context.Background(), 1707 bson.D{ 1708 {"status", "A"}, 1709 }, 1710 ) 1711 1712 // End Example 57 1713 1714 require.NoError(t, err) 1715 require.Equal(t, int64(2), result.DeletedCount) 1716 } 1717 1718 { 1719 // Start Example 58 1720 1721 result, err := coll.DeleteOne( 1722 context.Background(), 1723 bson.D{ 1724 {"status", "D"}, 1725 }, 1726 ) 1727 1728 // End Example 58 1729 1730 require.NoError(t, err) 1731 require.Equal(t, int64(1), result.DeletedCount) 1732 1733 } 1734 1735 { 1736 // Start Example 56 1737 1738 result, err := coll.DeleteMany(context.Background(), bson.D{}) 1739 1740 // End Example 56 1741 1742 require.NoError(t, err) 1743 require.Equal(t, int64(2), result.DeletedCount) 1744 } 1745} 1746 1747var log = logger.New(ioutil.Discard, "", logger.LstdFlags) 1748 1749// Start Transactions Intro Example 1 1750 1751// UpdateEmployeeInfo is an example function demonstrating transactions. 1752func UpdateEmployeeInfo(ctx context.Context, client *mongo.Client) error { 1753 employees := client.Database("hr").Collection("employees") 1754 events := client.Database("reporting").Collection("events") 1755 1756 return client.UseSession(ctx, func(sctx mongo.SessionContext) error { 1757 err := sctx.StartTransaction(options.Transaction(). 1758 SetReadConcern(readconcern.Snapshot()). 1759 SetWriteConcern(writeconcern.New(writeconcern.WMajority())), 1760 ) 1761 if err != nil { 1762 return err 1763 } 1764 1765 _, err = employees.UpdateOne(sctx, bson.D{{"employee", 3}}, bson.D{{"$set", bson.D{{"status", "Inactive"}}}}) 1766 if err != nil { 1767 sctx.AbortTransaction(sctx) 1768 log.Println("caught exception during transaction, aborting.") 1769 return err 1770 } 1771 _, err = events.InsertOne(sctx, bson.D{{"employee", 3}, {"status", bson.D{{"new", "Inactive"}, {"old", "Active"}}}}) 1772 if err != nil { 1773 sctx.AbortTransaction(sctx) 1774 log.Println("caught exception during transaction, aborting.") 1775 return err 1776 } 1777 1778 for { 1779 err = sctx.CommitTransaction(sctx) 1780 switch e := err.(type) { 1781 case nil: 1782 return nil 1783 case mongo.CommandError: 1784 if e.HasErrorLabel("UnknownTransactionCommitResult") { 1785 log.Println("UnknownTransactionCommitResult, retrying commit operation...") 1786 continue 1787 } 1788 log.Println("Error during commit...") 1789 return e 1790 default: 1791 log.Println("Error during commit...") 1792 return e 1793 } 1794 } 1795 }) 1796} 1797 1798// End Transactions Intro Example 1 1799 1800// Start Transactions Retry Example 1 1801 1802// RunTransactionWithRetry is an example function demonstrating transaction retry logic. 1803func RunTransactionWithRetry(sctx mongo.SessionContext, txnFn func(mongo.SessionContext) error) error { 1804 for { 1805 err := txnFn(sctx) // Performs transaction. 1806 if err == nil { 1807 return nil 1808 } 1809 1810 log.Println("Transaction aborted. Caught exception during transaction.") 1811 1812 // If transient error, retry the whole transaction 1813 if cmdErr, ok := err.(mongo.CommandError); ok && cmdErr.HasErrorLabel("TransientTransactionError") { 1814 log.Println("TransientTransactionError, retrying transaction...") 1815 continue 1816 } 1817 return err 1818 } 1819} 1820 1821// End Transactions Retry Example 1 1822 1823// Start Transactions Retry Example 2 1824 1825// CommitWithRetry is an example function demonstrating transaction commit with retry logic. 1826func CommitWithRetry(sctx mongo.SessionContext) error { 1827 for { 1828 err := sctx.CommitTransaction(sctx) 1829 switch e := err.(type) { 1830 case nil: 1831 log.Println("Transaction committed.") 1832 return nil 1833 case mongo.CommandError: 1834 // Can retry commit 1835 if e.HasErrorLabel("UnknownTransactionCommitResult") { 1836 log.Println("UnknownTransactionCommitResult, retrying commit operation...") 1837 continue 1838 } 1839 log.Println("Error during commit...") 1840 return e 1841 default: 1842 log.Println("Error during commit...") 1843 return e 1844 } 1845 } 1846} 1847 1848// End Transactions Retry Example 2 1849 1850// TransactionsExamples contains examples for transaction operations. 1851func TransactionsExamples(ctx context.Context, client *mongo.Client) error { 1852 _, err := client.Database("hr").Collection("employees").InsertOne(ctx, bson.D{{"pi", 3.14159}}) 1853 if err != nil { 1854 return err 1855 } 1856 _, err = client.Database("hr").Collection("employees").DeleteOne(ctx, bson.D{{"pi", 3.14159}}) 1857 if err != nil { 1858 return err 1859 } 1860 _, err = client.Database("reporting").Collection("events").InsertOne(ctx, bson.D{{"pi", 3.14159}}) 1861 if err != nil { 1862 return err 1863 } 1864 _, err = client.Database("reporting").Collection("events").DeleteOne(ctx, bson.D{{"pi", 3.14159}}) 1865 if err != nil { 1866 return err 1867 } 1868 // Start Transactions Retry Example 3 1869 1870 runTransactionWithRetry := func(sctx mongo.SessionContext, txnFn func(mongo.SessionContext) error) error { 1871 for { 1872 err := txnFn(sctx) // Performs transaction. 1873 if err == nil { 1874 return nil 1875 } 1876 1877 log.Println("Transaction aborted. Caught exception during transaction.") 1878 1879 // If transient error, retry the whole transaction 1880 if cmdErr, ok := err.(mongo.CommandError); ok && cmdErr.HasErrorLabel("TransientTransactionError") { 1881 log.Println("TransientTransactionError, retrying transaction...") 1882 continue 1883 } 1884 return err 1885 } 1886 } 1887 1888 commitWithRetry := func(sctx mongo.SessionContext) error { 1889 for { 1890 err := sctx.CommitTransaction(sctx) 1891 switch e := err.(type) { 1892 case nil: 1893 log.Println("Transaction committed.") 1894 return nil 1895 case mongo.CommandError: 1896 // Can retry commit 1897 if e.HasErrorLabel("UnknownTransactionCommitResult") { 1898 log.Println("UnknownTransactionCommitResult, retrying commit operation...") 1899 continue 1900 } 1901 log.Println("Error during commit...") 1902 return e 1903 default: 1904 log.Println("Error during commit...") 1905 return e 1906 } 1907 } 1908 } 1909 1910 // Updates two collections in a transaction. 1911 updateEmployeeInfo := func(sctx mongo.SessionContext) error { 1912 employees := client.Database("hr").Collection("employees") 1913 events := client.Database("reporting").Collection("events") 1914 1915 err := sctx.StartTransaction(options.Transaction(). 1916 SetReadConcern(readconcern.Snapshot()). 1917 SetWriteConcern(writeconcern.New(writeconcern.WMajority())), 1918 ) 1919 if err != nil { 1920 return err 1921 } 1922 1923 _, err = employees.UpdateOne(sctx, bson.D{{"employee", 3}}, bson.D{{"$set", bson.D{{"status", "Inactive"}}}}) 1924 if err != nil { 1925 sctx.AbortTransaction(sctx) 1926 log.Println("caught exception during transaction, aborting.") 1927 return err 1928 } 1929 _, err = events.InsertOne(sctx, bson.D{{"employee", 3}, {"status", bson.D{{"new", "Inactive"}, {"old", "Active"}}}}) 1930 if err != nil { 1931 sctx.AbortTransaction(sctx) 1932 log.Println("caught exception during transaction, aborting.") 1933 return err 1934 } 1935 1936 return commitWithRetry(sctx) 1937 } 1938 1939 return client.UseSessionWithOptions( 1940 ctx, options.Session().SetDefaultReadPreference(readpref.Primary()), 1941 func(sctx mongo.SessionContext) error { 1942 return runTransactionWithRetry(sctx, updateEmployeeInfo) 1943 }, 1944 ) 1945} 1946 1947// End Transactions Retry Example 3 1948 1949// Start Transactions withTxn API Example 1 1950 1951// WithTransactionExample is an example of using the Session.WithTransaction function. 1952func WithTransactionExample() { 1953 ctx := context.Background() 1954 // For a replica set, include the replica set name and a seedlist of the members in the URI string; e.g. 1955 // uri := "mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017/?replicaSet=myRepl" 1956 // For a sharded cluster, connect to the mongos instances; e.g. 1957 // uri := "mongodb://mongos0.example.com:27017,mongos1.example.com:27017/" 1958 var uri string 1959 1960 clientOpts := options.Client().ApplyURI(uri) 1961 client, err := mongo.Connect(ctx, clientOpts) 1962 if err != nil { 1963 panic(err) 1964 } 1965 defer func() { _ = client.Disconnect(ctx) }() 1966 1967 // Prereq: Create collections. 1968 wcMajority := writeconcern.New(writeconcern.WMajority(), writeconcern.WTimeout(1*time.Second)) 1969 wcMajorityCollectionOpts := options.Collection().SetWriteConcern(wcMajority) 1970 fooColl := client.Database("mydb1").Collection("foo", wcMajorityCollectionOpts) 1971 barColl := client.Database("mydb1").Collection("bar", wcMajorityCollectionOpts) 1972 1973 // Step 1: Define the callback that specifies the sequence of operations to perform inside the transaction. 1974 callback := func(sessCtx mongo.SessionContext) (interface{}, error) { 1975 // Important: You must pass sessCtx as the Context parameter to the operations for them to be executed in the 1976 // transaction. 1977 if _, err := fooColl.InsertOne(sessCtx, bson.D{{"abc", 1}}); err != nil { 1978 return nil, err 1979 } 1980 if _, err := barColl.InsertOne(sessCtx, bson.D{{"xyz", 999}}); err != nil { 1981 return nil, err 1982 } 1983 1984 return nil, nil 1985 } 1986 1987 // Step 2: Start a session and run the callback using WithTransaction. 1988 session, err := client.StartSession() 1989 if err != nil { 1990 panic(err) 1991 } 1992 defer session.EndSession(ctx) 1993 1994 result, err := session.WithTransaction(ctx, callback) 1995 if err != nil { 1996 panic(err) 1997 } 1998 fmt.Printf("result: %v\n", result) 1999} 2000 2001// End Transactions withTxn API Example 1 2002 2003// ChangeStreamExamples contains examples of changestream operations. 2004func ChangeStreamExamples(t *testing.T, db *mongo.Database) { 2005 ctx := context.Background() 2006 2007 coll := db.Collection("inventory_changestream") 2008 2009 err := coll.Drop(context.Background()) 2010 require.NoError(t, err) 2011 2012 _, err = coll.InsertOne(ctx, bson.D{{"x", int32(1)}}) 2013 require.NoError(t, err) 2014 2015 var stop int32 2016 2017 doInserts := func(coll *mongo.Collection) { 2018 for atomic.LoadInt32(&stop) == 0 { 2019 _, err = coll.InsertOne(ctx, bson.D{{"x", 1}}) 2020 time.Sleep(10 * time.Millisecond) 2021 coll.DeleteOne(ctx, bson.D{{"x", 1}}) 2022 } 2023 } 2024 2025 go doInserts(coll) 2026 2027 { 2028 // Start Changestream Example 1 2029 2030 cs, err := coll.Watch(ctx, mongo.Pipeline{}) 2031 require.NoError(t, err) 2032 defer cs.Close(ctx) 2033 2034 ok := cs.Next(ctx) 2035 next := cs.Current 2036 2037 // End Changestream Example 1 2038 2039 require.True(t, ok) 2040 require.NoError(t, err) 2041 require.NotEqual(t, len(next), 0) 2042 } 2043 { 2044 // Start Changestream Example 2 2045 2046 cs, err := coll.Watch(ctx, mongo.Pipeline{}, options.ChangeStream().SetFullDocument(options.UpdateLookup)) 2047 require.NoError(t, err) 2048 defer cs.Close(ctx) 2049 2050 ok := cs.Next(ctx) 2051 next := cs.Current 2052 2053 // End Changestream Example 2 2054 2055 require.True(t, ok) 2056 require.NoError(t, err) 2057 require.NotEqual(t, len(next), 0) 2058 } 2059 2060 { 2061 original, err := coll.Watch(ctx, mongo.Pipeline{}) 2062 require.NoError(t, err) 2063 defer original.Close(ctx) 2064 2065 ok := original.Next(ctx) 2066 require.True(t, ok) 2067 2068 // Start Changestream Example 3 2069 resumeToken := original.ResumeToken() 2070 2071 cs, err := coll.Watch(ctx, mongo.Pipeline{}, options.ChangeStream().SetResumeAfter(resumeToken)) 2072 require.NoError(t, err) 2073 defer cs.Close(ctx) 2074 2075 ok = cs.Next(ctx) 2076 result := cs.Current 2077 2078 // End Changestream Example 3 2079 2080 require.True(t, ok) 2081 require.NoError(t, err) 2082 require.NotEqual(t, len(result), 0) 2083 } 2084 2085 { 2086 // Start Changestream Example 4 2087 pipeline := mongo.Pipeline{bson.D{{"$match", bson.D{{"$or", 2088 bson.A{ 2089 bson.D{{"fullDocument.username", "alice"}}, 2090 bson.D{{"operationType", "delete"}}}}}, 2091 }}} 2092 cs, err := coll.Watch(ctx, pipeline) 2093 require.NoError(t, err) 2094 defer cs.Close(ctx) 2095 2096 ok := cs.Next(ctx) 2097 next := cs.Current 2098 2099 // End Changestream Example 4 2100 2101 require.True(t, ok) 2102 require.NoError(t, err) 2103 require.NotEqual(t, len(next), 0) 2104 } 2105 2106 atomic.StoreInt32(&stop, 1) 2107} 2108 2109// AggregationExamples contains examples of aggregation operations. 2110func AggregationExamples(t *testing.T, db *mongo.Database) { 2111 ctx := context.Background() 2112 2113 salesColl := db.Collection("sales") 2114 airlinesColl := db.Collection("airlines") 2115 airAlliancesColl := db.Collection("air_alliances") 2116 2117 err := salesColl.Drop(ctx) 2118 require.NoError(t, err) 2119 err = airlinesColl.Drop(ctx) 2120 require.NoError(t, err) 2121 err = airAlliancesColl.Drop(ctx) 2122 require.NoError(t, err) 2123 2124 date20180208 := parseDate(t, "2018-02-08T09:00:00.000Z") 2125 date20180109 := parseDate(t, "2018-01-09T07:12:00.000Z") 2126 date20180127 := parseDate(t, "2018-01-27T09:13:00.000Z") 2127 date20180203 := parseDate(t, "2018-02-03T07:58:00.000Z") 2128 date20180205 := parseDate(t, "2018-02-05T06:03:00.000Z") 2129 date20180111 := parseDate(t, "2018-01-11T07:15:00.000Z") 2130 2131 sales := []interface{}{ 2132 bson.D{ 2133 {"date", date20180208}, 2134 {"items", bson.A{ 2135 bson.D{ 2136 {"fruit", "kiwi"}, 2137 {"quantity", 2}, 2138 {"price", 0.5}, 2139 }, 2140 bson.D{ 2141 {"fruit", "apple"}, 2142 {"quantity", 1}, 2143 {"price", 1.0}, 2144 }, 2145 }}, 2146 }, 2147 bson.D{ 2148 {"date", date20180109}, 2149 {"items", bson.A{ 2150 bson.D{ 2151 {"fruit", "banana"}, 2152 {"quantity", 8}, 2153 {"price", 1.0}, 2154 }, 2155 bson.D{ 2156 {"fruit", "apple"}, 2157 {"quantity", 1}, 2158 {"price", 1.0}, 2159 }, 2160 bson.D{ 2161 {"fruit", "papaya"}, 2162 {"quantity", 1}, 2163 {"price", 4.0}, 2164 }, 2165 }}, 2166 }, 2167 bson.D{ 2168 {"date", date20180127}, 2169 {"items", bson.A{ 2170 bson.D{ 2171 {"fruit", "banana"}, 2172 {"quantity", 1}, 2173 {"price", 1.0}, 2174 }, 2175 }}, 2176 }, 2177 bson.D{ 2178 {"date", date20180203}, 2179 {"items", bson.A{ 2180 bson.D{ 2181 {"fruit", "banana"}, 2182 {"quantity", 1}, 2183 {"price", 1.0}, 2184 }, 2185 }}, 2186 }, 2187 bson.D{ 2188 {"date", date20180205}, 2189 {"items", bson.A{ 2190 bson.D{ 2191 {"fruit", "banana"}, 2192 {"quantity", 1}, 2193 {"price", 1.0}, 2194 }, 2195 bson.D{ 2196 {"fruit", "mango"}, 2197 {"quantity", 2}, 2198 {"price", 2.0}, 2199 }, 2200 bson.D{ 2201 {"fruit", "apple"}, 2202 {"quantity", 1}, 2203 {"price", 1.0}, 2204 }, 2205 }}, 2206 }, 2207 bson.D{ 2208 {"date", date20180111}, 2209 {"items", bson.A{ 2210 bson.D{ 2211 {"fruit", "banana"}, 2212 {"quantity", 1}, 2213 {"price", 1.0}, 2214 }, 2215 bson.D{ 2216 {"fruit", "apple"}, 2217 {"quantity", 1}, 2218 {"price", 1.0}, 2219 }, 2220 bson.D{ 2221 {"fruit", "papaya"}, 2222 {"quantity", 3}, 2223 {"price", 4.0}, 2224 }, 2225 }}, 2226 }, 2227 } 2228 airlines := []interface{}{ 2229 bson.D{ 2230 {"airline", 17}, 2231 {"name", "Air Canada"}, 2232 {"alias", "AC"}, 2233 {"iata", "ACA"}, 2234 {"icao", "AIR CANADA"}, 2235 {"active", "Y"}, 2236 {"country", "Canada"}, 2237 {"base", "TAL"}, 2238 }, 2239 bson.D{ 2240 {"airline", 18}, 2241 {"name", "Turkish Airlines"}, 2242 {"alias", "YK"}, 2243 {"iata", "TRK"}, 2244 {"icao", "TURKISH"}, 2245 {"active", "Y"}, 2246 {"country", "Turkey"}, 2247 {"base", "AET"}, 2248 }, 2249 bson.D{ 2250 {"airline", 22}, 2251 {"name", "Saudia"}, 2252 {"alias", "SV"}, 2253 {"iata", "SVA"}, 2254 {"icao", "SAUDIA"}, 2255 {"active", "Y"}, 2256 {"country", "Saudi Arabia"}, 2257 {"base", "JSU"}, 2258 }, 2259 bson.D{ 2260 {"airline", 29}, 2261 {"name", "Finnair"}, 2262 {"alias", "AY"}, 2263 {"iata", "FIN"}, 2264 {"icao", "FINNAIR"}, 2265 {"active", "Y"}, 2266 {"country", "Finland"}, 2267 {"base", "JMZ"}, 2268 }, 2269 bson.D{ 2270 {"airline", 34}, 2271 {"name", "Afric'air Express"}, 2272 {"alias", ""}, 2273 {"iata", "AAX"}, 2274 {"icao", "AFREX"}, 2275 {"active", "N"}, 2276 {"country", "Ivory Coast"}, 2277 {"base", "LOK"}, 2278 }, 2279 bson.D{ 2280 {"airline", 37}, 2281 {"name", "Artem-Avia"}, 2282 {"alias", ""}, 2283 {"iata", "ABA"}, 2284 {"icao", "ARTEM-AVIA"}, 2285 {"active", "N"}, 2286 {"country", "Ukraine"}, 2287 {"base", "JBR"}, 2288 }, 2289 bson.D{ 2290 {"airline", 38}, 2291 {"name", "Lufthansa"}, 2292 {"alias", "LH"}, 2293 {"iata", "DLH"}, 2294 {"icao", "LUFTHANSA"}, 2295 {"active", "Y"}, 2296 {"country", "Germany"}, 2297 {"base", "CYS"}, 2298 }, 2299 } 2300 airAlliances := []interface{}{ 2301 bson.D{ 2302 {"name", "Star Alliance"}, 2303 {"airlines", bson.A{ 2304 "Air Canada", 2305 "Avianca", 2306 "Air China", 2307 "Air New Zealand", 2308 "Asiana Airlines", 2309 "Brussels Airlines", 2310 "Copa Airlines", 2311 "Croatia Airlines", 2312 "EgyptAir", 2313 "TAP Portugal", 2314 "United Airlines", 2315 "Turkish Airlines", 2316 "Swiss International Air Lines", 2317 "Lufthansa", 2318 }}, 2319 }, 2320 bson.D{ 2321 {"name", "SkyTeam"}, 2322 {"airlines", bson.A{ 2323 "Aerolinias Argentinas", 2324 "Aeromexico", 2325 "Air Europa", 2326 "Air France", 2327 "Alitalia", 2328 "Delta Air Lines", 2329 "Garuda Indonesia", 2330 "Kenya Airways", 2331 "KLM", 2332 "Korean Air", 2333 "Middle East Airlines", 2334 "Saudia", 2335 }}, 2336 }, 2337 bson.D{ 2338 {"name", "OneWorld"}, 2339 {"airlines", bson.A{ 2340 "Air Berlin", 2341 "American Airlines", 2342 "British Airways", 2343 "Cathay Pacific", 2344 "Finnair", 2345 "Iberia Airlines", 2346 "Japan Airlines", 2347 "LATAM Chile", 2348 "LATAM Brasil", 2349 "Malasya Airlines", 2350 "Canadian Airlines", 2351 }}, 2352 }, 2353 } 2354 2355 salesResult, salesErr := salesColl.InsertMany(ctx, sales) 2356 airlinesResult, airlinesErr := airlinesColl.InsertMany(ctx, airlines) 2357 airAlliancesResult, airAlliancesErr := airAlliancesColl.InsertMany(ctx, airAlliances) 2358 2359 require.NoError(t, salesErr) 2360 require.Len(t, salesResult.InsertedIDs, 6) 2361 require.NoError(t, airlinesErr) 2362 require.Len(t, airlinesResult.InsertedIDs, 7) 2363 require.NoError(t, airAlliancesErr) 2364 require.Len(t, airAlliancesResult.InsertedIDs, 3) 2365 2366 { 2367 // Start Aggregation Example 1 2368 pipeline := mongo.Pipeline{ 2369 { 2370 {"$match", bson.D{ 2371 {"items.fruit", "banana"}, 2372 }}, 2373 }, 2374 { 2375 {"$sort", bson.D{ 2376 {"date", 1}, 2377 }}, 2378 }, 2379 } 2380 2381 cursor, err := salesColl.Aggregate(ctx, pipeline) 2382 2383 // End Aggregation Example 1 2384 2385 require.NoError(t, err) 2386 defer cursor.Close(ctx) 2387 requireCursorLength(t, cursor, 5) 2388 } 2389 { 2390 // Start Aggregation Example 2 2391 pipeline := mongo.Pipeline{ 2392 { 2393 {"$unwind", "$items"}, 2394 }, 2395 { 2396 {"$match", bson.D{ 2397 {"items.fruit", "banana"}, 2398 }}, 2399 }, 2400 { 2401 {"$group", bson.D{ 2402 {"_id", bson.D{ 2403 {"day", bson.D{ 2404 {"$dayOfWeek", "$date"}, 2405 }}, 2406 }}, 2407 {"count", bson.D{ 2408 {"$sum", "$items.quantity"}, 2409 }}, 2410 }}, 2411 }, 2412 { 2413 {"$project", bson.D{ 2414 {"dayOfWeek", "$_id.day"}, 2415 {"numberSold", "$count"}, 2416 {"_id", 0}, 2417 }}, 2418 }, 2419 { 2420 {"$sort", bson.D{ 2421 {"numberSold", 1}, 2422 }}, 2423 }, 2424 } 2425 2426 cursor, err := salesColl.Aggregate(ctx, pipeline) 2427 2428 // End Aggregation Example 2 2429 2430 require.NoError(t, err) 2431 defer cursor.Close(ctx) 2432 requireCursorLength(t, cursor, 4) 2433 } 2434 { 2435 // Start Aggregation Example 3 2436 pipeline := mongo.Pipeline{ 2437 { 2438 {"$unwind", "$items"}, 2439 }, 2440 { 2441 {"$group", bson.D{ 2442 {"_id", bson.D{ 2443 {"day", bson.D{ 2444 {"$dayOfWeek", "$date"}, 2445 }}, 2446 }}, 2447 {"items_sold", bson.D{ 2448 {"$sum", "$items.quantity"}, 2449 }}, 2450 {"revenue", bson.D{ 2451 {"$sum", bson.D{ 2452 {"$multiply", bson.A{"$items.quantity", "$items.price"}}, 2453 }}, 2454 }}, 2455 }}, 2456 }, 2457 { 2458 {"$project", bson.D{ 2459 {"day", "$_id.day"}, 2460 {"revenue", 1}, 2461 {"items_sold", 1}, 2462 {"discount", bson.D{ 2463 {"$cond", bson.D{ 2464 {"if", bson.D{ 2465 {"$lte", bson.A{"$revenue", 250}}, 2466 }}, 2467 {"then", 25}, 2468 {"else", 0}, 2469 }}, 2470 }}, 2471 }}, 2472 }, 2473 } 2474 2475 cursor, err := salesColl.Aggregate(ctx, pipeline) 2476 2477 // End Aggregation Example 3 2478 2479 require.NoError(t, err) 2480 defer cursor.Close(ctx) 2481 requireCursorLength(t, cursor, 4) 2482 } 2483 { 2484 // Start Aggregation Example 4 2485 pipeline := mongo.Pipeline{ 2486 { 2487 {"$lookup", bson.D{ 2488 {"from", "air_airlines"}, 2489 {"let", bson.D{ 2490 {"constituents", "$airlines"}}, 2491 }, 2492 {"pipeline", bson.A{bson.D{ 2493 {"$match", bson.D{ 2494 {"$expr", bson.D{ 2495 {"$in", bson.A{"$name", "$$constituents"}}, 2496 }}, 2497 }}, 2498 }}}, 2499 {"as", "airlines"}, 2500 }}, 2501 }, 2502 { 2503 {"$project", bson.D{ 2504 {"_id", 0}, 2505 {"name", 1}, 2506 {"airlines", bson.D{ 2507 {"$filter", bson.D{ 2508 {"input", "$airlines"}, 2509 {"as", "airline"}, 2510 {"cond", bson.D{ 2511 {"$eq", bson.A{"$$airline.country", "Canada"}}, 2512 }}, 2513 }}, 2514 }}, 2515 }}, 2516 }, 2517 } 2518 2519 cursor, err := airAlliancesColl.Aggregate(ctx, pipeline) 2520 2521 // End Aggregation Example 4 2522 2523 require.NoError(t, err) 2524 defer cursor.Close(ctx) 2525 requireCursorLength(t, cursor, 3) 2526 } 2527} 2528 2529// RunCommandExamples contains examples of RunCommand operations. 2530func RunCommandExamples(t *testing.T, db *mongo.Database) { 2531 ctx := context.Background() 2532 2533 coll := db.Collection("restaurants") 2534 2535 err := coll.Drop(ctx) 2536 require.NoError(t, err) 2537 2538 restaurants := []interface{}{ 2539 bson.D{ 2540 {"name", "Chez Panisse"}, 2541 {"city", "Oakland"}, 2542 {"state", "California"}, 2543 {"country", "United States"}, 2544 {"rating", 4.4}, 2545 }, 2546 bson.D{ 2547 {"name", "Central"}, 2548 {"city", "Lima"}, 2549 {"country", "Peru"}, 2550 {"rating", 4.8}, 2551 }, 2552 bson.D{ 2553 {"name", "Eleven Madison Park"}, 2554 {"city", "New York City"}, 2555 {"state", "New York"}, 2556 {"country", "United States"}, 2557 {"rating", 4.6}, 2558 }, 2559 bson.D{ 2560 {"name", "Gaggan"}, 2561 {"city", "Bangkok"}, 2562 {"country", "Thailand"}, 2563 {"rating", 4.3}, 2564 }, 2565 bson.D{ 2566 {"name", "Dad's Grill"}, 2567 {"city", "Oklahoma City"}, 2568 {"state", "Oklahoma"}, 2569 {"country", "United States"}, 2570 {"rating", 2.1}, 2571 }, 2572 } 2573 2574 result, err := coll.InsertMany(ctx, restaurants) 2575 require.NoError(t, err) 2576 require.Len(t, result.InsertedIDs, 5) 2577 2578 { 2579 // Start RunCommand Example 1 2580 res := db.RunCommand(ctx, bson.D{{"buildInfo", 1}}) 2581 2582 // End RunCommand Example 1 2583 2584 err := res.Err() 2585 require.NoError(t, err) 2586 } 2587 { 2588 // Start RunCommand Example 2 2589 res := db.RunCommand(ctx, bson.D{{"collStats", "restaurants"}}) 2590 2591 // End RunCommand Example 2 2592 2593 err := res.Err() 2594 require.NoError(t, err) 2595 } 2596} 2597 2598// IndexExamples contains examples of Index operations. 2599func IndexExamples(t *testing.T, db *mongo.Database) { 2600 ctx := context.Background() 2601 2602 recordsColl := db.Collection("records") 2603 restaurantsColl := db.Collection("restaurants") 2604 2605 err := recordsColl.Drop(ctx) 2606 require.NoError(t, err) 2607 err = restaurantsColl.Drop(ctx) 2608 require.NoError(t, err) 2609 2610 records := []interface{}{ 2611 bson.D{ 2612 {"student", "Marty McFly"}, 2613 {"classYear", 1986}, 2614 {"school", "Hill Valley High"}, 2615 {"score", 56.5}, 2616 }, 2617 bson.D{ 2618 {"student", "Ferris F. Bueller"}, 2619 {"classYear", 1987}, 2620 {"school", "Glenbrook North High"}, 2621 {"status", "Suspended"}, 2622 {"score", 76.0}, 2623 }, 2624 bson.D{ 2625 {"student", "Reynard Muldoon"}, 2626 {"classYear", 2007}, 2627 {"school", "Stonetown Middle"}, 2628 {"score", 99.9}, 2629 }, 2630 } 2631 restaurants := []interface{}{ 2632 bson.D{ 2633 {"name", "Chez Panisse"}, 2634 {"cuisine", "American/French"}, 2635 {"city", "Oakland"}, 2636 {"state", "California"}, 2637 {"country", "United States"}, 2638 {"rating", 4.9}, 2639 }, 2640 bson.D{ 2641 {"name", "Central"}, 2642 {"cuisine", "Peruvian"}, 2643 {"city", "Lima"}, 2644 {"country", "Peru"}, 2645 {"rating", 5.8}, 2646 }, 2647 bson.D{ 2648 {"name", "Eleven Madison Park"}, 2649 {"cuisine", "French"}, 2650 {"city", "New York City"}, 2651 {"state", "New York"}, 2652 {"country", "United States"}, 2653 {"rating", 7.1}, 2654 }, 2655 bson.D{ 2656 {"name", "Gaggan"}, 2657 {"cuisine", "Thai Fusion"}, 2658 {"city", "Bangkok"}, 2659 {"country", "Thailand"}, 2660 {"rating", 9.2}, 2661 }, 2662 bson.D{ 2663 {"name", "Dad's Grill"}, 2664 {"cuisine", "BBQ"}, 2665 {"city", "Oklahoma City"}, 2666 {"state", "Oklahoma"}, 2667 {"country", "United States"}, 2668 {"rating", 2.1}, 2669 }, 2670 } 2671 2672 recordsResult, recordsErr := recordsColl.InsertMany(ctx, records) 2673 restaurantsResult, restaurantsErr := restaurantsColl.InsertMany(ctx, restaurants) 2674 2675 require.NoError(t, recordsErr) 2676 require.Len(t, recordsResult.InsertedIDs, 3) 2677 require.NoError(t, restaurantsErr) 2678 require.Len(t, restaurantsResult.InsertedIDs, 5) 2679 2680 { 2681 // Start Index Example 1 2682 indexModel := mongo.IndexModel{ 2683 Keys: bson.D{ 2684 {"score", 1}, 2685 }, 2686 } 2687 _, err := recordsColl.Indexes().CreateOne(ctx, indexModel) 2688 2689 // End Index Example 1 2690 2691 require.NoError(t, err) 2692 } 2693 { 2694 // Start Index Example 2 2695 partialFilterExpression := bson.D{ 2696 {"rating", bson.D{ 2697 {"$gt", 5}, 2698 }}, 2699 } 2700 indexModel := mongo.IndexModel{ 2701 Keys: bson.D{ 2702 {"cuisine", 1}, 2703 {"name", 1}, 2704 }, 2705 Options: options.Index().SetPartialFilterExpression(partialFilterExpression), 2706 } 2707 2708 _, err := restaurantsColl.Indexes().CreateOne(ctx, indexModel) 2709 2710 // End Index Example 2 2711 2712 require.NoError(t, err) 2713 } 2714} 2715