Skip to content
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

Fixes Client.Delete() behaves opposite to spec. Deprecates Client.Delete() in favor of Cliente.DeleteDocument() for RediSearch >=v2.0 #80

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ fmt:
$(GOFMT) ./...

godoc_examples: get fmt
$(GOTEST) -race -covermode=atomic -v ./redisearch
$(GOTEST) -race -covermode=atomic ./redisearch

test: get fmt
$(GOTEST) -race -covermode=atomic -run "Test" -v ./redisearch
$(GOTEST) -race -covermode=atomic -run "Test" ./redisearch

coverage: get
$(GOTEST) -race -coverprofile=coverage.txt -covermode=atomic -v ./redisearch
$(GOTEST) -race -coverprofile=coverage.txt -covermode=atomic ./redisearch

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func ExampleClient() {
| [FT.AGGREGATE](https://oss.redislabs.com/redisearch/Commands.html#ftaggregate) | [Aggregate](https://godoc.org/github.com/RediSearch/redisearch-go/redisearch#Client.Aggregate) |
| [FT.CURSOR](https://oss.redislabs.com/redisearch/Aggregations.html#cursor_api) | [Aggregate](https://godoc.org/github.com/RediSearch/redisearch-go/redisearch#Client.Aggregate) + (*WithCursor option set to True) |
| [FT.EXPLAIN](https://oss.redislabs.com/redisearch/Commands.html#ftexplain) | [Explain](https://godoc.org/github.com/RediSearch/redisearch-go/redisearch#Client.Explain) |
| [FT.DEL](https://oss.redislabs.com/redisearch/Commands.html#ftdel) | [Delete](https://godoc.org/github.com/RediSearch/redisearch-go/redisearch#Client.Delete) |
| [FT.DEL](https://oss.redislabs.com/redisearch/Commands.html#ftdel) | [DeleteDocument](https://godoc.org/github.com/RediSearch/redisearch-go/redisearch#Client.DeleteDocument) |
| [FT.GET](https://oss.redislabs.com/redisearch/Commands.html#ftget) | [Get](https://godoc.org/github.com/RediSearch/redisearch-go/redisearch#Client.Get) |
| [FT.MGET](https://oss.redislabs.com/redisearch/Commands.html#ftmget) | [MultiGet](https://godoc.org/github.com/RediSearch/redisearch-go/redisearch#Client.Multi) |
| [FT.DROP](https://oss.redislabs.com/redisearch/Commands.html#ftdrop) | [Drop](https://godoc.org/github.com/RediSearch/redisearch-go/redisearch#Client.Drop) |
Expand Down
18 changes: 14 additions & 4 deletions redisearch/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,16 +364,26 @@ func (i *Client) Drop() error {
}

// Delete the document from the index, optionally delete the actual document
// WARNING: As of RediSearch 2.0 and above, FT.DEL always deletes the underlying document.
// Deprecated: This function is deprecated on RediSearch 2.0 and above, use DeleteDocument() instead
func (i *Client) Delete(docId string, deleteDocument bool) (err error) {
return i.delDoc(docId, deleteDocument)
}

// Delete the document from the index and also delete the HASH key in which the document is stored
func (i *Client) DeleteDocument(docId string) (err error) {
return i.delDoc(docId, true)
}

// Internal method to be used by Delete() and DeleteDocument()
func (i *Client) delDoc(docId string, deleteDocument bool) (err error) {
conn := i.pool.Get()
defer conn.Close()

if deleteDocument {
_, err = conn.Do("FT.DEL", i.name, docId)
} else {
_, err = conn.Do("FT.DEL", i.name, docId, "DD")
} else {
_, err = conn.Do("FT.DEL", i.name, docId)
}

return
}

Expand Down
126 changes: 126 additions & 0 deletions redisearch/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -724,3 +724,129 @@ func TestClient_SynUpdate(t *testing.T) {
})
}
}

func TestClient_Delete(t *testing.T) {
c := createClient("ft.del-test")
sc := NewSchema(DefaultOptions).
AddField(NewTextField("name")).
AddField(NewTextField("addr"))
version, err := c.getRediSearchVersion()
assert.Nil(t, err)

type args struct {
docId string
deleteDocument bool
}
tests := []struct {
name string
args args
wantErr bool
documentShouldExist bool
}{
{"persist-doc", args{"doc1", false}, false, true},
{"delete-doc", args{"doc1", true}, false, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c.Drop()
err := c.CreateIndex(sc)
assert.Nil(t, err)
err = c.Index(NewDocument(tt.args.docId, 1.0).Set("name", "Jon Doe"))
assert.Nil(t, err)
if err := c.Delete(tt.args.docId, tt.args.deleteDocument); (err != nil) != tt.wantErr {
t.Errorf("Delete() error = %v, wantErr %v", err, tt.wantErr)
}
docExists, err := redis.Bool(c.pool.Get().Do("EXISTS", tt.args.docId))
assert.Nil(t, err)
if version <= 10699 {
assert.Equal(t, tt.documentShouldExist, docExists)
} else {
assert.Equal(t, false, docExists)
}
teardown(c)
})
}
}

func TestClient_DeleteDocument(t *testing.T) {
c := createClient("ft.DeleteDocument-test")
sc := NewSchema(DefaultOptions).
AddField(NewTextField("name")).
AddField(NewTextField("addr"))

type args struct {
docId string
docIdsToAddIdx []string
}
tests := []struct {
name string
args args
wantErr bool
}{
{"doc-exists", args{"doc1", []string{"doc1", "doc2"}}, false},
{"doc-not-exists", args{"doc3", []string{"doc1", "doc2"}}, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c.Drop()
err := c.CreateIndex(sc)
assert.Nil(t, err)
for _, docId := range tt.args.docIdsToAddIdx {
err = c.Index(NewDocument(docId, 1.0).Set("name", "Jon Doe"))
assert.Nil(t, err)
}
if err := c.DeleteDocument(tt.args.docId); (err != nil) != tt.wantErr {
t.Errorf("DeleteDocument() error = %v, wantErr %v", err, tt.wantErr)
}
docExists, err := redis.Bool(c.pool.Get().Do("EXISTS", tt.args.docId))
assert.Nil(t, err)
assert.False(t, docExists)
teardown(c)
})
}
}

func TestClient_CreateIndexWithIndexDefinition1(t *testing.T) {
c := createClient("index-definition-test")
version, err := c.getRediSearchVersion()
assert.Nil(t, err)
if version <= 10699 {
// IndexDefinition is available for RediSearch 2.0+
return
}
// Create a schema
sc := NewSchema(DefaultOptions).
AddField(NewTextFieldOptions("name", TextFieldOptions{Sortable: true})).
AddField(NewTextFieldOptions("description", TextFieldOptions{Weight: 5.0, Sortable: true})).
AddField(NewNumericField("price"))

type args struct {
schema *Schema
definition *IndexDefinition
}
tests := []struct {
name string
args args
wantErr bool
}{
{"default", args{sc, NewIndexDefinition()}, false},
{"default+async", args{sc, NewIndexDefinition().SetAsync(true)}, false},
{"default+score", args{sc, NewIndexDefinition().SetScore(0.75)}, false},
{"default+score_field", args{sc, NewIndexDefinition().SetScoreField("myscore")}, false},
{"default+language", args{sc, NewIndexDefinition().SetLanguage("portuguese")}, false},
{"default+language_field", args{sc, NewIndexDefinition().SetLanguageField("mylanguage")}, false},
{"default+prefix", args{sc, NewIndexDefinition().AddPrefix("products:*")}, false},
{"default+payload_field", args{sc, NewIndexDefinition().SetPayloadField("products_description")}, false},
{"default+filter", args{sc, NewIndexDefinition().SetFilterExpression("@score >= 0")}, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c.Drop()
if err := c.CreateIndexWithIndexDefinition(tt.args.schema, tt.args.definition); (err != nil) != tt.wantErr {
t.Errorf("CreateIndexWithIndexDefinition() error = %v, wantErr %v", err, tt.wantErr)
}
})
teardown(c)

}
}
57 changes: 0 additions & 57 deletions redisearch/redisearch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,63 +358,6 @@ func TestTags(t *testing.T) {
teardown(c)
}

func TestDelete(t *testing.T) {
c := createClient("TestDelete-testung")

sc := NewSchema(DefaultOptions).
AddField(NewTextField("foo"))

err := c.Drop()

assert.Nil(t, c.CreateIndex(sc))

var info *IndexInfo

// validate that the index is empty
info, err = c.Info()
assert.Nil(t, err)
if !info.IsIndexing {
assert.Equal(t, uint64(0), info.DocCount)
}

doc := NewDocument("TestDelete-doc1", 1.0)
doc.Set("foo", "Hello world")

err = c.IndexOptions(DefaultIndexingOptions, doc)
assert.Nil(t, err)

// Wait for all documents to be indexed
info, err = c.Info()
assert.Nil(t, err)
for info.IsIndexing {
time.Sleep(time.Second)
info, err = c.Info()
assert.Nil(t, err)
}

// now we should have 1 document (id = doc1)
info, err = c.Info()
assert.Nil(t, err)
assert.Equal(t, uint64(1), info.DocCount)

// delete the document from the index
err = c.Delete("TestDelete-doc1", true)
assert.Nil(t, err)

// Wait for all documents to be indexed
info, err = c.Info()
assert.Nil(t, err)
for info.IsIndexing {
time.Sleep(time.Second)
info, err = c.Info()
assert.Nil(t, err)
}

assert.Nil(t, err)
assert.Equal(t, uint64(0), info.DocCount)
teardown(c)
}

func TestSpellCheck(t *testing.T) {
c := createClient("testung")
countries := []string{"Spain", "Israel", "Portugal", "France", "England", "Angola"}
Expand Down