jimmy
jimmy

Reputation: 415

How to pass array to Elasticsearch's NewTermsQuery in Golang?

I want to implement the following Elasticsearch query using Golang.

{
  "query": {
    "bool": {
      "must": {
        "range": { "sales_start_date": { "gte": "2018-07-01T00:00:00.000Z" } }
      },
      "filter": {
        "terms": { "item_holder_id": [2, 7, 9] }
      }
    }
  }
}
'

My current code is the following (I am using http://github.com/olivere/elastic library).

query := elastic.NewBoolQuery()
query = query.Must(elastic.NewRangeQuery("sales_start_date").Gte(date).TimeZone("+09:00"))
query = query.Filter(elastic.NewTermsQuery("item_holder_id", ihids))

with ihids being an []int. When I execute this code I got the error

elastic: Error 400 (Bad Request): [terms] unknown token [END_ARRAY] after [item_holder_id] [type=parsing_exception]

After some research I found out that I need to write this like this

elastic.NewTermsQuery("item_holder_id", "1", "2")

but being new to Golang I guess I am missing some of the basic concepts. How can I pass an array of values like this?

Thank you for any information that can help me!

Upvotes: 9

Views: 5066

Answers (3)

Claire
Claire

Reputation: 21

    values := make([]interface{}, len(status))
    for i, v := range status {
        values[i] = v
    }
    query = query.Filter(elastic.NewTermsQuery("item_holder_id", values...))

Upvotes: 2

omotto
omotto

Reputation: 1879

in order to complete the @Ullaakut answer:

// Convert type []int to type []interface{}

status := make([]interface{}, len(ihids))
for index, value := range ihids {
    status[index] = value
}

// Ullaakut aswer

query := elastic.NewBoolQuery()
query = query.Must(elastic.NewRangeQuery("sales_start_date").Gte(date).TimeZone("+09:00"))
query = query.Filter(elastic.NewTermsQuery("item_holder_id", status...))

I had the same issue and I solved on this way.

Upvotes: 8

Ullaakut
Ullaakut

Reputation: 3734

You can simply fix it by adding ... after your ihids argument like this:

query := elastic.NewBoolQuery()
query = query.Must(elastic.NewRangeQuery("sales_start_date").Gte(date).TimeZone("+09:00"))
query = query.Filter(elastic.NewTermsQuery("item_holder_id", ihids...))

And for an explanation on how that works, this is from the golang spec:

If f is variadic with final parameter type ...T, then within the function the argument is equivalent to a parameter of type []T. At each call of f, the argument passed to the final parameter is a new slice of type []T whose successive elements are the actual arguments, which all must be assignable to the type T.

Upvotes: 0

Related Questions