Skip to content

Commit 11b717e

Browse files
Added contains and suffix search benchmarks (#17)
1 parent f5fbaca commit 11b717e

7 files changed

Lines changed: 115 additions & 3 deletions

File tree

.github/workflows/publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
runs-on: ubuntu-latest
1212
strategy:
1313
matrix:
14-
goos: [linux, darwin,windows]
14+
goos: [linux, darwin]
1515
goarch: [amd64, arm64]
1616
steps:
1717
- uses: actions/checkout@v3

benchmark.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,58 @@ func SearchBenchmark(queries []string, field string, idx index.Index, opts inter
3030
}
3131
}
3232

33+
func SuffixBenchmark(terms []string, field string, idx index.Index, prefixMinLen, prefixMaxLen int64, debug int) func() error {
34+
counter := 0
35+
fixedPrefixSize := false
36+
if prefixMinLen == prefixMaxLen {
37+
fixedPrefixSize = true
38+
}
39+
return func() error {
40+
term := terms[counter%len(terms)]
41+
var prefixSize int64 = prefixMinLen
42+
if !fixedPrefixSize {
43+
n := rand.Int63n(int64(prefixMaxLen - prefixMinLen))
44+
prefixSize = prefixSize + n
45+
}
46+
for prefixSize > int64(len(term)) {
47+
counter++
48+
term = terms[counter%len(terms)]
49+
}
50+
term = term[len(term)-int(prefixSize):]
51+
q := query.NewQuery(idx.GetName(), term).Limit(0, 5).SetFlags(query.QueryTypeSuffix).SetField(field)
52+
_, _, err := idx.SuffixQuery(*q, debug)
53+
counter++
54+
return err
55+
}
56+
}
57+
58+
func ContainsBenchmark(terms []string, field string, idx index.Index, prefixMinLen, prefixMaxLen int64, debug int) func() error {
59+
counter := 0
60+
fixedPrefixSize := false
61+
if prefixMinLen == prefixMaxLen {
62+
fixedPrefixSize = true
63+
}
64+
return func() error {
65+
term := terms[counter%len(terms)]
66+
var prefixSize int64 = prefixMinLen
67+
if !fixedPrefixSize {
68+
n := rand.Int63n(int64(prefixMaxLen - prefixMinLen))
69+
prefixSize = prefixSize + n
70+
}
71+
for prefixSize > int64(len(term)) {
72+
counter++
73+
term = terms[counter%len(terms)]
74+
}
75+
term = term[0:prefixSize]
76+
term = "*" + term + "*"
77+
78+
q := query.NewQuery(idx.GetName(), term).Limit(0, 5).SetField(field)
79+
_, _, err := idx.ContainsQuery(*q, debug)
80+
counter++
81+
return err
82+
}
83+
}
84+
3385
// SearchBenchmark returns a closure of a function for the benchmarker to run, using a given index
3486
// and options, on a set of queries
3587
func PrefixBenchmark(terms []string, field string, idx index.Index, prefixMinLen, prefixMaxLen int64, debug int) func() error {

index/elastic/elastic.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,42 @@ func elasticParseResponse(r map[string]interface{}, verbose int, res *esapi.Resp
310310
return hits
311311
}
312312

313+
// https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-wildcard-query.html
314+
func (i *Index) ContainsQuery(q query.Query, verbose int) ([]index.Document, int, error) {
315+
es := i.conn
316+
query := map[string]interface{}{
317+
"from": q.Paging.Offset,
318+
"size": q.Paging.Num,
319+
"query": map[string]interface{}{
320+
"wildcard": map[string]interface{}{
321+
q.Field: map[string]interface{}{
322+
"value": q.Term,
323+
},
324+
},
325+
},
326+
}
327+
hits, err := elasticSearchQuery(i.name, es, verbose, query)
328+
return nil, hits, err
329+
}
330+
331+
// https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-wildcard-query.html
332+
func (i *Index) SuffixQuery(q query.Query, verbose int) ([]index.Document, int, error) {
333+
es := i.conn
334+
query := map[string]interface{}{
335+
"from": q.Paging.Offset,
336+
"size": q.Paging.Num,
337+
"query": map[string]interface{}{
338+
"wildcard": map[string]interface{}{
339+
q.Field: map[string]interface{}{
340+
"value": q.Term,
341+
},
342+
},
343+
},
344+
}
345+
hits, err := elasticSearchQuery(i.name, es, verbose, query)
346+
return nil, hits, err
347+
}
348+
313349
// https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-wildcard-query.html
314350
func (i *Index) WildCardQuery(q query.Query, verbose int) ([]index.Document, int, error) {
315351
es := i.conn

index/index.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ type Index interface {
1111
Index(documents []Document, options interface{}) error
1212
FullTextQuerySingleField(query.Query, int) (docs []Document, total int, err error)
1313
PrefixQuery(query.Query, int) (docs []Document, total int, err error)
14+
SuffixQuery(query.Query, int) (docs []Document, total int, err error)
1415
WildCardQuery(query.Query, int) (docs []Document, total int, err error)
16+
ContainsQuery(q query.Query, debug int) (docs []Document, total int, err error)
1517
Drop() error
1618
DocumentCount() int64
1719
Create() error
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,14 @@ func (i *Index) Index(docs []index.Document, options interface{}) error {
197197
return nil
198198
}
199199

200+
func (i *Index) SuffixQuery(q query.Query, verbose int) (docs []index.Document, total int, err error) {
201+
return i.FullTextQuerySingleField(q, verbose)
202+
}
203+
204+
func (i *Index) ContainsQuery(q query.Query, verbose int) (docs []index.Document, total int, err error) {
205+
return i.FullTextQuerySingleField(q, verbose)
206+
}
207+
200208
func (i *Index) PrefixQuery(q query.Query, verbose int) (docs []index.Document, total int, err error) {
201209
return i.FullTextQuerySingleField(q, verbose)
202210
}
@@ -213,6 +221,9 @@ func (i *Index) FullTextQuerySingleField(q query.Query, verbose int) (docs []ind
213221
if q.Flags&query.QueryTypePrefix != 0 && term[len(term)-1] != '*' {
214222
term = fmt.Sprintf("%s*", term)
215223
}
224+
if q.Flags&query.QueryTypeSuffix != 0 && term[0] != '*' {
225+
term = fmt.Sprintf("*%s", term)
226+
}
216227
queryParam := term
217228
if q.Field != "" {
218229
queryParam = fmt.Sprintf("@%s:%s", q.Field, term)

main.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ const (
3131
DEFAULT_DATASET = EN_WIKI_DATASET
3232
BENCHMARK_SEARCH = "search"
3333
BENCHMARK_PREFIX = "prefix"
34+
BENCHMARK_CONTAINS = "contains"
35+
BENCHMARK_SUFFIX = "suffix"
3436
BENCHMARK_WILDCARD = "wildcard"
3537
BENCHMARK_DEFAULT = BENCHMARK_SEARCH
3638
ENGINE_REDIS = "redis"
@@ -93,7 +95,7 @@ func main() {
9395
randomSeed := flag.Int64("seed", 12345, "PRNG seed.")
9496
termStopWords := flag.String("stopwords", DEFAULT_STOPWORDS, "filtered stopwords for term creation")
9597
dataset := flag.String("dataset", DEFAULT_DATASET, fmt.Sprintf("The dataset tp process. One of: [%s]", strings.Join([]string{EN_WIKI_DATASET, REDDIT_DATASET, PMC_DATASET}, "|")))
96-
benchmark := flag.String("benchmark", "", fmt.Sprintf("The benchmark to run. One of: [%s]. If empty will not run.", strings.Join([]string{BENCHMARK_SEARCH, BENCHMARK_PREFIX, BENCHMARK_WILDCARD}, "|")))
98+
benchmark := flag.String("benchmark", "", fmt.Sprintf("The benchmark to run. One of: [%s]. If empty will not run.", strings.Join([]string{BENCHMARK_SEARCH, BENCHMARK_PREFIX, BENCHMARK_WILDCARD, BENCHMARK_CONTAINS, BENCHMARK_SUFFIX}, "|")))
9799

98100
tlsSkipVerify := flag.Bool("tls-skip-verify", true, "Skip verification of server certificate.")
99101
seconds := flag.Int("duration", 60, "number of seconds to run the benchmark")
@@ -194,6 +196,10 @@ func main() {
194196
}
195197
returnCode := 0
196198
switch *benchmark {
199+
case BENCHMARK_CONTAINS:
200+
name := fmt.Sprintf("contains: %d terms", len(queries))
201+
log.Println("Starting term-level queries benchmark: Type CONTAINS")
202+
Benchmark(*conc, duration, &histogramMutex, *engine, name, *outfile, *reportingPeriod, w, ContainsBenchmark(queries, benchmarkQueryField, indexes[0], *termQueryPrefixMinLen, *termQueryPrefixMaxLen, *debugLevel))
197203
case BENCHMARK_WILDCARD:
198204
name := fmt.Sprintf("wildcard: %d terms", len(queries))
199205
log.Println("Starting term-level queries benchmark: Type WILDCARD")
@@ -203,6 +209,10 @@ func main() {
203209
log.Println(fmt.Sprintf("%s needs to be at least larger by 2 than min length given we want the wildcard to be present at the midle of the term. Forcing %s=%d", TERM_QUERY_MAX_LEN, TERM_QUERY_MAX_LEN, prefixMaxLen))
204210
}
205211
Benchmark(*conc, duration, &histogramMutex, *engine, name, *outfile, *reportingPeriod, w, WildcardBenchmark(queries, benchmarkQueryField, indexes[0], *termQueryPrefixMinLen, prefixMaxLen, *debugLevel))
212+
case BENCHMARK_SUFFIX:
213+
name := fmt.Sprintf("suffix: %d terms", len(queries))
214+
log.Println("Starting term-level queries benchmark: Type SUFFIX")
215+
Benchmark(*conc, duration, &histogramMutex, *engine, name, *outfile, *reportingPeriod, w, SuffixBenchmark(queries, benchmarkQueryField, indexes[0], *termQueryPrefixMinLen, *termQueryPrefixMaxLen, *debugLevel))
206216
case BENCHMARK_PREFIX:
207217
name := fmt.Sprintf("prefix: %d terms", len(queries))
208218
log.Println("Starting term-level queries benchmark: Type PREFIX")

query/query.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ const (
77
QueryVerbatim Flag = 0x1
88
QueryNoContent Flag = 0x2
99
QueryTypePrefix Flag = 0x3
10-
QueryTypeWildcard Flag = 0x4
10+
QueryTypeSuffix Flag = 0x4
11+
QueryTypeWildcard Flag = 0x5
1112
// ... more to come!
1213

1314
DefaultOffset = 0

0 commit comments

Comments
 (0)