123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- // Copyright 2012-present Oliver Eilhard. All rights reserved.
- // Use of this source code is governed by a MIT-license.
- // See http://olivere.mit-license.org/license.txt for details.
- package elastic
- // TermSuggester suggests terms based on edit distance.
- // For more details, see
- // https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-suggesters-term.html.
- type TermSuggester struct {
- Suggester
- name string
- text string
- field string
- analyzer string
- size *int
- shardSize *int
- contextQueries []SuggesterContextQuery
- // fields specific to term suggester
- suggestMode string
- accuracy *float64
- sort string
- stringDistance string
- maxEdits *int
- maxInspections *int
- maxTermFreq *float64
- prefixLength *int
- minWordLength *int
- minDocFreq *float64
- }
- // NewTermSuggester creates a new TermSuggester.
- func NewTermSuggester(name string) *TermSuggester {
- return &TermSuggester{
- name: name,
- }
- }
- func (q *TermSuggester) Name() string {
- return q.name
- }
- func (q *TermSuggester) Text(text string) *TermSuggester {
- q.text = text
- return q
- }
- func (q *TermSuggester) Field(field string) *TermSuggester {
- q.field = field
- return q
- }
- func (q *TermSuggester) Analyzer(analyzer string) *TermSuggester {
- q.analyzer = analyzer
- return q
- }
- func (q *TermSuggester) Size(size int) *TermSuggester {
- q.size = &size
- return q
- }
- func (q *TermSuggester) ShardSize(shardSize int) *TermSuggester {
- q.shardSize = &shardSize
- return q
- }
- func (q *TermSuggester) ContextQuery(query SuggesterContextQuery) *TermSuggester {
- q.contextQueries = append(q.contextQueries, query)
- return q
- }
- func (q *TermSuggester) ContextQueries(queries ...SuggesterContextQuery) *TermSuggester {
- q.contextQueries = append(q.contextQueries, queries...)
- return q
- }
- func (q *TermSuggester) SuggestMode(suggestMode string) *TermSuggester {
- q.suggestMode = suggestMode
- return q
- }
- func (q *TermSuggester) Accuracy(accuracy float64) *TermSuggester {
- q.accuracy = &accuracy
- return q
- }
- func (q *TermSuggester) Sort(sort string) *TermSuggester {
- q.sort = sort
- return q
- }
- func (q *TermSuggester) StringDistance(stringDistance string) *TermSuggester {
- q.stringDistance = stringDistance
- return q
- }
- func (q *TermSuggester) MaxEdits(maxEdits int) *TermSuggester {
- q.maxEdits = &maxEdits
- return q
- }
- func (q *TermSuggester) MaxInspections(maxInspections int) *TermSuggester {
- q.maxInspections = &maxInspections
- return q
- }
- func (q *TermSuggester) MaxTermFreq(maxTermFreq float64) *TermSuggester {
- q.maxTermFreq = &maxTermFreq
- return q
- }
- func (q *TermSuggester) PrefixLength(prefixLength int) *TermSuggester {
- q.prefixLength = &prefixLength
- return q
- }
- func (q *TermSuggester) MinWordLength(minWordLength int) *TermSuggester {
- q.minWordLength = &minWordLength
- return q
- }
- func (q *TermSuggester) MinDocFreq(minDocFreq float64) *TermSuggester {
- q.minDocFreq = &minDocFreq
- return q
- }
- // termSuggesterRequest is necessary because the order in which
- // the JSON elements are routed to Elasticsearch is relevant.
- // We got into trouble when using plain maps because the text element
- // needs to go before the term element.
- type termSuggesterRequest struct {
- Text string `json:"text"`
- Term interface{} `json:"term"`
- }
- // Source generates the source for the term suggester.
- func (q *TermSuggester) Source(includeName bool) (interface{}, error) {
- // "suggest" : {
- // "my-suggest-1" : {
- // "text" : "the amsterdma meetpu",
- // "term" : {
- // "field" : "body"
- // }
- // },
- // "my-suggest-2" : {
- // "text" : "the rottredam meetpu",
- // "term" : {
- // "field" : "title",
- // }
- // }
- // }
- ts := &termSuggesterRequest{}
- if q.text != "" {
- ts.Text = q.text
- }
- suggester := make(map[string]interface{})
- ts.Term = suggester
- if q.analyzer != "" {
- suggester["analyzer"] = q.analyzer
- }
- if q.field != "" {
- suggester["field"] = q.field
- }
- if q.size != nil {
- suggester["size"] = *q.size
- }
- if q.shardSize != nil {
- suggester["shard_size"] = *q.shardSize
- }
- switch len(q.contextQueries) {
- case 0:
- case 1:
- src, err := q.contextQueries[0].Source()
- if err != nil {
- return nil, err
- }
- suggester["context"] = src
- default:
- ctxq := make([]interface{}, len(q.contextQueries))
- for i, query := range q.contextQueries {
- src, err := query.Source()
- if err != nil {
- return nil, err
- }
- ctxq[i] = src
- }
- suggester["context"] = ctxq
- }
- // Specific to term suggester
- if q.suggestMode != "" {
- suggester["suggest_mode"] = q.suggestMode
- }
- if q.accuracy != nil {
- suggester["accuracy"] = *q.accuracy
- }
- if q.sort != "" {
- suggester["sort"] = q.sort
- }
- if q.stringDistance != "" {
- suggester["string_distance"] = q.stringDistance
- }
- if q.maxEdits != nil {
- suggester["max_edits"] = *q.maxEdits
- }
- if q.maxInspections != nil {
- suggester["max_inspections"] = *q.maxInspections
- }
- if q.maxTermFreq != nil {
- suggester["max_term_freq"] = *q.maxTermFreq
- }
- if q.prefixLength != nil {
- suggester["prefix_length"] = *q.prefixLength
- }
- if q.minWordLength != nil {
- suggester["min_word_len"] = *q.minWordLength
- }
- if q.minDocFreq != nil {
- suggester["min_doc_freq"] = *q.minDocFreq
- }
- if !includeName {
- return ts, nil
- }
- source := make(map[string]interface{})
- source[q.name] = ts
- return source, nil
- }
|