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 5package elastic 6 7// HasChildQuery accepts a query and the child type to run against, and results 8// in parent documents that have child docs matching the query. 9// 10// For more details, see 11// https://www.elastic.co/guide/en/elasticsearch/reference/5.2/query-dsl-has-child-query.html 12type HasChildQuery struct { 13 query Query 14 childType string 15 boost *float64 16 scoreMode string 17 minChildren *int 18 maxChildren *int 19 shortCircuitCutoff *int 20 queryName string 21 innerHit *InnerHit 22} 23 24// NewHasChildQuery creates and initializes a new has_child query. 25func NewHasChildQuery(childType string, query Query) *HasChildQuery { 26 return &HasChildQuery{ 27 query: query, 28 childType: childType, 29 } 30} 31 32// Boost sets the boost for this query. 33func (q *HasChildQuery) Boost(boost float64) *HasChildQuery { 34 q.boost = &boost 35 return q 36} 37 38// ScoreMode defines how the scores from the matching child documents 39// are mapped into the parent document. Allowed values are: min, max, 40// avg, or none. 41func (q *HasChildQuery) ScoreMode(scoreMode string) *HasChildQuery { 42 q.scoreMode = scoreMode 43 return q 44} 45 46// MinChildren defines the minimum number of children that are required 47// to match for the parent to be considered a match. 48func (q *HasChildQuery) MinChildren(minChildren int) *HasChildQuery { 49 q.minChildren = &minChildren 50 return q 51} 52 53// MaxChildren defines the maximum number of children that are required 54// to match for the parent to be considered a match. 55func (q *HasChildQuery) MaxChildren(maxChildren int) *HasChildQuery { 56 q.maxChildren = &maxChildren 57 return q 58} 59 60// ShortCircuitCutoff configures what cut off point only to evaluate 61// parent documents that contain the matching parent id terms instead 62// of evaluating all parent docs. 63func (q *HasChildQuery) ShortCircuitCutoff(shortCircuitCutoff int) *HasChildQuery { 64 q.shortCircuitCutoff = &shortCircuitCutoff 65 return q 66} 67 68// QueryName specifies the query name for the filter that can be used when 69// searching for matched filters per hit. 70func (q *HasChildQuery) QueryName(queryName string) *HasChildQuery { 71 q.queryName = queryName 72 return q 73} 74 75// InnerHit sets the inner hit definition in the scope of this query and 76// reusing the defined type and query. 77func (q *HasChildQuery) InnerHit(innerHit *InnerHit) *HasChildQuery { 78 q.innerHit = innerHit 79 return q 80} 81 82// Source returns JSON for the function score query. 83func (q *HasChildQuery) Source() (interface{}, error) { 84 // { 85 // "has_child" : { 86 // "type" : "blog_tag", 87 // "score_mode" : "min", 88 // "query" : { 89 // "term" : { 90 // "tag" : "something" 91 // } 92 // } 93 // } 94 // } 95 source := make(map[string]interface{}) 96 query := make(map[string]interface{}) 97 source["has_child"] = query 98 99 src, err := q.query.Source() 100 if err != nil { 101 return nil, err 102 } 103 query["query"] = src 104 query["type"] = q.childType 105 if q.boost != nil { 106 query["boost"] = *q.boost 107 } 108 if q.scoreMode != "" { 109 query["score_mode"] = q.scoreMode 110 } 111 if q.minChildren != nil { 112 query["min_children"] = *q.minChildren 113 } 114 if q.maxChildren != nil { 115 query["max_children"] = *q.maxChildren 116 } 117 if q.shortCircuitCutoff != nil { 118 query["short_circuit_cutoff"] = *q.shortCircuitCutoff 119 } 120 if q.queryName != "" { 121 query["_name"] = q.queryName 122 } 123 if q.innerHit != nil { 124 src, err := q.innerHit.Source() 125 if err != nil { 126 return nil, err 127 } 128 query["inner_hits"] = src 129 } 130 return source, nil 131} 132