search_queries_fsq.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // Copyright 2012-present Oliver Eilhard. All rights reserved.
  2. // Use of this source code is governed by a MIT-license.
  3. // See http://olivere.mit-license.org/license.txt for details.
  4. package elastic
  5. // FunctionScoreQuery allows you to modify the score of documents that
  6. // are retrieved by a query. This can be useful if, for example,
  7. // a score function is computationally expensive and it is sufficient
  8. // to compute the score on a filtered set of documents.
  9. //
  10. // For more details, see
  11. // https://www.elastic.co/guide/en/elasticsearch/reference/5.2/query-dsl-function-score-query.html
  12. type FunctionScoreQuery struct {
  13. query Query
  14. filter Query
  15. boost *float64
  16. maxBoost *float64
  17. scoreMode string
  18. boostMode string
  19. filters []Query
  20. scoreFuncs []ScoreFunction
  21. minScore *float64
  22. weight *float64
  23. }
  24. // NewFunctionScoreQuery creates and initializes a new function score query.
  25. func NewFunctionScoreQuery() *FunctionScoreQuery {
  26. return &FunctionScoreQuery{
  27. filters: make([]Query, 0),
  28. scoreFuncs: make([]ScoreFunction, 0),
  29. }
  30. }
  31. // Query sets the query for the function score query.
  32. func (q *FunctionScoreQuery) Query(query Query) *FunctionScoreQuery {
  33. q.query = query
  34. return q
  35. }
  36. // Filter sets the filter for the function score query.
  37. func (q *FunctionScoreQuery) Filter(filter Query) *FunctionScoreQuery {
  38. q.filter = filter
  39. return q
  40. }
  41. // Add adds a score function that will execute on all the documents
  42. // matching the filter.
  43. func (q *FunctionScoreQuery) Add(filter Query, scoreFunc ScoreFunction) *FunctionScoreQuery {
  44. q.filters = append(q.filters, filter)
  45. q.scoreFuncs = append(q.scoreFuncs, scoreFunc)
  46. return q
  47. }
  48. // AddScoreFunc adds a score function that will execute the function on all documents.
  49. func (q *FunctionScoreQuery) AddScoreFunc(scoreFunc ScoreFunction) *FunctionScoreQuery {
  50. q.filters = append(q.filters, nil)
  51. q.scoreFuncs = append(q.scoreFuncs, scoreFunc)
  52. return q
  53. }
  54. // ScoreMode defines how results of individual score functions will be aggregated.
  55. // Can be first, avg, max, sum, min, or multiply.
  56. func (q *FunctionScoreQuery) ScoreMode(scoreMode string) *FunctionScoreQuery {
  57. q.scoreMode = scoreMode
  58. return q
  59. }
  60. // BoostMode defines how the combined result of score functions will
  61. // influence the final score together with the sub query score.
  62. func (q *FunctionScoreQuery) BoostMode(boostMode string) *FunctionScoreQuery {
  63. q.boostMode = boostMode
  64. return q
  65. }
  66. // MaxBoost is the maximum boost that will be applied by function score.
  67. func (q *FunctionScoreQuery) MaxBoost(maxBoost float64) *FunctionScoreQuery {
  68. q.maxBoost = &maxBoost
  69. return q
  70. }
  71. // Boost sets the boost for this query. Documents matching this query will
  72. // (in addition to the normal weightings) have their score multiplied by the
  73. // boost provided.
  74. func (q *FunctionScoreQuery) Boost(boost float64) *FunctionScoreQuery {
  75. q.boost = &boost
  76. return q
  77. }
  78. // MinScore sets the minimum score.
  79. func (q *FunctionScoreQuery) MinScore(minScore float64) *FunctionScoreQuery {
  80. q.minScore = &minScore
  81. return q
  82. }
  83. // Source returns JSON for the function score query.
  84. func (q *FunctionScoreQuery) Source() (interface{}, error) {
  85. source := make(map[string]interface{})
  86. query := make(map[string]interface{})
  87. source["function_score"] = query
  88. if q.query != nil {
  89. src, err := q.query.Source()
  90. if err != nil {
  91. return nil, err
  92. }
  93. query["query"] = src
  94. }
  95. if q.filter != nil {
  96. src, err := q.filter.Source()
  97. if err != nil {
  98. return nil, err
  99. }
  100. query["filter"] = src
  101. }
  102. if len(q.filters) > 0 {
  103. funcs := make([]interface{}, len(q.filters))
  104. for i, filter := range q.filters {
  105. hsh := make(map[string]interface{})
  106. if filter != nil {
  107. src, err := filter.Source()
  108. if err != nil {
  109. return nil, err
  110. }
  111. hsh["filter"] = src
  112. }
  113. // Weight needs to be serialized on this level.
  114. if weight := q.scoreFuncs[i].GetWeight(); weight != nil {
  115. hsh["weight"] = weight
  116. }
  117. // Serialize the score function
  118. src, err := q.scoreFuncs[i].Source()
  119. if err != nil {
  120. return nil, err
  121. }
  122. hsh[q.scoreFuncs[i].Name()] = src
  123. funcs[i] = hsh
  124. }
  125. query["functions"] = funcs
  126. }
  127. if q.scoreMode != "" {
  128. query["score_mode"] = q.scoreMode
  129. }
  130. if q.boostMode != "" {
  131. query["boost_mode"] = q.boostMode
  132. }
  133. if q.maxBoost != nil {
  134. query["max_boost"] = *q.maxBoost
  135. }
  136. if q.boost != nil {
  137. query["boost"] = *q.boost
  138. }
  139. if q.minScore != nil {
  140. query["min_score"] = *q.minScore
  141. }
  142. return source, nil
  143. }