Skip to content

Commit 9132657

Browse files
Merge pull request #26 from Trendyol/feature/match-phrase-prefix
feature: add `matchPhrasePrefix` query
2 parents c9f8197 + 0a38999 commit 9132657

File tree

2 files changed

+299
-0
lines changed

2 files changed

+299
-0
lines changed

es/match_phrase_prefix_query.go

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package es
2+
3+
import ZeroTermsQuery "github.com/Trendyol/es-query-builder/es/enums/zero-terms-query"
4+
5+
type matchPhrasePrefixType Object
6+
7+
// MatchPhrasePrefix creates a new es.matchPhrasePrefixType object with the specified field and query.
8+
//
9+
// This function initializes an es.matchPhrasePrefixType object for a match phrase prefix query, where the key
10+
// is the field name and query is the value to search for in that field. This is used
11+
// to construct queries that match the specified value in the given field.
12+
//
13+
// Example usage:
14+
//
15+
// m := es.MatchPhrasePrefix("title", "es-query-builder")
16+
// // m now contains an es.matchPhrasePrefixType object that matches the query "es-query-builder" in the "title" field.
17+
//
18+
// Parameters:
19+
// - key: A string representing the field name for the match phrase prefix query.
20+
// - query: The value to be matched in the specified field. The type is generic.
21+
//
22+
// Returns:
23+
//
24+
// An es.matchPhrasePrefixType object containing the specified match phrase prefix query.
25+
func MatchPhrasePrefix[T any](key string, query T) matchPhrasePrefixType {
26+
return matchPhrasePrefixType{
27+
"match_phrase_prefix": Object{
28+
key: Object{
29+
"query": query,
30+
},
31+
},
32+
}
33+
}
34+
35+
// Analyzer sets the "analyzer" field in the match phrase prefix query.
36+
//
37+
// This method specifies the analyzer to use for the match phrase prefix query, which determines
38+
// how the input text is processed during analysis (e.g., tokenization and normalization).
39+
// Custom analyzers can be used to tailor the query behavior to specific requirements.
40+
//
41+
// Example usage:
42+
//
43+
// m := es.MatchPhrasePrefix("title", "es-query-builder").Analyzer("custom_analyzer")
44+
// // m now has an "analyzer" field set to "custom_analyzer" in the match phrase prefix query object.
45+
//
46+
// Parameters:
47+
// - value: A string representing the name of the analyzer to use.
48+
//
49+
// Returns:
50+
//
51+
// The updated es.matchPhrasePrefixType object with the "analyzer" field set to the specified value.
52+
func (m matchPhrasePrefixType) Analyzer(value string) matchPhrasePrefixType {
53+
return m.putInTheField("analyzer", value)
54+
}
55+
56+
// Boost sets the "boost" field in the match phrase prefix query.
57+
//
58+
// This method configures the match phrase prefix query to use a specified boost factor, which influences
59+
// the relevance scoring of the matched documents.
60+
//
61+
// Example usage:
62+
//
63+
// m := es.MatchPhrasePrefix("title", "es-query-builder").Boost(1.5)
64+
// // m now has a "boost" field set to 1.5 in the match phrase prefix query object.
65+
//
66+
// Parameters:
67+
// - boost: A float64 value representing the boost factor to be applied to the match phrase prefix query.
68+
//
69+
// Returns:
70+
//
71+
// The updated es.matchPhrasePrefixType object with the "boost" field set to the specified value.
72+
func (m matchPhrasePrefixType) Boost(boost float64) matchPhrasePrefixType {
73+
return m.putInTheField("boost", boost)
74+
}
75+
76+
// MaxExpansions sets the "max_expansions" field in the match phrase prefix query.
77+
//
78+
// This method configures the match phrase prefix query to limit the maximum number of terms that can be expanded
79+
// for multi-term queries, such as those involving fuzzy matching. Higher values allow more terms to
80+
// be considered, but may impact performance.
81+
//
82+
// Example usage:
83+
//
84+
// m := es.MatchPhrasePrefix("title", "es-query-builder").MaxExpansions(50)
85+
// // m now has a "max_expansions" field set to 50 in the match phrase prefix query object.
86+
//
87+
// Parameters:
88+
// - maxExpansions: An integer representing the maximum number of term expansions to be allowed in the match phrase prefix query.
89+
//
90+
// Returns:
91+
//
92+
// The updated es.matchPhrasePrefixType object with the "max_expansions" field set to the specified value.
93+
func (m matchPhrasePrefixType) MaxExpansions(maxExpansions int) matchPhrasePrefixType {
94+
return m.putInTheField("max_expansions", maxExpansions)
95+
}
96+
97+
// ZeroTermsQuery sets the "zero_terms_query" field in the match phrase prefix query.
98+
//
99+
// This method configures the behavior of the match phrase prefix query when no terms remain after analysis
100+
// (for example, if all terms are stop words). The specified zero_terms_query value determines
101+
// how to handle this scenario, with options like "all" to match all documents or "none" to
102+
// match none.
103+
//
104+
// Example usage:
105+
//
106+
// m := es.MatchPhrasePrefix("title", "es-query-builder").ZeroTermsQuery(zerotermsquery.All)
107+
// // m now has a "zero_terms_query" field set to "all" in the match phrase prefix query object.
108+
//
109+
// Parameters:
110+
// - zeroTermsQuery: A zerotermsquery.ZeroTermsQuery value that specifies the behavior for zero-term queries.
111+
//
112+
// Returns:
113+
//
114+
// The updated es.matchPhrasePrefixType object with the "zero_terms_query" field set to the specified value.
115+
func (m matchPhrasePrefixType) ZeroTermsQuery(zeroTermsQuery ZeroTermsQuery.ZeroTermsQuery) matchPhrasePrefixType {
116+
return m.putInTheField("zero_terms_query", zeroTermsQuery)
117+
}
118+
119+
// Slop sets the "slop" field in the match phrase prefix query.
120+
//
121+
// This method specifies the allowed distance between terms in a phrase query, enabling more
122+
// flexibility in matching phrases that may have slight variations in word order or spacing.
123+
// A higher slop value allows more variation, while a slop of 0 requires exact matching.
124+
//
125+
// Example usage:
126+
//
127+
// m := es.MatchPhrasePrefix("title", "es-query-builder").Slop(2)
128+
// // m now has a "slop" field set to 2 in the match phrase prefix query object.
129+
//
130+
// Parameters:
131+
// - slop: An integer representing the maximum allowed distance between terms.
132+
//
133+
// Returns:
134+
//
135+
// The updated es.matchPhrasePrefixType object with the "slop" field set to the specified value.
136+
func (m matchPhrasePrefixType) Slop(slop int) matchPhrasePrefixType {
137+
return m.putInTheField("slop", slop)
138+
}
139+
140+
func (m matchPhrasePrefixType) putInTheField(key string, value any) matchPhrasePrefixType {
141+
if matchPhrasePrefix, ok := m["match_phrase_prefix"].(Object); ok {
142+
for _, fieldObj := range matchPhrasePrefix {
143+
if fieldObject, foOk := fieldObj.(Object); foOk {
144+
fieldObject[key] = value
145+
break
146+
}
147+
}
148+
}
149+
return m
150+
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
package es_test
2+
3+
import (
4+
"testing"
5+
6+
ZeroTermsQuery "github.com/Trendyol/es-query-builder/es/enums/zero-terms-query"
7+
8+
"github.com/Trendyol/es-query-builder/es"
9+
"github.com/Trendyol/es-query-builder/test/assert"
10+
)
11+
12+
//// Match Phrase Prefix ////
13+
14+
func Test_MatchPhrasePrefix_should_exist_on_es_package(t *testing.T) {
15+
// Given When Then
16+
assert.NotNil(t, es.MatchPhrasePrefix[any])
17+
}
18+
19+
func Test_MatchPhrasePrefix_method_should_create_matchPhrasePrefixType(t *testing.T) {
20+
// Given
21+
b := es.MatchPhrasePrefix("key", "value")
22+
23+
// Then
24+
assert.NotNil(t, b)
25+
assert.IsTypeString(t, "es.matchPhrasePrefixType", b)
26+
}
27+
28+
func Test_MatchPhrasePrefix_should_have_Analyzer_method(t *testing.T) {
29+
// Given
30+
match := es.MatchPhrasePrefix("key", "value")
31+
32+
// When Then
33+
assert.NotNil(t, match.Analyzer)
34+
}
35+
36+
func Test_MatchPhrasePrefix_Analyzer_should_create_json_with_analyzer_field_inside_match_phrase_prefix(t *testing.T) {
37+
// Given
38+
query := es.NewQuery(
39+
es.MatchPhrasePrefix("type", "Folder").
40+
Analyzer("standart"),
41+
)
42+
43+
// When Then
44+
assert.NotNil(t, query)
45+
bodyJSON := assert.MarshalWithoutError(t, query)
46+
assert.Equal(t, "{\"query\":{\"match_phrase_prefix\":{\"type\":{\"analyzer\":\"standart\",\"query\":\"Folder\"}}}}", bodyJSON)
47+
}
48+
49+
func Test_MatchPhrasePrefix_should_have_Boost_method(t *testing.T) {
50+
// Given
51+
match := es.MatchPhrasePrefix("key", "value")
52+
53+
// When Then
54+
assert.NotNil(t, match.Boost)
55+
}
56+
57+
func Test_MatchPhrasePrefix_Boost_should_create_json_with_boost_field_inside_match_phrase_prefix(t *testing.T) {
58+
// Given
59+
query := es.NewQuery(
60+
es.MatchPhrasePrefix("type", "Folder").
61+
Boost(3.14),
62+
)
63+
64+
// When Then
65+
assert.NotNil(t, query)
66+
bodyJSON := assert.MarshalWithoutError(t, query)
67+
assert.Equal(t, "{\"query\":{\"match_phrase_prefix\":{\"type\":{\"boost\":3.14,\"query\":\"Folder\"}}}}", bodyJSON)
68+
}
69+
70+
func Test_MatchPhrasePrefix_should_have_MaxExpansions_method(t *testing.T) {
71+
// Given
72+
match := es.MatchPhrasePrefix("key", "value")
73+
74+
// When Then
75+
assert.NotNil(t, match.MaxExpansions)
76+
}
77+
78+
func Test_MatchPhrasePrefix_MaxExpansions_should_create_json_with_max_expansions_field_inside_match_phrase_prefix(t *testing.T) {
79+
// Given
80+
query := es.NewQuery(
81+
es.MatchPhrasePrefix("type", "Folder").
82+
MaxExpansions(7),
83+
)
84+
85+
// When Then
86+
assert.NotNil(t, query)
87+
bodyJSON := assert.MarshalWithoutError(t, query)
88+
assert.Equal(t, "{\"query\":{\"match_phrase_prefix\":{\"type\":{\"max_expansions\":7,\"query\":\"Folder\"}}}}", bodyJSON)
89+
}
90+
91+
func Test_MatchPhrasePrefix_should_have_Slop_method(t *testing.T) {
92+
// Given
93+
match := es.MatchPhrasePrefix("key", "value")
94+
95+
// When Then
96+
assert.NotNil(t, match.Slop)
97+
}
98+
99+
func Test_MatchPhrasePrefix_Slop_should_create_json_with_slop_field_inside_match_phrase_prefix(t *testing.T) {
100+
// Given
101+
query := es.NewQuery(
102+
es.MatchPhrasePrefix("type", "Folder").
103+
Slop(3),
104+
)
105+
106+
// When Then
107+
assert.NotNil(t, query)
108+
bodyJSON := assert.MarshalWithoutError(t, query)
109+
assert.Equal(t, "{\"query\":{\"match_phrase_prefix\":{\"type\":{\"query\":\"Folder\",\"slop\":3}}}}", bodyJSON)
110+
}
111+
112+
func Test_MatchPhrasePrefix_should_have_ZeroTermsQuery_method(t *testing.T) {
113+
// Given
114+
match := es.MatchPhrasePrefix("key", "value")
115+
116+
// When Then
117+
assert.NotNil(t, match.ZeroTermsQuery)
118+
}
119+
120+
func Test_MatchPhrasePrefix_ZeroTermsQuery_should_create_json_with_zero_terms_query_field_inside_match_phrase_prefix(t *testing.T) {
121+
// Given
122+
query := es.NewQuery(
123+
es.MatchPhrasePrefix("type", "Folder").
124+
ZeroTermsQuery(ZeroTermsQuery.All),
125+
)
126+
127+
// When Then
128+
assert.NotNil(t, query)
129+
bodyJSON := assert.MarshalWithoutError(t, query)
130+
assert.Equal(t, "{\"query\":{\"match_phrase_prefix\":{\"type\":{\"query\":\"Folder\",\"zero_terms_query\":\"all\"}}}}", bodyJSON)
131+
}
132+
133+
func Test_MatchPhrasePrefix_should_create_json_with_match_phrase_prefix_field_inside_query(t *testing.T) {
134+
// Given
135+
query := es.NewQuery(
136+
es.MatchPhrasePrefix("message", "this is a test").
137+
Analyzer("standart").
138+
Boost(2.14).
139+
MaxExpansions(50).
140+
Slop(9).
141+
ZeroTermsQuery(ZeroTermsQuery.None),
142+
)
143+
144+
// When Then
145+
assert.NotNil(t, query)
146+
bodyJSON := assert.MarshalWithoutError(t, query)
147+
// nolint:golint,lll
148+
assert.Equal(t, "{\"query\":{\"match_phrase_prefix\":{\"message\":{\"analyzer\":\"standart\",\"boost\":2.14,\"max_expansions\":50,\"query\":\"this is a test\",\"slop\":9,\"zero_terms_query\":\"none\"}}}}", bodyJSON)
149+
}

0 commit comments

Comments
 (0)