ElasticSearch _source field in golang - go

I am implementing a golang API which will search in elastic search index and retrieve results. The index contains huge nested fields. To optimise the search, I want to use a query like
GET my_index/_search
{
"_source": ["nested_object.nested_field"],
"query": {
"match": {
"field": "dummy object"
}
}
}
I am not able to find implementations of this _source field in golang. I am using the oliviere/elastic/v7 package. Can someone help me in implementing this??

You need to add FetchSourceContext to your query. Something like that:
fetchContext := elastic.NewFetchSourceContext(true)
fetchContext = fetchContext.Include(fieldsToFetch...)
SearchResult, err := r.es.Search().
Index(r.index).
Query(Query),
).
FetchSourceContext(fetchContext).
Do(ctx)

Related

Elasticsearch nested objects with query_string as first class attributes

I'm trying to index a nested field as a first-class attribute in my document so that I can search them using query_string without dot syntax.
For example, if I have a document like
"data": { "name": "Bob" }
instead of searching for data.name:Bob I would like to be able to search for name:Bob
The root of my issue is that we index a jsonb column that may have varying attributes. In some instances the data property may contain a data.business attribute, etc. I would like users to be able to search on these attributes without needing to "dig" into the object.
The data field does not have to be indexed as a nested type unless necessary; I was indexing it as an object previously.
I have tried to leverage the _all field as suggested in this post.
I have also tried to use include_in_parent:true and set the datatype as nested for my data field as suggested in this post.
I have also looked into the inner_hits feature to no avail.
Here's an example of my mapping for the data attribute.
PUT my_index
{
"mappings": {
"my_type": {
"properties": {
"data": {
"type": "object"
}
}
}
}
}
Example document
PUT my_index/_doc/1
{
"data": {
name: "bob",
business: "None of yours"
}
}
And how my query currently looks:
GET my_index/_search
{
"query": {
"query_string": {
"query": "name:bob",
"fields": ["data.*"]
}
}
}
With the current setup I almost get my desired results. I can search on individual properties like data.name:bob and data.business:"None of yours" and get back the correct documents.
However I want to be able to get the exact same results with business:"None of yours" or name:bob.
Thanks in advance for any help!
I figured it out using dynamic templates. For anyone coming across this in the future, here is how I solved the issue:
I used path_match to match the data object (data.*).
Then using copy_to and {name} I dynamically created top-level fields on my parent object.
{
"dynamic_templates":[
{"template_1":
{"mapping":
{"copy_to":"{name}"},
"path_match":"data.*"
}
}
]
}

Elasticsearch query based on two values

I am trying to use elasticsearch in order to find documents with a rule based on two doc properties.
Lets say the documents are in the following structure:
{
"customer_payment_timestamp" : 14387930787,
"customer_delivery_timestamp" : 14387230787,
}
and i would like to query these kind of documents and find all documents where customer_payment_timestamp is greater than customer_delivery_timestamp.
Tried the official documentation, but I couldn't find any relevant example regarding the query itself or a pre-mapped field... is it even possible?
You can achieve this with a script filter like this:
POST index/_search
{
"query": {
"bool": {
"filter": {
"script": {
"script": "doc.customer_payment_timestamp.value > doc. customer_delivery_timestamp.value"
}
}
}
}
}
Note: you need to make sure that dynamic scripting is enabled

Elastic search paginating on multiple types in an index

I have an index with multiple types like below :
songs
books
movies
I am building an API for suggesting indexed items grouped by their type, The problem is that I want a size functionality inside each aggregation, Just like the completion suggester approach which returns an exact number of items for each type. I ended up with multi index query approach to query each type separately, Is there any better approach to handle this ?
Each aggregation you specify can have a filter associated with it, so you could
reduce the context of an aggregation to a specific type that way. Additionally,
you can use the filters aggregation to create buckets for each filter, and run
an aggregation with a certain size on each sub-bucket, like this:
GET /_search
{
"aggs": {
"alltypes": {
"filters": {
"filters": {
"songs": {"term": {"_type": "songs"}},
"books": {"term": {"_type": "books"}},
"movies": {"term": {"_type": "movies"}}
}
},
"aggs": {
... your aggregation for each individual type here ...
}
}
}
}
More info about the filters aggregation can be found at
http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-filters-aggregation.html
Hopefully that helps, let me know if I misunderstood your question (it was a
little uncertain whether you were talking about suggestors or aggregations since
both were mentioned in the question).

Why I can retrieve records in Elastic search using bool query?

I've inserted a record in ElasticSearch an I can see that here:
But this query returns nothing:
{
"query": {
"filtered": {
"query": {
"bool": {
"must": {
"term": {
"name": "Ehsanl"
}
}
}
}
}
}
}
I post this query using post method to this user: http://127.0.0.1:9200/mydb/customers2/_search
What's wrong with that?
Try giving the name as "ehsanl". All in lower case.
What you see on your screenshot is the original document as you indexed it (_source field).
However, by default, string fields are analyzed (see this answer for more detail about analysis).
Using standard analyzer, your name value should have been lowercased to ehsanl and stored this way in the index : term queries search for the exact value Ehsanl in the index, which doesn't exist.
You can either :
use ehsanl value with term query
use Ehsanl value with a match query, which will apply the same analyzer before to search.

Sorting a match query with ElasticSearch

I'm trying to use ElasticSearch to find all records containing a particular string. I'm using a match query for this, and it's working fine.
Now, I'm trying to sort the results based on a particular field. When I try this, I get some very unexpected output, and none of the records even contain my initial search query.
My request is structured as follows:
{
"query":
{
"match": {"_all": "some_search_string"}
},
"sort": [
{
"some_field": {
"order": "asc"
}
}
] }
Am I doing something wrong here?
In order to sort on a string field, your mapping must contain a non-analyzed version of this field. Here's a simple blog post I found that describes how you can do this using the multi_field mapping type.

Resources