«

»

Mar 06

Elastic Search – just a few useful snippets

Install head plugin or rely on oldschool curl utility in order to test your queries:

curl -XPOST 'http://ELASTICSEARCH_HOST:ELASTICSEARCH_PORT/INDEX_NAME/_search?pretty' -d 'PUT_PROPER_QUERY_HERE'

or

curl -XPOST 'http://ELASTICSEARCH_HOST:ELASTICSEARCH_PORT/INDEX_NAME/_search?pretty' -d@FILE_WITH_YOUR_JSON_REQUEST

Q: Show me example of query for complex, nested document?

A:

{ "query": 
    { "bool":
        { "must": [
            {"nested":
                 {"path": "document.sub_document",
                  "query": 
                       {"bool": 
                           {"must": [
                               { "match":
                                   { "document.sub_document.attribute": "PUT_YOUR_SEARCH_VALUE_HERE" }
                               }
                           ]}
                        }
                 }
           }]
        }
    }
}

NOTE: if what are you searching for in sub-sub-sub document – just add proper number of nested chains of “bool” “must” “nested” elements.

Q: I need full text search and aggregations (aka facets) by attribute in nested document.

A:

{ "query": 
    { "query_string": 
        { "query": "PUT_YOUR_SEARCH_STRING_HERE" }
    },
    "aggs":
        {"name_of_parent_aggregation":
            {"nested":
                {"path": "document.SUB_DOCUMENT"},
                    "aggs":
                    {"name_of_aggregation":
                        {"terms":
                            {"field": "document.SUB_DOCUMENT.ATTRIBUTE_NAME"}
                        }
                    }
            }
        }
}

Q: I need a full text search and aggregations by geo positions aka distance range.

NOTE: put proper values for “origin”, “field”, “ranges” fields.

{ "query":
    { "query_string":
        { "query": "PUT_YOUR_SEARCH_STRING_HERE" }
    },
    "aggs":
        {"name_of_parent_aggregation":
            {"nested":
                {"path": "document.SUB_DOCUMENT"},
                "aggs": 
                    {"name_of_aggregation":
                        {"geo_distance":
                            {"origin": "100500, 100500",
                            "field":"document.SUB_DOCUMENT.NAME_OF_YOUR_GEO_POINT_ATTRIBUTE",
                             "ranges": [{"to": 1000}, {"to": 3000, "from": 1000}, {"from": 3000}]
                             }
                         }
                    }
            }
        }
}

Q: I have fields in document that contains multiple words, I want them to be be aggregated not as separate single terms, but as a whole string.

A.1 put proper mapping for such field – “multi_field” or in most recent version of elasticsearch – just “fields”.


... document mapping, ...

YOUR_FIELD: {   "type": "string",
                "fields":
                {"raw":
                    { "type": "string", "index": "not_analyzed" }
                }
            }

... document mapping, ...

A.2 use such kind of queries for nested faceting:

{"query":
    {"query_string":
        {"query": "PUT_YOUR_SEARCH_STRING_HERE"}
    },
    "aggs":
        {"name_of_parent_aggregation": 
            {"nested":
                {"path": "document.SUB_DOCUMENT"},
                 "aggs":
                     {"name_of_aggregation":
                         {"terms":
                             {"field": "document.SUB_DOCUMENT.ATTRIBUTE_NAME.raw"}
                         }
                     }
            }
        }
}

Q: I want return all documents sorted by distance and my geo_point field in nested document.

NOTE: ATTRIBUTE_NAME should be mapped as geo_point at moment of writing – it can be done only via manually created mapping.

A:

{"query":
    {"match_all": {}},
    "sort": [
        {"_geo_distance": 
            {"document.SUB_DOCUMENT.ATTRIBUTE_NAME": 
                {"lat": 25,"lon": 55},
                 "order": "asc",
                 "unit": "km",
                 "distance_type": "plane"
            }
        }]
}

Q: I want to return aggregation only?

A:

{"size": 0,
    "aggs": {
        "name_of_1st_parent_aggregation": {
            "nested": {"path": "document.SUB_DOCUMENT"},
            "aggs": {
                "name_of_1st_aggregation": {
                    "terms": {
                        "field":"document.SUB_DOCUMENT.ATTRIBUTE_NAME"
        }}}},
        "name_of_2nd_parent_aggregation": {
            "nested": {"path": "document.SUB_DOCUMENT_1"},
            "aggs": {
                "name_of_2nd_aggregation": {
                    "terms": {
                        "field":"document.SUB_DOCUMENT_1.ATTRIBUTE_NAME_1.raw"
        }}}},
        "name_of_3rd_parent_aggregation": {
            "nested": {"path": "document.SUB_DOCUMENT_2"},
            "aggs": {
                "name_of_3rd_aggregation": {
                    "geo_distance":
                            {"origin": "100500, 100500",
                            "field":"document.SUB_DOCUMENT_2.NAME_OF_YOUR_GEO_POINT_ATTRIBUTE",
                             "ranges": [{"to": 1000}, {"to": 3000, "from": 1000}, {"from": 3000}]
                             }
                }
        }}
}

Q: I want autocomplete?

A-0. NOTE better to use n-gramm based approach

A-1. Prefix approach for autocomplete:

{
    "query":{"query_string" : {
        "default_field" : "field.name",
        "query" : "start_of_phrase*"
    }},   
    "fields":["field.name"]
}

A-2. by adding to document mapping additional suggest field:

...
"mappings" : {
    "document_type": {
        "properties":{
             "suggest" : {
                        "type" : "completion",
                        "index_analyzer" :"simple",
                        "search_analyzer" :"simple",
                        "payloads":"true"
                    },
....

When you add document for indexing you have to specify this additional information and use special endpoint _suggest for request suggestions:

{
    "suggest_name" : {
        "text" : "k",
        "completion" : {
            "field" : "suggest"
        }
    }
}

Q: I want filtering of a search result by nested attribute!

{
  "query": {
    "filtered": {
      "query": {
        "match_all": {}
      },
      "filter": {
        "or": [
          {
            "nested": {
              "path": "document.nested_attribute",
              "filter": {
                "bool": {
                  "must": [
                    {
                      "terms": {
                        "document.nested_attribute.attribute_value": [
                          1,
                          2
                        ]
                      }
                    }
                  ]
                }
              }
            }
          },
          {
            "nested": {
              "path": "document.nested_attribute_1",
              "filter": {
                "bool": {
                  "must": [
                    {
                      "terms": {
                        "document.nested_attribute_1.attribute_value": [
                          "some string value"
                        ]
                      }
                    }
                  ]
                }
              }
            }
          }
        ]
      }
    }
  }
}

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>