diff --git a/session.go b/session.go index 5e7c99775..2b383ad40 100644 --- a/session.go +++ b/session.go @@ -2857,6 +2857,10 @@ type CollectionInfo struct { // storage engine in use. The map keys must hold the storage engine // name for which options are being specified. StorageEngine interface{} + // Specifies the default collation for the collection. + // Collation allows users to specify language-specific rules for string + // comparison, such as rules for lettercase and accent marks. + Collation *Collation } // Create explicitly creates the c collection with details of info. @@ -2900,6 +2904,10 @@ func (c *Collection) Create(info *CollectionInfo) error { if info.StorageEngine != nil { cmd = append(cmd, bson.DocElem{"storageEngine", info.StorageEngine}) } + if info.Collation != nil { + cmd = append(cmd, bson.DocElem{"collation", info.Collation}) + } + return c.Database.Run(cmd, nil) } @@ -3039,6 +3047,30 @@ func (q *Query) Sort(fields ...string) *Query { return q } +// Collation allows to specify language-specific rules for string comparison, +// such as rules for lettercase and accent marks. +// When specifying collation, the locale field is mandatory; all other collation +// fields are optional +// +// For example, to perform a case and diacritic insensitive query: +// +// var res []bson.M +// collation := &mgo.Collation{Locale: "en", Strength: 1} +// err = db.C("mycoll").Find(bson.M{"a": "a"}).Collation(collation).All(&res) +// if err != nil { +// return err +// } +// +// This query will match following documents: +// +// {"a": "a"} +// {"a": "A"} +// {"a": "รข"} +// +// Relevant documentation: +// +// https://docs.mongodb.com/manual/reference/collation/ +// func (q *Query) Collation(collation *Collation) *Query { q.m.Lock() q.op.options.Collation = collation diff --git a/session_test.go b/session_test.go index 5f1689bea..f3bb70ec9 100644 --- a/session_test.go +++ b/session_test.go @@ -1020,6 +1020,39 @@ func (s *S) TestCreateCollectionStorageEngine(c *C) { c.Assert(err, ErrorMatches, "test is not a registered storage engine for this server") } +func (s *S) TestCreateCollectionWithCollation(c *C) { + if !s.versionAtLeast(3, 4) { + c.Skip("depends on mongodb 3.4+") + } + session, err := mgo.Dial("localhost:40001") + c.Assert(err, IsNil) + defer session.Close() + + db := session.DB("mydb") + coll := db.C("mycoll") + + info := &mgo.CollectionInfo{ + Collation: &mgo.Collation{Locale: "en", Strength: 1}, + } + err = coll.Create(info) + c.Assert(err, IsNil) + + err = coll.Insert(M{"a": "case"}) + c.Assert(err, IsNil) + + err = coll.Insert(M{"a": "CaSe"}) + c.Assert(err, IsNil) + + var docs []struct { + A string `bson:"a"` + } + err = coll.Find(bson.M{"a": "case"}).All(&docs) + c.Assert(err, IsNil) + c.Assert(docs[0].A, Equals, "case") + c.Assert(docs[1].A, Equals, "CaSe") + +} + func (s *S) TestIsDupValues(c *C) { c.Assert(mgo.IsDup(nil), Equals, false) c.Assert(mgo.IsDup(&mgo.LastError{Code: 1}), Equals, false)