-
Notifications
You must be signed in to change notification settings - Fork 917
GODRIVER-3125 Allow to set search index type #1649
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
507a0fb
e36ca41
9bbe027
290d6f7
13dabb3
13037d2
433c45e
cce9f01
5431ca5
aa96020
55f81cb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -311,4 +311,151 @@ func TestSearchIndexProse(t *testing.T) { | |
actual := doc.Lookup("latestDefinition").Value | ||
assert.Equal(mt, expected, actual, "unmatched definition") | ||
}) | ||
|
||
case7CollName, err := uuid.New() | ||
assert.NoError(mt, err, "failed to create random collection name for case #7") | ||
|
||
mt.RunOpts("case 7: Driver can successfully handle search index types when creating indexes", | ||
mtest.NewOptions().CollectionName(case7CollName.String()), | ||
func(mt *mtest.T) { | ||
ctx := context.Background() | ||
|
||
_, err := mt.Coll.InsertOne(ctx, bson.D{}) | ||
require.NoError(mt, err, "failed to insert") | ||
|
||
view := mt.Coll.SearchIndexes() | ||
|
||
definition := bson.D{{"mappings", bson.D{{"dynamic", false}}}} | ||
indexName := "test-search-index-case7-implicit" | ||
opts := options.SearchIndexes().SetName(indexName) | ||
index, err := view.CreateOne(ctx, mongo.SearchIndexModel{ | ||
Definition: definition, | ||
Options: opts, | ||
}) | ||
require.NoError(mt, err, "failed to create index") | ||
require.Equal(mt, indexName, index, "unmatched name") | ||
var doc bson.Raw | ||
for doc == nil { | ||
cursor, err := view.List(ctx, opts) | ||
require.NoError(mt, err, "failed to list") | ||
|
||
if !cursor.Next(ctx) { | ||
break | ||
} | ||
name := cursor.Current.Lookup("name").StringValue() | ||
queryable := cursor.Current.Lookup("queryable").Boolean() | ||
indexType := cursor.Current.Lookup("type").StringValue() | ||
if name == indexName && queryable { | ||
doc = cursor.Current | ||
assert.Equal(mt, indexType, "search") | ||
} else { | ||
t.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String()) | ||
time.Sleep(5 * time.Second) | ||
} | ||
} | ||
|
||
indexName = "test-search-index-case7-explicit" | ||
opts = options.SearchIndexes().SetName(indexName).SetType("search") | ||
index, err = view.CreateOne(ctx, mongo.SearchIndexModel{ | ||
Definition: definition, | ||
Options: opts, | ||
}) | ||
require.NoError(mt, err, "failed to create index") | ||
require.Equal(mt, indexName, index, "unmatched name") | ||
doc = nil | ||
for doc == nil { | ||
cursor, err := view.List(ctx, opts) | ||
require.NoError(mt, err, "failed to list") | ||
|
||
if !cursor.Next(ctx) { | ||
break | ||
} | ||
name := cursor.Current.Lookup("name").StringValue() | ||
queryable := cursor.Current.Lookup("queryable").Boolean() | ||
indexType := cursor.Current.Lookup("type").StringValue() | ||
if name == indexName && queryable { | ||
doc = cursor.Current | ||
assert.Equal(mt, indexType, "search") | ||
} else { | ||
t.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String()) | ||
time.Sleep(5 * time.Second) | ||
} | ||
} | ||
|
||
indexName = "test-search-index-case7-vector" | ||
type vectorDefinitionField struct { | ||
Type string `bson:"type"` | ||
Path string `bson:"path"` | ||
NumDimensions int `bson:"numDimensions"` | ||
Similarity string `bson:"similarity"` | ||
} | ||
|
||
type vectorDefinition struct { | ||
Fields []vectorDefinitionField `bson:"fields"` | ||
} | ||
|
||
opts = options.SearchIndexes().SetName(indexName).SetType("vectorSearch") | ||
index, err = view.CreateOne(ctx, mongo.SearchIndexModel{ | ||
Definition: vectorDefinition{ | ||
Fields: []vectorDefinitionField{{"vector", "path", 1536, "euclidean"}}, | ||
}, | ||
Options: opts, | ||
}) | ||
require.NoError(mt, err, "failed to create index") | ||
require.Equal(mt, indexName, index, "unmatched name") | ||
doc = nil | ||
for doc == nil { | ||
cursor, err := view.List(ctx, opts) | ||
require.NoError(mt, err, "failed to list") | ||
|
||
if !cursor.Next(ctx) { | ||
break | ||
} | ||
name := cursor.Current.Lookup("name").StringValue() | ||
queryable := cursor.Current.Lookup("queryable").Boolean() | ||
indexType := cursor.Current.Lookup("type").StringValue() | ||
if name == indexName && queryable { | ||
doc = cursor.Current | ||
assert.Equal(mt, indexType, "vectorSearch") | ||
} else { | ||
t.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String()) | ||
time.Sleep(5 * time.Second) | ||
} | ||
} | ||
}) | ||
|
||
case8CollName, err := uuid.New() | ||
assert.NoError(mt, err, "failed to create random collection name for case #8") | ||
|
||
mt.RunOpts("case 8: Driver requires explicit type to create a vector search index", | ||
mtest.NewOptions().CollectionName(case8CollName.String()), | ||
func(mt *mtest.T) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just realized this change requires everything after this line to be indented, my suggestion didn't include that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed |
||
ctx := context.Background() | ||
|
||
_, err := mt.Coll.InsertOne(ctx, bson.D{}) | ||
require.NoError(mt, err, "failed to insert") | ||
|
||
view := mt.Coll.SearchIndexes() | ||
|
||
type vectorDefinitionField struct { | ||
Type string `bson:"type"` | ||
Path string `bson:"path"` | ||
NumDimensions int `bson:"numDimensions"` | ||
Similarity string `bson:"similarity"` | ||
} | ||
|
||
type vectorDefinition struct { | ||
Fields []vectorDefinitionField `bson:"fields"` | ||
} | ||
|
||
const indexName = "test-search-index-case7-vector" | ||
opts := options.SearchIndexes().SetName(indexName) | ||
_, err = view.CreateOne(ctx, mongo.SearchIndexModel{ | ||
Definition: vectorDefinition{ | ||
Fields: []vectorDefinitionField{{"vector", "plot_embedding", 1536, "euclidean"}}, | ||
}, | ||
Options: opts, | ||
}) | ||
assert.ErrorContains(mt, err, "Attribute mappings missing") | ||
}) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,7 +26,7 @@ tests: | |
- name: createSearchIndex | ||
object: *collection0 | ||
arguments: | ||
model: { definition: &definition { mappings: { dynamic: true } } } | ||
model: { definition: &definition { mappings: { dynamic: true } } , type: 'search' } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These tests are failing because we do not include Type in var m struct {
Definition interface{}
Name *string
Type *string
}
err = bson.Unmarshal(val.Value, &m)
if err != nil {
return nil, err
}
model := mongo.SearchIndexModel{
Definition: m.Definition,
Options: options.SearchIndexes(),
}
model.Options.Name = m.Name
model.Options.Type = m.Type
models = append(models, model) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed |
||
expectError: | ||
# This test always errors in a non-Atlas environment. The test functions as a unit test by asserting | ||
# that the driver constructs and sends the correct command. | ||
|
@@ -39,15 +39,15 @@ tests: | |
- commandStartedEvent: | ||
command: | ||
createSearchIndexes: *collection0 | ||
indexes: [ { definition: *definition } ] | ||
indexes: [ { definition: *definition, type: 'search'} ] | ||
$db: *database0 | ||
|
||
- description: "name provided for an index definition" | ||
operations: | ||
- name: createSearchIndex | ||
object: *collection0 | ||
arguments: | ||
model: { definition: &definition { mappings: { dynamic: true } } , name: 'test index' } | ||
model: { definition: &definition { mappings: { dynamic: true } } , name: 'test index', type: 'search' } | ||
expectError: | ||
# This test always errors in a non-Atlas environment. The test functions as a unit test by asserting | ||
# that the driver constructs and sends the correct command. | ||
|
@@ -60,5 +60,27 @@ tests: | |
- commandStartedEvent: | ||
command: | ||
createSearchIndexes: *collection0 | ||
indexes: [ { definition: *definition, name: 'test index' } ] | ||
indexes: [ { definition: *definition, name: 'test index', type: 'search' } ] | ||
$db: *database0 | ||
|
||
- description: "create a vector search index" | ||
operations: | ||
- name: createSearchIndex | ||
object: *collection0 | ||
arguments: | ||
model: { definition: &definition { fields: [ {"type": "vector", "path": "plot_embedding", "numDimensions": 1536, "similarity": "euclidean"} ] } | ||
, name: 'test index', type: 'vectorSearch' } | ||
expectError: | ||
# This test always errors in a non-Atlas environment. The test functions as a unit test by asserting | ||
# that the driver constructs and sends the correct command. | ||
# The expected error message was changed in SERVER-83003. Check for the substring "Atlas" shared by both error messages. | ||
isError: true | ||
errorContains: Atlas | ||
expectEvents: | ||
- client: *client0 | ||
events: | ||
- commandStartedEvent: | ||
command: | ||
createSearchIndexes: *collection0 | ||
indexes: [ { definition: *definition, name: 'test index', type: 'vectorSearch' } ] | ||
$db: *database0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized this change requires everything after this line to be indented, my suggestion didn't include that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed