search_queries_dis_max.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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. // DisMaxQuery is a query that generates the union of documents produced by
  6. // its subqueries, and that scores each document with the maximum score
  7. // for that document as produced by any subquery, plus a tie breaking
  8. // increment for any additional matching subqueries.
  9. //
  10. // For more details, see:
  11. // https://www.elastic.co/guide/en/elasticsearch/reference/5.2/query-dsl-dis-max-query.html
  12. type DisMaxQuery struct {
  13. queries []Query
  14. boost *float64
  15. tieBreaker *float64
  16. queryName string
  17. }
  18. // NewDisMaxQuery creates and initializes a new dis max query.
  19. func NewDisMaxQuery() *DisMaxQuery {
  20. return &DisMaxQuery{
  21. queries: make([]Query, 0),
  22. }
  23. }
  24. // Query adds one or more queries to the dis max query.
  25. func (q *DisMaxQuery) Query(queries ...Query) *DisMaxQuery {
  26. q.queries = append(q.queries, queries...)
  27. return q
  28. }
  29. // Boost sets the boost for this query. Documents matching this query will
  30. // (in addition to the normal weightings) have their score multiplied by
  31. // the boost provided.
  32. func (q *DisMaxQuery) Boost(boost float64) *DisMaxQuery {
  33. q.boost = &boost
  34. return q
  35. }
  36. // TieBreaker is the factor by which the score of each non-maximum disjunct
  37. // for a document is multiplied with and added into the final score.
  38. //
  39. // If non-zero, the value should be small, on the order of 0.1, which says
  40. // that 10 occurrences of word in a lower-scored field that is also in a
  41. // higher scored field is just as good as a unique word in the lower scored
  42. // field (i.e., one that is not in any higher scored field).
  43. func (q *DisMaxQuery) TieBreaker(tieBreaker float64) *DisMaxQuery {
  44. q.tieBreaker = &tieBreaker
  45. return q
  46. }
  47. // QueryName sets the query name for the filter that can be used
  48. // when searching for matched filters per hit.
  49. func (q *DisMaxQuery) QueryName(queryName string) *DisMaxQuery {
  50. q.queryName = queryName
  51. return q
  52. }
  53. // Source returns the JSON serializable content for this query.
  54. func (q *DisMaxQuery) Source() (interface{}, error) {
  55. // {
  56. // "dis_max" : {
  57. // "tie_breaker" : 0.7,
  58. // "boost" : 1.2,
  59. // "queries" : {
  60. // {
  61. // "term" : { "age" : 34 }
  62. // },
  63. // {
  64. // "term" : { "age" : 35 }
  65. // }
  66. // ]
  67. // }
  68. // }
  69. query := make(map[string]interface{})
  70. params := make(map[string]interface{})
  71. query["dis_max"] = params
  72. if q.tieBreaker != nil {
  73. params["tie_breaker"] = *q.tieBreaker
  74. }
  75. if q.boost != nil {
  76. params["boost"] = *q.boost
  77. }
  78. if q.queryName != "" {
  79. params["_name"] = q.queryName
  80. }
  81. // queries
  82. var clauses []interface{}
  83. for _, subQuery := range q.queries {
  84. src, err := subQuery.Source()
  85. if err != nil {
  86. return nil, err
  87. }
  88. clauses = append(clauses, src)
  89. }
  90. params["queries"] = clauses
  91. return query, nil
  92. }