# Using Emacs Restclient Mode to explore the Elasticsearch REST API
# http://www.elasticsearch.org/guide/en/elasticsearch/reference/

:es = http://127.0.0.1:9200

# Cluster Health

GET :es/_cat/health?v

# List of nodes

GET :es/_cat/nodes?v

# List all indexes

GET :es/_cat/indices?v

# Create index

PUT :es/customer?pretty

# Index a document

POST :es/customer/external/1

{
  "name": "John Doe"
}

# Query a document

GET :es/customer/external/1?pretty

# Delete an index

DELETE :es/customer?pretty

# Replacing (reindexing) a document

PUT :es/customer/external/1?pretty

{
  "name": "Jane Doe"
}

# Creating a document without an explicit ID
# Note: POST instead of PUT because we did not specify an explicit ID

POST :es/customer/external?pretty

{
  "name": "Jane Doe"
}

# Updating documents

POST :es/customer/external/1/_update?pretty

{
  "doc": { "name": "Jane Doe", "age": 20 }
}

# Updating with simple scripts

POST :es/customer/external/1/_update?pretty

{
  "script": "ctx._source.age += 5"
}

# Deleting documents

DELETE :es/customer/external/1?pretty

# Delete by query

DELETE :es/customer/external/_query?pretty

{
  "query": { "match" : { "name": "John Doe" } }
}

# Bulk API

POST :es/customer/external/_bulk?pretty

{"index": {"_id": "1"}}
{"name": "John Doe"}
{"index": {"_id": "2"}}
{"name": "Jane Doe"}

# Bulk API with multiple commands

POST :es/customer/external/_bulk?pretty

{"update": {"_id": "1"}}
{"doc": {"name": "John Doe becomes Jane Doe"}}
{"delete": {"_id": "2"}}

# Data generated via: http://www.json-generator.com/

# Loading via file
#    curl -L https://github.com/bly2k/files/blob/master/accounts.zip?raw=true > accounts.zip
#    unzip accounts.zip
#    curl -X POST 'localhost:9200/bank/account/_bulk?pretty' --data-binary @accounts.json

# Search using REST request URI

GET :es/bank/_search?q=*&pretty
Accept: application/json

# Search using REST request body

POST :es/bank/_search?pretty

{
  "query": { "match_all": {} }
}

# Query DSL
# http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl.html

# Return only first result

POST :es/bank/_search?pretty

{
  "query": { "match_all": {} },
  "size": 1
}

# Search at particular location
# from: 0 based; default = 0

POST :es/bank/_search?pretty

{
  "query": { "match_all": {} },
  "from": 10,
  "size": 10
}

# Search with sort

POST :es/bank/_search?pretty

{
  "query": { "match_all": {} },
  "sort": { "balance": { "order": "desc" } }
}

# Return only a few fields in search results

POST :es/bank/_search?pretty

{
  "query": { "match_all": {} },
  "_source": ["account_number", "balance"]
}

# match_all: matches all documents
# match: fielded search query

POST :es/bank/_search?pretty

{
  "query": { "match": { "account_number": 20 } }
}

# Search for substring in field

POST :es/bank/_search?pretty

{
  "query": { "match": { "address": "mill" } }
}

# Search using OR
# - return all accounts containing the term "mill" or "lane" in the address

POST :es/bank/_search?pretty

{
  "query": { "match": { "address": "mill lane" } }
}

# match_phrase:
# return all accounts containing the phrase "mill lane" in the address

POST :es/bank/_search?pretty

{
  "query": { "match_phrase": { "address": "mill lane" } }
}

# bool query to compose smaller queries using boolean logic

# bool must clause
# compose two match queries to return all accounts containing "mill"
# AND "lane"

POST :es/bank/_search?pretty

{
  "query": {
    "bool": {
      "must": [
        { "match": { "address": "mill" } },
        { "match": { "address": "lane" } }
      ]
    }
  }
}

# bool should clause
# "mill" OR "lane"

POST :es/bank/_search?pretty

{
  "query": {
    "bool": {
      "should": [
        { "match": { "address": "mill" } },
        { "match": { "address": "lane" } }
      ]
    }
  }
}

# bool must_not clause
# return all accounts that contain neither "mill" nor "lane"

POST :es/bank/_search?pretty

{
  "query": {
    "bool": {
      "must_not": [
        { "match": { "address": "mill" } },
        { "match": { "address": "lane" } }
      ]
    }
  }
}

# practice
# - accounts of anybody who is 40 years old but doesn't live in ID(aho)

POST :es/bank/_search?pretty

{
  "query": {
    "bool": {
      "must": [
        { "match": { "age": "40" } }
      ],
      "must_not": [
        { "match": { "state": "ID" } }
      ]
    }
  }
}

# The document score (`_score` field is the search results) is a
# numeric value that is a relative measure of how well the document
# matchs the search query that we specified (higher better).

# Filters are for when we don't need relevance scores.
# (Filters are also cached).

# filtered query allows us to combine a query (like `match_all`,
# `match`, `bool` etc) together with a filter.

# For example, `range` filter for numeric or date filtering.
# - has two parts -- the query part, and the filter part
# - SELECT WHERE

POST :es/bank/_search?pretty

{
  "query": {
    "filtered": {
      "query": { "match_all": {} },
      "filter": {
        "range": {
          "balance": {
            "gte": 20000,
            "lte": 30000
          }
        }
      }
    }
  }
}


# Aggregations --

# Group all account by state, and return the top 10 states sorted by
# count descending.
# SELECT COUNT(*) FROM bank GROUP BY state ORDER BY COUNT(*) DESC
#
# - set size = 0 to not show search hits because we only want to see
#   the aggregation results in the response.

POST :es/bank/_search?pretty

{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state"
      }
    }
  }
}

# Compute average account balance by state (only for the top ten
# states sorted average balance in descending order).

POST :es/bank/_search?pretty

{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state",
        "order": {
          "average_balance": "desc"
        }
      },
      "aggs": {
        "average_balance": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}

# Reference: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations.html
