Skip to content

Commit 635e5cf

Browse files
authored
chore: add collapse parameter to query builder (#264)
* chore: add collapse parameter to query builder * chore: update docs
1 parent 5bba24c commit 635e5cf

8 files changed

Lines changed: 48 additions & 13 deletions

File tree

core/api/util.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,14 @@ func WriteAckOKJSON(w http.ResponseWriter) {
8888

8989
func MustGetParameter(w http.ResponseWriter, r *http.Request, key string) string {
9090
if r.URL == nil {
91-
panic("URL is nil")
91+
panic(errors.NewWithHTTPCode(400, "URL is nil"))
92+
9293
}
9394

9495
v := r.URL.Query().Get(key)
9596

9697
if len(v) == 0 {
97-
panic("missing parameter " + key)
98+
panic(errors.NewWithHTTPCode(400, "missing parameter "+key))
9899
}
99100

100101
return v

core/orm/aggs.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,9 @@ func (b *baseAggregation) SetParams(params map[string]interface{}) {
9595
// TermsAggregation represents a "group by" or "bucketing" operation on a field.
9696
type TermsAggregation struct {
9797
baseAggregation
98-
Field string
99-
Size int
98+
Field string
99+
Include string
100+
Size int
100101
}
101102

102103
// AddNested provides a correctly typed chained call for TermsAggregation.

core/orm/query.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,10 @@ type QueryBuilder struct {
9898
size int
9999
fuzziness int
100100

101-
query string
102-
includes []string
103-
excludes []string
101+
query string
102+
collapseOverField string
103+
includes []string
104+
excludes []string
104105

105106
defaultOperator string
106107
defaultQueryFields []string
@@ -463,6 +464,10 @@ func (q *QueryBuilder) ToString() string {
463464
b.WriteString(", Default Fields: ")
464465
b.WriteString(strings.Join(q.defaultQueryFields, ","))
465466
}
467+
if len(q.collapseOverField) > 0 {
468+
b.WriteString(", Collapse Field: ")
469+
b.WriteString(q.collapseOverField)
470+
}
466471

467472
if len(q.defaultQueryFields) > 0 {
468473
b.WriteString(", Default QueryFields: ")
@@ -780,6 +785,14 @@ func (q *QueryBuilder) buildFuzzinessQuery() {
780785
}
781786
}
782787

788+
func (q *QueryBuilder) CollapseVal() string {
789+
return q.collapseOverField
790+
}
791+
792+
func (q *QueryBuilder) Collapse(field string) {
793+
q.collapseOverField = field
794+
}
795+
783796
// parseQuery attempts to extract field:value only if the field name is valid
784797
func parseQuery(queryStr string) (field string, value string) {
785798
parts := strings.SplitN(queryStr, ":", 2)

core/security/principal.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ type OrganizationPrincipal struct {
1414
Type string `json:"type,omitempty" elastic_mapping:"type:{type:keyword}"` // "type": "user", // or "team"
1515
Name string `json:"name,omitempty" elastic_mapping:"name:{type:text,copy_to:combined_fulltext,fields:{keyword: {type: keyword}, pinyin: {type: text, analyzer: pinyin_analyzer}}}"`
1616
Description string `json:"description,omitempty" elastic_mapping:"description:{type:keyword,copy_to:combined_fulltext}"`
17-
Avatar string `json:"avatar,omitempty" elastic_mapping:"avatar:{type:keyword}"`
17+
Avatar string `json:"avatar,omitempty" elastic_mapping:"avatar:{enabled:false}"`
1818
}
1919

2020
type OrganizationPrincipalCache struct {

docs/content.en/docs/release-notes/_index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Information about release notes of INFINI Framework is provided here.
2626
- refactor: refactoring user and permissions #256
2727
- chore: improve badger logging #260
2828
- chore: handle self-signed certs oauth client #263
29+
- chore: add collapse parameter to query builder #264
2930

3031
## 1.4.0 (2025-12-19)
3132
### ❌ Breaking changes

modules/elastic/orm.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,10 @@ func (handler *ElasticORM) DeleteByQuery(ctx *api.Context, qb *api.QueryBuilder)
360360
return nil, errors.New("failed to build query DSL")
361361
}
362362

363+
if global.Env().IsDebug {
364+
log.Debug("delete by query:", indexName, util.MustToJSON(dsl))
365+
}
366+
363367
// Execute delete-by-query
364368
resp, err := handler.Client.DeleteByQuery(indexName, util.MustToJSONBytes(dsl))
365369
if err != nil {
@@ -383,6 +387,10 @@ func (handler *ElasticORM) SearchV2(ctx *api.Context, qb *api.QueryBuilder) (*ap
383387
if qb != nil {
384388
request.From = qb.FromVal()
385389
request.Size = qb.SizeVal()
390+
391+
if v := qb.CollapseVal(); v != "" {
392+
request.Collapse = &elastic.Collapse{Field: v}
393+
}
386394
}
387395

388396
if collapseField := api.GetCollapseField(ctx); collapseField != "" {
@@ -406,6 +414,7 @@ func (handler *ElasticORM) SearchV2(ctx *api.Context, qb *api.QueryBuilder) (*ap
406414
} else {
407415
dsl = orm.BuildQueryDSL(qb)
408416
}
417+
409418
if len(qb.Aggs) > 0 {
410419
aggBuilder := orm.AggreationBuilder{}
411420
aggs, err := aggBuilder.Build(qb.Aggs)

modules/elastic/orm/aggs.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ type ESAggregation struct {
5050
}
5151

5252
type esTermsAggregation struct {
53-
Field string `json:"field,omitempty"`
54-
Size int `json:"size,omitempty"`
53+
Field string `json:"field,omitempty"`
54+
Include string `json:"include,omitempty"`
55+
Size int `json:"size,omitempty"`
5556
}
5657

5758
type esMetricAggregation struct {
@@ -118,8 +119,9 @@ func (c *AggreationBuilder) translateAggregation(agg orm.Aggregation) (*ESAggreg
118119
switch v := agg.(type) {
119120
case *orm.TermsAggregation:
120121
esAgg.Terms = &esTermsAggregation{
121-
Field: v.Field,
122-
Size: v.Size,
122+
Field: v.Field,
123+
Include: v.Include,
124+
Size: v.Size,
123125
}
124126
case *orm.MetricAggregation:
125127
metric := &esMetricAggregation{Field: v.Field}

modules/elastic/orm/query_dsl.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@
2424
package orm
2525

2626
import (
27+
"strings"
28+
2729
"infini.sh/framework/core/orm"
2830
"infini.sh/framework/core/util"
29-
"strings"
3031
)
3132

3233
func BuildQueryDSLOnTopOfDSL(q *orm.QueryBuilder, reqBody []byte) map[string]interface{} {
@@ -199,10 +200,17 @@ func BuildQueryDSL(q *orm.QueryBuilder) map[string]interface{} {
199200
if q.FromVal() > 0 {
200201
dsl["from"] = q.FromVal()
201202
}
203+
202204
if q.SizeVal() > 0 {
203205
dsl["size"] = q.SizeVal()
204206
}
205207

208+
if q.CollapseVal() != "" {
209+
dsl["collapse"] = map[string]interface{}{
210+
"field": q.CollapseVal(),
211+
}
212+
}
213+
206214
if len(q.IncludesVal()) > 0 || len(q.ExcludesVal()) > 0 {
207215
sources := util.MapStr{}
208216
if len(q.IncludesVal()) > 0 {

0 commit comments

Comments
 (0)