Skip to content

Commit 5efe8ec

Browse files
committed
Support partial indexes
1 parent 0cf7028 commit 5efe8ec

File tree

2 files changed

+63
-35
lines changed

2 files changed

+63
-35
lines changed

session.go

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,30 +1058,32 @@ func (db *Database) RemoveUser(user string) error {
10581058
}
10591059

10601060
type indexSpec struct {
1061-
Name, NS string
1062-
Key bson.D
1063-
Unique bool ",omitempty"
1064-
DropDups bool "dropDups,omitempty"
1065-
Background bool ",omitempty"
1066-
Sparse bool ",omitempty"
1067-
Bits int ",omitempty"
1068-
Min, Max float64 ",omitempty"
1069-
BucketSize float64 "bucketSize,omitempty"
1070-
ExpireAfter int "expireAfterSeconds,omitempty"
1071-
Weights bson.D ",omitempty"
1072-
DefaultLanguage string "default_language,omitempty"
1073-
LanguageOverride string "language_override,omitempty"
1074-
TextIndexVersion int "textIndexVersion,omitempty"
1061+
Name, NS string
1062+
Key bson.D
1063+
Unique bool ",omitempty"
1064+
DropDups bool "dropDups,omitempty"
1065+
Background bool ",omitempty"
1066+
Sparse bool ",omitempty"
1067+
Bits int ",omitempty"
1068+
Min, Max float64 ",omitempty"
1069+
BucketSize float64 "bucketSize,omitempty"
1070+
ExpireAfter int "expireAfterSeconds,omitempty"
1071+
Weights bson.D ",omitempty"
1072+
DefaultLanguage string "default_language,omitempty"
1073+
LanguageOverride string "language_override,omitempty"
1074+
TextIndexVersion int "textIndexVersion,omitempty"
1075+
PartialFilterExpression bson.M "partialFilterExpression,omitempty"
10751076

10761077
Collation *Collation "collation,omitempty"
10771078
}
10781079

10791080
type Index struct {
1080-
Key []string // Index key fields; prefix name with dash (-) for descending order
1081-
Unique bool // Prevent two documents from having the same index key
1082-
DropDups bool // Drop documents with the same index key as a previously indexed one
1083-
Background bool // Build index in background and return immediately
1084-
Sparse bool // Only index documents containing the Key fields
1081+
Key []string // Index key fields; prefix name with dash (-) for descending order
1082+
Unique bool // Prevent two documents from having the same index key
1083+
DropDups bool // Drop documents with the same index key as a previously indexed one
1084+
Background bool // Build index in background and return immediately
1085+
Sparse bool // Only index documents containing the Key fields
1086+
PartialFilter bson.M // Partial index filter expression
10851087

10861088
// If ExpireAfter is defined the server will periodically delete
10871089
// documents with indexed time.Time older than the provided delta.
@@ -1334,6 +1336,10 @@ func (c *Collection) EnsureIndexKey(key ...string) error {
13341336
// http://www.mongodb.org/display/DOCS/Multikeys
13351337
//
13361338
func (c *Collection) EnsureIndex(index Index) error {
1339+
if index.Sparse && index.PartialFilter != nil {
1340+
return errors.New("cannot mix sparse and partial indexes")
1341+
}
1342+
13371343
keyInfo, err := parseIndexKey(index.Key)
13381344
if err != nil {
13391345
return err
@@ -1346,22 +1352,23 @@ func (c *Collection) EnsureIndex(index Index) error {
13461352
}
13471353

13481354
spec := indexSpec{
1349-
Name: keyInfo.name,
1350-
NS: c.FullName,
1351-
Key: keyInfo.key,
1352-
Unique: index.Unique,
1353-
DropDups: index.DropDups,
1354-
Background: index.Background,
1355-
Sparse: index.Sparse,
1356-
Bits: index.Bits,
1357-
Min: index.Minf,
1358-
Max: index.Maxf,
1359-
BucketSize: index.BucketSize,
1360-
ExpireAfter: int(index.ExpireAfter / time.Second),
1361-
Weights: keyInfo.weights,
1362-
DefaultLanguage: index.DefaultLanguage,
1363-
LanguageOverride: index.LanguageOverride,
1364-
Collation: index.Collation,
1355+
Name: keyInfo.name,
1356+
NS: c.FullName,
1357+
Key: keyInfo.key,
1358+
Unique: index.Unique,
1359+
DropDups: index.DropDups,
1360+
Background: index.Background,
1361+
Sparse: index.Sparse,
1362+
Bits: index.Bits,
1363+
Min: index.Minf,
1364+
Max: index.Maxf,
1365+
BucketSize: index.BucketSize,
1366+
ExpireAfter: int(index.ExpireAfter / time.Second),
1367+
Weights: keyInfo.weights,
1368+
DefaultLanguage: index.DefaultLanguage,
1369+
LanguageOverride: index.LanguageOverride,
1370+
Collation: index.Collation,
1371+
PartialFilterExpression: index.PartialFilter,
13651372
}
13661373

13671374
if spec.Min == 0 && spec.Max == 0 {
@@ -1577,6 +1584,7 @@ func indexFromSpec(spec indexSpec) Index {
15771584
LanguageOverride: spec.LanguageOverride,
15781585
ExpireAfter: time.Duration(spec.ExpireAfter) * time.Second,
15791586
Collation: spec.Collation,
1587+
PartialFilter: spec.PartialFilterExpression,
15801588
}
15811589
if float64(int(spec.Min)) == spec.Min && float64(int(spec.Max)) == spec.Max {
15821590
index.Min = int(spec.Min)

session_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3104,6 +3104,21 @@ var indexTests = []struct {
31043104
"key": M{"cn": 1},
31053105
"ns": "mydb.mycoll",
31063106
},
3107+
}, {
3108+
mgo.Index{
3109+
Key: []string{"partial"},
3110+
PartialFilter: bson.M{
3111+
"b": bson.M{"$gt": 42},
3112+
},
3113+
},
3114+
M{
3115+
"name": "partial_1",
3116+
"ns": "mydb.mycoll",
3117+
"partialFilterExpression": M{
3118+
"b": M{"$gt": 42},
3119+
},
3120+
"key": M{"partial": 1},
3121+
},
31073122
}}
31083123

31093124
func (s *S) TestEnsureIndex(c *C) {
@@ -3119,6 +3134,11 @@ func (s *S) TestEnsureIndex(c *C) {
31193134
continue
31203135
}
31213136

3137+
// Only test partial indexes on
3138+
if !s.versionAtLeast(3, 2) && test.expected["name"] == "partial_1" {
3139+
continue
3140+
}
3141+
31223142
err = coll.EnsureIndex(test.index)
31233143
msg := "text search not enabled"
31243144
if err != nil && strings.Contains(err.Error(), msg) {

0 commit comments

Comments
 (0)